/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD 
 	* license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the 
 	* full text of the license. */ 
 		 
 	/** 
 	* @requires OpenLayers/Control.js 
 	* @requires OpenLayers/Feature/Vector.js 
 	*/ 
 	 
 	/** 
 	* Class: OpenLayers.Control.Measure 
 	* Allows for drawing of features for measurements. 
 	* 
 	* Inherits from: 
 	*  - <OpenLayers.Control> 
 	*/ 
 	OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, { 
 	 
			 	/** 
			 	* APIProperty: handlerOptions 
			 	* {Object} Used to set non-default properties on the control's handler 
			 	*/ 
			 	handlerOptions: null, 
 		     
 		    /** 
 		     * Property: callbacks 
 		     * {Object} The functions that are sent to the handler for callback 
 		     */ 
 		    callbacks: null, 
 		     
 		    /** 
 		     * Property: displayUnits 
 		     * {String} Units for output.  Must be one of 'in', 'ft', 'mi', 'm', 'km', 
 		     *     or 'dd'.  If null, displayUnits will be assumed to be the same as 
 		     *     map units. 
 		     */ 
 		    displayUnits: null, 
 		    tooltip : null,
 		    tooltips : null,
 		    tooltipBis : null,
 		    typeHandler : null ,
 		    dr : 0,
 		    lastdown : null,
 		    
 		 
 		    /** 
 		     * Constructor: OpenLayers.Control.Measure 
 		     *  
 		     * Parameters: 
 		     * handler - {<OpenLayers.Handler>}  
 		     * options - {Object}  
 		     */ 
 		    initialize: function(handler, options) { 
 		        OpenLayers.Control.prototype.initialize.apply(this, [options]); 
 		        this.callbacks = OpenLayers.Util.extend( 
 		            {done: this.reinitMeasure, down: this.downMeasure,mouvement:this.moveMeasure}, 
 		            this.callbacks 
 		        ); 
 		        this.handler = new handler(this, this.callbacks, this.handlerOptions);   	
 		        var styleAffiche = {fillColor:"#B0ACC5",
																fillOpacity:0.7,
																hoverFillColor:"#ffffff",
																hoverFillOpacity:0.8,
																strokeColor:"#DC569F",
																strokeOpacity:1,
																strokeWidth:1,
																strokeLinecap:"round",
																hoverStrokeColor:"#ff0000",
																hoverStrokeOpacity:1,
																hoverStrokeWidth:0.2
															};
 		        this.handler.style = OpenLayers.Util.extend({},styleAffiche);	        
 		    },  	
		    /**
		     * APIMethod: activate
		     */
		    activate: function() {
		        if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {		        	
				        this.tooltip = new OpenLayers.Control.Tooltip(this.map, {offsetX: 25,offsetY: 30,fixed:true});         
				        this.tooltips = new OpenLayers.Control.Tooltips(this.map);
				        
				        this.tooltip.align = 'bl';
				        this.typeHandler = (this.handler.CLASS_NAME == "OpenLayers.Handler.Polygon.Ux") ;
				        this.activated  = true ;
		            //this.redraw();		            
		            return true;
		        } else {
				        this.activated  = false ;
		            return false;
		        }
		    },	 		    
    		deactivate: function () {	
		        var deactivated = false;
		        // the return from the controls is unimportant in this case
		        if(OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
		    				this.tooltip.clear();
		        		this.tooltip.destroy();
		        		this.tooltips.destroy();
		            deactivated = true;		            
				        this.activated  = false ;
		        }
		        return deactivated;
    		},
    		clearMeasure : function(){
    			if(this.activated){
    				this.deactivate();
    				this.activate();
    			}
    		},
    		downMeasure : function(xy){
    				if(this.map.getScale() > PARAM_TRANSPOSE_MEASURE_UNITS){
    					this.displayUnits = 'km' ;
    				}
    				else{
    					this.displayUnits = 'm' ;
    				}    			
    				var geomTemp = this.handler.line.geometry.clone();
        		this.tooltipBis = new OpenLayers.Control.Tooltip(this.map, {align:'cc'});
		        if(this.lastdown == null) {
		            this.tooltips.destroy();
		            this.dr = 0;
		        }        			
		        this.tooltips.add(this.tooltipBis);		        
		        if(this.typeHandler && (geomTemp.components.length==4)){
		            this.tooltips.add(new OpenLayers.Control.Tooltip(this.map, {align:'cc'}));
		        }
		        this.lastdown = this.map.getLonLatFromPixel(xy);
		        //this.lastdown = xy ;
    		},
    		moveMeasure : function(xy){		
    			var geomTemp = this.handler.line.geometry.clone();
    			var lastPoint = this.map.getPixelFromLonLat(this.lastdown);
        	var lenseg = this.getDistGeo2PointsPx(lastPoint,xy);
        	
	        //xcenter = Math.abs((xy.x + this.lastdown.x)/2);
	        //ycenter = Math.abs((xy.y + this.lastdown.y)/2);
        	this.tooltip.update(xy, "<font> d : "+lenseg.toFixed(3)+' '+this.displayUnits+"<br> "+this.measureGeometry(geomTemp)+"</font>");
	        this.tooltipBis.update(this.getCenter2Points(lastPoint,xy), lenseg.toFixed(3)+' '+this.displayUnits);	        
	        if(this.typeHandler && (geomTemp.components.length >= 4)){
	            var p0 = geomTemp.components[0];
	            p0px = this.map.getPixelFromLonLat(new OpenLayers.LonLat(p0.x, p0.y));
        			this.dr = this.getDistGeo2PointsPx(p0px,xy);
	            this.tooltips.tooltips[2].update(this.getCenter2Points(p0px,xy), this.dr.toFixed(3)+" "+this.displayUnits);
	        }
	        this.tooltip.tooltip.style.fontSize = "10px";
	        this.tooltip.tooltip.style.fontFamily = "tahoma";
    		},
    		getDistGeo2PointsPx :function(xy1,xy2){
    			if(!xy1 || !xy2)return 0 ;
        	var prev = this.map.getLonLatFromPixel(xy1);
        	var next = this.map.getLonLatFromPixel(xy2);
          var segment = new OpenLayers.Geometry.LineString();
          segment.addComponent(new OpenLayers.Geometry.Point(prev.lon, prev.lat),segment.components.length);
          segment.addComponent(new OpenLayers.Geometry.Point(next.lon, next.lat),segment.components.length);
          var len = this.getLength(segment);
          return len ;    			
    		},
    		getCenter2Points : function(xy1,xy2){
	        xcenter = Math.abs((xy1.x + xy2.x)/2);
	        ycenter = Math.abs((xy1.y + xy2.y)/2);    
	        return {x:xcenter,y:ycenter};			
    		},
 		    /** 
 		     * Method: measureGeometry 
 		     */ 
 		    measureGeometry: function(geometry) { 
 		        var area = this.getArea(geometry); 
 		        var length = this.getLength(geometry); 
 		        return this.onMeasure(geometry, length, area, this.displayUnits); 
 		    }, 
 		    reinitMeasure : function(geometry){ 	
 		    	this.measureGeometry(geometry);	    		
		      this.lastdown = null ;
 		    },
 		     
 		    /** 
 		     * Method: getArea 
 		     */ 
 		    getArea: function(geometry) { 
 		        var area = geometry.getArea(); 
 		        var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[this.displayUnits]; 
 		        if(inPerDisplayUnit) { 
 		            var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[this.map.units]; 
 		            area *= Math.pow((inPerMapUnit / inPerDisplayUnit), 2); 
 		        } 
 		        return Math.abs(area); 
 		    }, 
 		     
 		    /** 
 		     * Method: getLength 
 		     */ 
 		    getLength: function(geometry) { 
 		        var length = geometry.getLength(); 
 		        var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[this.displayUnits]; 
 		        if(inPerDisplayUnit) { 
 		            var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[this.map.units]; 
 		            length *= (inPerMapUnit / inPerDisplayUnit); 
 		        } 
 		        return Math.abs(length); 
 		    }, 
			 	   
			 	/** 
			 	* APIProperty: onMeasure 
			 	* {Function} After a geometry is drawn, onMeasure is called with three 
			 	*     arguments: the geometry, its length, and its area. 
			 	*/ 
 		    onMeasure: function(geometry, length, area, units) { 		   
				 	var out = ""; 
				 	if(geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") { 
				 		out += MEASURE_LONGUEUR+" : " + length.toFixed(3) + " " + units; 
				 	} else { 
					 	out += MEASURE_PERIMETRE+" : " + length.toFixed(3) + " " + units + " <br> "+MEASURE_AREA+" : " + area.toFixed(3) + " " + units + "<sup>2</sup>"; 
				 	}
				 	return out ; 
 		    },
 		    reloadMesureOnMove : function(){ 		    	
 		    	if(this.tooltips){
 		    		this.tooltips.updatePosition();
 		    	}
 		    }, 
 		 
 		    CLASS_NAME: "OpenLayers.Control.Measure" 
 		}); 
