 function handleMeasurements(event) {
    var geometry = event.geometry;
    var units = event.units;
    var order = event.order;
    var measure = event.measure;
    var perimeter = event.perimeter;
   
    var out = "";  
    
    if(order == 1) {
    	var element = document.getElementById('resultMeasure');
        element.value = '';
    	var misura = measure;
    	
    	distanze['m'] = misura.toFixed(3);
    	distanze['km'] = (misura/1000).toFixed(3);
    	distanze['mi'] = (misura/1609.344).toFixed(3);
    	distanze['nm'] = (misura/1852).toFixed(3);    	
    	
        //calcolo per misurare le distanze
        var unitamisura = document.getElementById('unitamisura').value;
    
        //conversione in base all'unita di misura scelta per le distanze
	    if (unitamisura=='km') {
	    	misura = misura/1000;
	    } else if (unitamisura=='mi') {
	    	misura = misura/1609.344;
	    } else if (unitamisura=='nm') {
	    	misura = misura/1852;
	    }	
	    
	    misura = misura.toFixed(3);
        out +=misura ;
        element.value = out;
       
    } else {
    	 var element = document.getElementById('resultMeasureArea');
         element.value = '';
    	
    	var misura = measure;
        
        aree['m2'] = misura.toFixed(3);
    	aree['km2'] = (misura/1000000).toFixed(3);
    	aree['et'] = (misura/10000).toFixed(3);
    	
        //measure in questo caso contiene l'area
        
        var unitamisura = document.getElementById('unitamisuraarea').value;
    
        //conversione in base all'unita di misura scelta per le aree
	    if (unitamisura=='km2') {
	    	misura = misura/1000000;
	    } else if (unitamisura=='et') {
	    	misura = misura/10000;
	    } 
	    
	    misura = misura.toFixed(3);
        element.value = misura ;       
        
	    var element = document.getElementById('resultMeasurePerimetro');
	    element.value = '';
		
		var misura = perimeter;
		
		perimetri['m'] = misura.toFixed(3);
    	perimetri['km'] = (misura/1000).toFixed(3);
		
	    //perimeter contiene il perimetro 
	    var unitamisura = document.getElementById('unitamisuraperimetro').value;
	      //conversione in base all'unita di misura scelta per il perimetro
	    if (unitamisura=='km') {
	    	misura = misura/1000;
	    } 
	    misura = misura.toFixed(3);
	    element.value =misura ;       
        
    }
  
    //toggleSideBar('open');
}
//funzione invocata quando seleziono i checkbox per scegliere
// le distanze o le aree 
function toggleControlMeasure(evt) {
	
	//elimino i marker degli eventuali
	//indirizzi, dei percorsi, dei poi e delle 
	//località e pulisco il div dei risultati laterale
	if (dirs!=null) {
		dirs.reset();
	}
	
	if (addr!=null) {
		addr.reset();
	}
	
	clearObjectMarkers();
	
	reset_init();
	
	var radios = document.getElementsByName('misure');
    for (i=0;i<radios.length;i++) {
          var radio = radios[i];
          if(this.value != radio.value) { 
             radio.checked=false;  
             document.getElementById(radio.value).className = 'spandistanzearee'; 
          }          
    }
    
    var span = document.getElementById(this.value);        
    
    var  ele = evt.target || evt.srcElement;
		
	if (ele.tagName.toUpperCase()=='SPAN') {    
	    if(this.checked==false) { 
	       	 this.checked=true;
	       	 span.className = 'spandistanzeareeselected';
	    }
	    else {
	    	 this.checked=false;
	    	 span.className = 'spandistanzearee';
	    }
	} else	{
		 if(this.checked==false) {
		 	span.className = 'spandistanzearee';	 	
		 } else {
		 	span.className = 'spandistanzeareeselected';
		 }
	}
    
    
    if (document.getElementById('unitamisuraarea')!=null) {
      	document.getElementById('unitamisuraarea').value = 'm2';
    }        
    if (document.getElementById('unitamisuraperimetro')!=null) {
       	document.getElementById('unitamisuraperimetro').value = 'm';
    }        
    if (document.getElementById('unitamisura')!=null) {
       	document.getElementById('unitamisura').value = 'm';
    }
    
    distanze = {
   	'm':'',
   	'km':'',
   	'mi':'',
  	'nm':''
	};
		   
	aree = {
   	'm2':'',
   	'km2':'',
   	'et':''
	};
		   
	perimetri = {
   	'm':'',
   	'km':''
	}; 
    
    //svuoto i risultati del perimetro
    var element = document.getElementById('resultMeasurePerimetro');
    if (element!=null) {
    	element.value = '';    	
    }
    //svuoto i risultati delle aree
    var element = document.getElementById('resultMeasureArea');
    if (element!=null) {
    	element.value = '';    	
    }
    //svuoto i risultati dellle distanze
    var element = document.getElementById('resultMeasure');
    if (element!=null) {
    	element.value = '';    	
    }    
    //svuoto i risultati delle coordinate
    var element = document.getElementById('resultCoord');
    if (element!=null) {
    	element.value = '';    	
    }    
    
    var element = document.getElementById('resultLink');
    if (element!=null) {
    	element.value = '';    	
    }    

    //seleziono il poligono come figura iniziale cliccandi il checkbox delle aree
    if (document.getElementById('cerchio')!=null) {
	    var img = document.getElementById('cerchio');	    
		img.src = OpenLayers.ImgPath + 'toolbar/external/cir_off.png';
    }
    if (document.getElementById('poligono')!=null) {
		var img = document.getElementById('poligono');
		img.src = OpenLayers.ImgPath + 'toolbar/external/pol_on.png';
    }
    if (document.getElementById('rettangolo')!=null) {
		var img = document.getElementById('rettangolo');
		img.src = OpenLayers.ImgPath + 'toolbar/external/rect_off.png';
    }
    
    var distanza = document.getElementById('misuredistanza');
    var area = document.getElementById('misurearea');
    var coordinate = document.getElementById('misurecoord');
    
    if (distanza!=null && area!=null) {
    	 if(this.value == 'polygon' && this.checked) {
    	 	area.style.backgroundColor = 'rgb(255, 204, 102)' ;
    	 	distanza.style.backgroundColor = 'white' ;
    	 	coordinate.style.backgroundColor = 'white' ;
    	 	
    	 	var resultDistanza = document.getElementById('measuredistanza');
    	 	if (resultDistanza!=null)
    	 	{
    	 		 resultDistanza.style.display = 'none';
    	 	     resultDistanza.style.visibility = 'hidden';
    	 	}    	 	
    	 	
    	 	var resultArea = document.getElementById('measurearea');
    	 	
    	 	if (resultArea!=null)
    	 	{
    	 		resultArea.style.display = 'block';
    	 		resultArea.style.visibility = 'visible';
    	 	} 	
    	 	
     	 	var resultCoord = document.getElementById('measurecoord');  	 	
    	 	if (resultCoord!=null)
    	 	{
    	 		resultCoord.style.display = 'none';
    	 		resultCoord.style.visibility = 'hidden';
   	 			coordinateButton.deactivate();
     	 	} 	

    	 }
    	 else if (this.value == 'line' && this.checked){
    	 	area.style.backgroundColor = 'white' ;
    	 	distanza.style.backgroundColor = 'rgb(255, 204, 102)' ;
    	 	coordinate.style.backgroundColor = 'white' ;
    	 	
    	 	var resultDistanza = document.getElementById('measuredistanza');
    	 	if (resultDistanza!=null)
    	 	{
    	 		 resultDistanza.style.display = 'block';
    	 	     resultDistanza.style.visibility = 'visible';
    	 	}    	 	
    	 	
    	 	var resultArea = document.getElementById('measurearea');
    	 	
    	 	if (resultArea!=null)
    	 	{
    	 		resultArea.style.display = 'none';
    	 		resultArea.style.visibility = 'hidden';
    	 	} 	
    	 	
     	 	var resultCoord = document.getElementById('measurecoord');  	 	
    	 	if (resultCoord!=null)
    	 	{
    	 		resultCoord.style.display = 'none';
    	 		resultCoord.style.visibility = 'hidden';
    	 		coordinateButton.deactivate();
    	 	} 	

	   	 }
    	 else if (this.value == 'coord' && this.checked){
    	 	distanza.style.backgroundColor = 'white' ;
    	 	area.style.backgroundColor = 'white' ;
    	 	coordinate.style.backgroundColor = 'rgb(255, 204, 102)' ;
    	 	
    	 	var resultDistanza = document.getElementById('measuredistanza');
    	 	if (resultDistanza!=null)
    	 	{
    	 		 resultDistanza.style.display = 'none';
    	 	     resultDistanza.style.visibility = 'hidden';
    	 	}    	 	
    	 	
    	 	var resultArea = document.getElementById('measurearea');  	 	
    	 	if (resultArea!=null)
    	 	{
    	 		resultArea.style.display = 'none';
    	 		resultArea.style.visibility = 'hidden';
    	 	} 	
    	 	
    	 	var resultCoord = document.getElementById('measurecoord');  	 	
    	 	if (resultCoord!=null)
    	 	{
    	 		resultCoord.style.display = 'block';
    	 		resultCoord.style.visibility = 'visible';
    	 		coordinateButton.activate();
    	 	} 	

   	 	
    	 } else {
    	 	distanza.style.backgroundColor = 'white' ;
    	 	area.style.backgroundColor = 'white' ;
     	 	coordinate.style.backgroundColor = 'white' ;
   	 	
    	 	var resultDistanza = document.getElementById('measuredistanza');
    	 	if (resultDistanza!=null)
    	 	{
    	 		 resultDistanza.style.display = 'none';
    	 	     resultDistanza.style.visibility = 'hidden';
    	 	}    	 	
    	 	
    	 	var resultArea = document.getElementById('measurearea');
    	 	
    	 	if (resultArea!=null)
    	 	{
    	 		resultArea.style.display = 'none';
    	 		resultArea.style.visibility = 'hidden';
    	 	} 	 	 	
    	 	
     	 	var resultCoord = document.getElementById('measurecoord');  	 	
    	 	if (resultCoord!=null)
    	 	{
    	 		resultCoord.style.display = 'none';
    	 		resultCoord.style.visibility = 'hidden';
   	 			coordinateButton.deactivate();
     	 	} 	
    	 }
    }            	
		
	for(key in measureControls) {
        var control = measureControls[key];
        if(this.value == key && this.checked) {
            control.activate();
        } else {
            control.deactivate();
        }
    }
}

//funzione invocata per cancellare i percorsi disegnati per calcolare le misure 
function cancellaPercorso(evt) {
	
	for(key in this) {
        var control = this[key];
        if(control.active==true) {
        	if (control.handler.layer!=null)
        	{
        		control.handler.deleteGeometry();
        	}            
        } 
    }
    
	if (document.getElementById('resultMeasure')!=null) {
	   	document.getElementById('resultMeasure').value = '';            	
	}	   
	var element = document.getElementById('resultMeasurePerimetro');
	if (element!=null) {
	   	element.value = '';    	
	}
	var element = document.getElementById('resultMeasureArea');
	if (element!=null) {
	   	element.value = '';    	
	}

    distanze = {
	   	'm':'',
	   	'km':'',
	   	'mi':'',
	  	'nm':''
	};
		   
	aree = {
	   	'm2':'',
	   	'km2':'',
	   	'et':''
	};
		   
	perimetri = {
	   	'm':'',
	   	'km':''
	}; 
		
}	

//funzione invocata per selezionare i tipo di figura che si vuole disegnare per 
//calcolare le misure
function selezionaFigura(evt) {
	
	for(key in measureControls) {
        var control = measureControls[key];
        control.deactivate();        
    }
    
     //svuoto i risultati del perimetro
    var element = document.getElementById('resultMeasurePerimetro');
    if (element!=null) {
    	element.value = '';    	
    }
    //svuoto i risultati delle aree
    var element = document.getElementById('resultMeasureArea');
    if (element!=null) {
    	element.value = '';    	
    }
    //svuoto i risultati dellle distanze
    var element = document.getElementById('resultMeasure');
    if (element!=null) {
    	element.value = '';    	
    }    
    
    if (this.handler.CLASS_NAME=='Point') {
    	var img = document.getElementById('cerchio');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/cir_on.png';
    	var img = document.getElementById('poligono');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/pol_off.png';
    	var img = document.getElementById('rettangolo');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/rect_off.png';
    } else if (this.handler.CLASS_NAME=='Polygon') {
      	var img = document.getElementById('cerchio');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/cir_off.png';
    	var img = document.getElementById('poligono');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/pol_on.png';
    	var img = document.getElementById('rettangolo');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/rect_off.png';
    } else if (this.handler.CLASS_NAME=='Rectangle') {
      	var img = document.getElementById('cerchio');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/cir_off.png';
    	var img = document.getElementById('poligono');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/pol_off.png';
    	var img = document.getElementById('rettangolo');
    	img.src = OpenLayers.ImgPath + 'toolbar/external/rect_on.png';
    }
	
	this.activate();
	
}	

//funzione invocata quando cambio unita di musura per
// le distanze, le aree e i perimetri
function convertMeasure(evt) {
    
    var inputunita = this['inputunita'];
    //il vettore con i risultati per ogni conversione
    var measure = this['measure'];
    var inputrisultato = this['inputrisultato'];
    
    //unita di destinazione
	var unitadest = document.getElementById(inputunita);
	//risultato da convertire
	var risultato = document.getElementById(inputrisultato);
		
	if (unitadest!=null && risultato!=null) {	
		
		if (risultato.value!=null && risultato.value!='') {
			var dest = unitadest.value;
			var numero = risultato.value;		
			if (measure=='distanza') {
				risultato.value = distanze[dest];
			} else if (measure=='area') {
				risultato.value = aree[dest];
			} else if (measure=='perimetro') {
				risultato.value = perimetri[dest];
			}	
						
		}	
	}	
}	

	//funzione invocata per inserire le coordinate del punto cliccato 
	function calcolaCoordinate(lonlat) {
		var resultCoord = document.getElementById('resultCoord');  	 	
		var checkCoord = document.getElementById('checkcoord');  	 	
		if (checkCoord.checked)
		{
			resultCoord.value =  roundNumber(lonlat.lon,0) + " , " + roundNumber(lonlat.lat,0);
		} 	
		creaLink(lonlat);
	}



    /**
	 * round number to decimal dec value
    */
    function roundNumber (num, dec) {
    	var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
    	return result;
    }
    
    
    //funzione invocata per cancellare i percorsi disegnati per calcolare le misure 
function selectInput(evt) {
	//console.log (evt);
	var id = evt.currentTarget.id
	document.getElementById(id).select();	
}

/**
 * Class: Point
 * Handler to draw a point on the map.  Point is displayed on mouse down,
 * moves on mouse move, and is finished on mouse up.  The handler triggers
 * callbacks for 'done' and 'cancel'.  Create a new instance with the
 * <Point> constructor.
 * 
 * Inherits from:
 *  - <OpenLayers.Handler>
 */
Point = OpenLayers.Class(OpenLayers.Handler, {
    
    /**
     * Property: point
     * {<OpenLayers.Feature.Vector>} The currently drawn point
     */
    point: null,

    /**
     * Property: layer
     * {<OpenLayers.Layer.Vector>} The temporary drawing layer
     */
    layer: null,
    
    /**
     * Property: multi
     * {Boolean} Cast features to multi-part geometries before passing to the
     *     layer.  Default is false.
     */
    multi: false,
    
    /**
     * Property: drawing 
     * {Boolean} A point is being drawn
     */
    drawing: false,
    
    /**
     * Property: mouseDown
     * {Boolean} The mouse is down
     */
    mouseDown: false,

    /**
     * Property: lastDown
     * {<OpenLayers.Pixel>} Location of the last mouse down
     */
    lastDown: null,

    /**
     * Property: lastUp
     * {<OpenLayers.Pixel>}
     */
    lastUp: null,

    /**
     * APIProperty: persist
     * {Boolean} Leave the feature rendered until destroyFeature is called.
     *     Default is false.  If set to true, the feature remains rendered until
     *     destroyFeature is called, typically by deactivating the handler or
     *     starting another drawing.
     */
    persist: false,

    /**
     * Property: layerOptions
     * {Object} Any optional properties to be set on the sketch layer.
     */
    layerOptions: null,

    /**
     * Constructor: Point
     * Create a new point handler.
     *
     * Parameters:
     * control - {<OpenLayers.Control>} The control that owns this handler
     * callbacks - {Object} An object with a 'done' property whose value is a
     *             function to be called when the point drawing is finished.
     *             The callback should expect to recieve a single argument,
     *             the point geometry.  If the callbacks object contains a
     *             'cancel' property, this function will be called when the
     *             handler is deactivated while drawing.  The cancel should
     *             expect to receive a geometry.
     * options - {Object} An optional object with properties to be set on the
     *           handler
     */
    initialize: function(control, callbacks, options) {
        // TBD: deal with style
        this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});

        OpenLayers.Handler.prototype.initialize.apply(this, arguments);
    },
    
    /**
     * APIMethod: activate
     * turn on the handler
     */
    activate: function() {
        if(!OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
            return false;
        }
        // create temporary vector layer for rendering geometry sketch
        // TBD: this could be moved to initialize/destroy - setting visibility here
        var options = OpenLayers.Util.extend({
            displayInLayerSwitcher: false,
            // indicate that the temp vector layer will never be out of range
            // without this, resolution properties must be specified at the
            // map-level for this temporary layer to init its resolutions
            // correctly
            calculateInRange: function() { return true; }
        }, this.layerOptions);
        this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
        this.map.addLayer(this.layer);
        return true;
    },
    
    /**
     * Method: createFeature
     * Add temporary features
     */
    createFeature: function() {
        this.point = new OpenLayers.Feature.Vector(
            new OpenLayers.Geometry.Point()
        );
        
        
        this.layer.addFeatures([this.point], {silent: true});
    },

    /**
     * APIMethod: deactivate
     * turn off the handler
     */
    deactivate: function() {
        if(!OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
            return false;
        }
        // call the cancel callback if mid-drawing
        if(this.drawing) {
            this.cancel();
        }
        this.destroyFeature();
        // If a layer's map property is set to null, it means that that layer
        // isn't added to the map. Since we ourself added the layer to the map
        // in activate(), we can assume that if this.layer.map is null it means
        // that the layer has been destroyed (as a result of map.destroy() for
        // example.
        if (this.layer.map != null) {
            this.layer.destroy(false);
        }
        this.layer = null;
        return true;
    },
    
    /**
     * Method: destroyFeature
     * Destroy the temporary geometries
     */
    destroyFeature: function() {
        if(this.layer) {
            this.layer.destroyFeatures();
        }
        this.point = null;
    },

    /**
     * Method: finalize
     * Finish the geometry and call the "done" callback.
     *
     * Parameters:
     * cancel - {Boolean} Call cancel instead of done callback.  Default is
     *     false.
     */
    finalize: function(cancel) {
        var key = cancel ? "cancel" : "done";
        this.drawing = false;
        this.mouseDown = false;
        this.lastDown = null;
        this.lastUp = null;
        this.callback(key, [this.geometryClone()]);
        if(cancel || !this.persist) {
            this.destroyFeature();
        }
    },

    /**
     * APIMethod: cancel
     * Finish the geometry and call the "cancel" callback.
     */
    cancel: function() {
        this.finalize(true);
    },

    /**
     * Method: click
     * Handle clicks.  Clicks are stopped from propagating to other listeners
     *     on map.events or other dom elements.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    click: function(evt) {
        OpenLayers.Event.stop(evt);
        return false;
    },

    /**
     * Method: dblclick
     * Handle double-clicks.  Double-clicks are stopped from propagating to other
     *     listeners on map.events or other dom elements.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    dblclick: function(evt) {
        OpenLayers.Event.stop(evt);
        return false;
    },
    
    /**
     * Method: drawFeature
     * Render features on the temporary layer.
     */
    drawFeature: function() {
        this.layer.drawFeature(this.point, this.style);       
    },
    
    /**
     * Method: getGeometry
     * Return the sketch geometry.  If <multi> is true, this will return
     *     a multi-part geometry.
     *
     * Returns:
     * {<OpenLayers.Geometry.Point>}
     */
    getGeometry: function() {
        var geometry = this.point.geometry;
        if(this.multi) {
            geometry = new OpenLayers.Geometry.MultiPoint([geometry]);
        }
        return geometry;
    },

    /**
     * Method: geometryClone
     * Return a clone of the relevant geometry.
     *
     * Returns:
     * {<OpenLayers.Geometry>}
     */
    geometryClone: function() {
        return this.getGeometry().clone();
    },
  
    /**
     * Method: mousedown
     * Handle mouse down.  Adjust the geometry and redraw.
     * Return determines whether to propagate the event on the map.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mousedown: function(evt) {
          // check keyboard modifiers
        if(!this.checkModifiers(evt)) {
            return true;
        }
        // ignore double-clicks
        if(this.lastDown && this.lastDown.equals(evt.xy)) {
           this.finalize();
            return false;
        }
        if(this.lastDown == null) {
            if(this.persist) {
                this.destroyFeature();
            }
            this.createFeature();
        }
        this.lastDown = evt.xy;
        
        if ( this.drawing) {
        	
        	var lonlat = this.map.getLonLatFromPixel(evt.xy);
        	this.pointFixed = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
            this.pointFixed.geometry.x = lonlat.lon;
	        this.pointFixed.geometry.y = lonlat.lat;
	        this.pointFixed.geometry.clearBounds();                            
       		this.layer.addFeatures([this.pointFixed], {silent: true});  	
       		
       		
       		if (this.layer!=null) {
	        	if (this.layer.features.length>0) {
	        		var feature = this.layer.features[0];
	        		var centrox = feature.geometry.x;
					var centroy = feature.geometry.y;
					
					var dx2 = Math.pow(centrox - lonlat.lon, 2);
             		var dy2 = Math.pow(centroy - lonlat.lat, 2);
             		var distance = Math.sqrt( dx2 + dy2 );
             		
             		var x = centrox+distance;
					var y = centroy;
					var pointf = map.getViewPortPxFromLonLat(new OpenLayers.LonLat(x,y));
					x = centrox;
					y = centroy;
					var pointi = map.getViewPortPxFromLonLat(new OpenLayers.LonLat(x,y));
					distance = (new Number(pointf.x - pointi.x)).valueOf();
					
			        var style = {
			            pointRadius: 1,
			            fillColor: "white",
			            fillOpacity: 0,
			            strokeWidth: 2,
			            strokeOpacity: 1,
			            strokeColor: "#181CB4"
			        }; 	      	
			        
			        style.pointRadius = distance;		
        			if (distance<=0) {
        				style.pointRadius = 1;
        			}
					feature.style = style;   
			        this.layer.drawFeature(feature,style);		        		    		
	        	}      	
	        }      	
	        
	        this.layer.drawFeature(this.pointFixed, this.style); 	
       		
        	this.finalize();
            return false;
        }        
        if (! this.drawing) {
        	
	        this.drawing = true;
	        var lonlat = this.map.getLonLatFromPixel(evt.xy);
	        this.point.geometry.x = lonlat.lon;
	        this.point.geometry.y = lonlat.lat;
	        this.point.geometry.clearBounds();	         
	                                  
       		this.pointFixed = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
            this.pointFixed.geometry.x = lonlat.lon;
	        this.pointFixed.geometry.y = lonlat.lat;
	        this.pointFixed.geometry.clearBounds();                            
       		this.layer.addFeatures([this.pointFixed], {silent: true});  	
       		this.layer.drawFeature(this.pointFixed, this.style);      		        
	       
	        this.drawFeature();	        
        }
        return false;
    },
    
    /**
     * Method: finalize
     * Finish the geometry and call the "done" callback.
     *
     * Parameters:
     * cancel - {Boolean} Call cancel instead of done callback.  Default is
     *     false.
     */
   deleteGeometry:function() {
        this.drawing = false;
        this.mouseDown = false;
        this.lastDown = null;
        this.lastUp = null;
        if (this.layer!=null) {
	        this.layer.renderer.clear();
	        this.layer.destroyFeatures();
    	}
        return true;
   },

    /**
     * Method: mousemove
     * Handle mouse move.  Adjust the geometry and redraw.
     * Return determines whether to propagate the event on the map.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mousemove: function (evt) {
     
      
        return true;
    },

    /**
     * Method: mouseup
     * Handle mouse up.  Send the latest point in the geometry to the control.
     * Return determines whether to propagate the event on the map.
     *
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mouseup: function (evt) {
      
        return true;
        
    },

    CLASS_NAME: "Point"
});


/**
 * Class: Path
 * Handler to draw a path on the map.  Path is displayed on mouse down,
 * moves on mouse move, and is finished on mouse up.
 *
 * Inherits from:
 *  - <Point>
 */
Path = OpenLayers.Class(Point, {
    
    /**
     * Property: line
     * {<OpenLayers.Feature.Vector>}
     */
    line: null,
     
     /**
     * Property: firstDown
     * {<boolean>}
     */
    firstDown:true,
    
   

    /**
     * Constructor: Path
     * Create a new path hander
     *
     * Parameters:
     * control - {<OpenLayers.Control>} 
     * callbacks - {Object} An object with a 'done' property whos value is a
     *     function to be called when the path drawing is finished. The 
     *     callback should expect to recieve a single argument, the line 
     *     string geometry. If the callbacks object contains a 'point' 
     *     property, this function will be sent each point as they are added.  
     *     If the callbacks object contains a 'cancel' property, this function 
     *     will be called when the handler is deactivated while drawing. The 
     *     cancel should expect to receive a geometry.
     * options - {Object} An optional object with properties to be set on the
     *           handler
     */
    initialize: function(control, callbacks, options) {
        Point.prototype.initialize.apply(this, arguments);
    },
        
     
     /**
     * APIMethod: activate
     * turn on the handler
     */
    activate: function() {
        if(!OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
            return false;
        }
        // create temporary vector layer for rendering geometry sketch
        // TBD: this could be moved to initialize/destroy - setting visibility here
        var options = OpenLayers.Util.extend({
            displayInLayerSwitcher: false,
            // indicate that the temp vector layer will never be out of range
            // without this, resolution properties must be specified at the
            // map-level for this temporary layer to init its resolutions
            // correctly
            calculateInRange: function() { return true; }
        }, this.layerOptions);
        this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
        this.map.addLayer(this.layer);
        this.markersLayer = new OpenLayers.Layer.Markers( "MarkersLayer" );
		this.map.addLayer(this.markersLayer);
        return true;
    },
     
     
         
    /**
     * Method: destroyFeature
     * Destroy temporary geometries
     */
    destroyFeature: function() {
    	this.firstDown = true;
        Point.prototype.destroyFeature.apply(this);
        this.line = null;
    },

  
    /**
     * Method: addPoint
     * Add point to geometry.  Send the point index to override
     * the behavior of LinearRing that disregards adding duplicate points.
     */
    addPoint: function() {
    	this.line.geometry.addComponent(this.point.geometry.clone(),
                                        this.line.geometry.components.length);
        this.callback("point", [this.point.geometry, this.getGeometry()]);
    },
    
   /**
     * Method: drawFeature
     * Render geometries on the temporary layer.
     */
    drawFeature: function() {
        this.layer.drawFeature(this.line, this.style);
        this.layer.drawFeature(this.point, this.style);
        if (this.layer.features!=null)
        {
           for(var i=1; i<this.layer.features.length ; i++){
	 	     this.layer.drawFeature(this.layer.features[i], this.style);
     	   }
        }
    },

    /**
     * Method: getGeometry
     * Return the sketch geometry.  If <multi> is true, this will return
     *     a multi-part geometry.
     *
     * Returns:
     * {<OpenLayers.Geometry.LineString>}
     */
    getGeometry: function() {
        var geometry = this.line.geometry;
        if(this.multi) {
            geometry = new OpenLayers.Geometry.MultiLineString([geometry]);
        }
        return geometry;
    },

    /**
     * Method: mousedown
     * Handle mouse down.  Add a new point to the geometry and
     * render it. Return determines whether to propagate the event on the map.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mousedown: function(evt) {    	
        if (this.firstDown) {
        	  var offset = new OpenLayers.Pixel(-(68/2), -48);
        	  var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
			                                         
			  var icon =  new OpenLayers.Icon(OpenLayers.ImgPath + 'play.png', new OpenLayers.Size(68, 48),offset);
             
		      this.markerStart = new OpenLayers.Marker(lonlat,icon);
		      this.markersLayer.addMarker(this.markerStart); 
        	
        	  this.line = new OpenLayers.Feature.Vector(
	                                        new OpenLayers.Geometry.LineString());
    	                               
       		  this.point = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
       		  this.layer.addFeatures([this.line, this.point], {silent: true});  
        } else {
        	 
        	  if (this.markersLayer.markers!=null && this.markersLayer.markers.length>1) {
        	  	var marker = this.markersLayer.markers[1];
        	  	this.markersLayer.removeMarker(this.markersLayer.markers[1]); 
        	  	marker.destroy();
        	  }
        	  var offset = new OpenLayers.Pixel(-(68/2), -48);
        	  var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
			                                         
			  var icon =  new OpenLayers.Icon(OpenLayers.ImgPath + 'stop.png', new OpenLayers.Size(68, 48),offset);
             
		      this.markerEnd = new OpenLayers.Marker(lonlat,icon);
		      this.markersLayer.addMarker(this.markerEnd);  
        	 
        	 this.point = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
       		 this.layer.addFeatures([this.point], {silent: true});  
        }      
        var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
        this.point.geometry.x = lonlat.lon;
        this.point.geometry.y = lonlat.lat;
        this.point.geometry.clearBounds();
        this.addPoint();
        this.drawFeature();
        this.firstDown = false;
        return false;
    },

    /**
     * Method: mousemove
     * Handle mouse move.  Adjust the geometry and redraw.
     * Return determines whether to propagate the event on the map.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mousemove: function (evt) {
    	
        return true;
    },
    
    /**
     * Method: mouseup
     * Handle mouse up.  Send the latest point in the geometry to
     * the control. Return determines whether to propagate the event on the map.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mouseup: function (evt) {
    	
        return true;
    },
  
    /**
     * Method: dblclick 
     * Handle double-clicks.  Finish the geometry and send it back
     * to the control.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    dblclick: function(evt) {    	
       return true;
    },
    
     /**
     * Method: finalize
     * Finish the geometry and call the "done" callback.
     *
     * Parameters:
     * cancel - {Boolean} Call cancel instead of done callback.  Default is
     *     false.
     */
    deleteGeometry: function() {
       this.firstDown = true;
       if(this.markersLayer != null) {
			  if (this.markersLayer.markers != null) {
	            while(this.markersLayer.markers.length > 0) {
	            	var marker = this.markersLayer.markers[0];
	            	this.markersLayer.removeMarker(marker);
	            	marker.destroy();
	            }
	        }
	   }
       if (this.layer!=null) {
	        this.layer.renderer.clear();
	        this.layer.destroyFeatures();
    	}
        return true;
    },
    
     /**
     * APIMethod: deactivate
     * turn off the handler
     */
    deactivate: function() {
    	this.firstDown = true;
        if(!OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
            return false;
        }
        // call the cancel callback if mid-drawing
        if(this.drawing) {
            this.cancel();
        }
        this.destroyFeature();
        // If a layer's map property is set to null, it means that that layer
        // isn't added to the map. Since we ourself added the layer to the map
        // in activate(), we can assume that if this.layer.map is null it means
        // that the layer has been destroyed (as a result of map.destroy() for
        // example.
        if (this.layer.map != null) {
            this.layer.destroy(false);
        }
        this.layer = null;
        
        if (this.markersLayer.map != null) {
            this.markersLayer.destroy(false);
        }
        this.markersLayer = null;
       
       
        return true;
    },
    
    
    
    CLASS_NAME: "Path"
});

/**
 * Class: Polygon
 * Handler to draw a polygon on the map.  Polygon is displayed on mouse down,
 * moves on mouse move, and is finished on mouse up.
 *
 * Inherits from:
 *  - <OpenLayers.Handler.Path>
 *  - <OpenLayers.Handler>
 */
Polygon = OpenLayers.Class(Path, {
    
    /**
     * Parameter: polygon
     * {<OpenLayers.Feature.Vector>}
     */
    polygon: null,

    /**
     * Constructor: OpenLayers.Handler.Polygon
     * Create a Polygon Handler.
     *
     * Parameters:
     * control - {<OpenLayers.Control>} 
     * callbacks - {Object} An object with a 'done' property whos value is
     *                          a function to be called when the path drawing is
     *                          finished. The callback should expect to recieve a
     *                          single argument, the polygon geometry.
     *                          If the callbacks object contains a 'point'
     *                          property, this function will be sent each point
     *                          as they are added.  If the callbacks object contains
     *                          a 'cancel' property, this function will be called when
     *                          the handler is deactivated while drawing.  The cancel
     *                          should expect to receive a geometry.
     * options - {Object} 
     */
    initialize: function(control, callbacks, options) {
        Path.prototype.initialize.apply(this, arguments);
    },
    
     /**
     * Method: mousedown
     * Handle mouse down.  Add a new point to the geometry and
     * render it. Return determines whether to propagate the event on the map.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mousedown: function(evt) {    	
        if (this.firstDown) {
        	    this.polygon = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Polygon());
        		this.line = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.LinearRing());
        		this.polygon.geometry.addComponent(this.line.geometry);
        		this.point = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
       			this.layer.addFeatures([this.polygon, this.point], {silent: true});
        } else {
        	 this.point = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
       		 this.layer.addFeatures([this.point], {silent: true});  
        }      
        var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
        this.point.geometry.x = lonlat.lon;
        this.point.geometry.y = lonlat.lat;
        this.point.geometry.clearBounds();
        this.addPoint();
        this.drawFeature();
        this.firstDown = false;
        return false;
    },
    
    
    /**
     * Method: destroyFeature
     * Destroy temporary geometries
     */
    destroyFeature: function() {
    	this.firstDown = true;
        Path.prototype.destroyFeature.apply(this);
        this.polygon = null;
    },

    /**
     * Method: drawFeature
     * Render geometries on the temporary layer.
     */
    drawFeature: function() {
        this.layer.drawFeature(this.polygon, this.style);
        this.layer.drawFeature(this.point, this.style);
        if (this.layer.features!=null)
        {
           for(var i=1; i<this.layer.features.length ; i++){
	 	     this.layer.drawFeature(this.layer.features[i], this.style);
     	   }
        }
       
	
    },
    
    /**
     * Method: getGeometry
     * Return the sketch geometry.  If <multi> is true, this will return
     *     a multi-part geometry.
     *
     * Returns:
     * {<OpenLayers.Geometry.Polygon>}
     */
    getGeometry: function() {
        var geometry = this.polygon.geometry;
        if(this.multi) {
            geometry = new OpenLayers.Geometry.MultiPolygon([geometry]);
        }
        return geometry;
    },

  

    CLASS_NAME: "Polygon"
});


Rectangle = OpenLayers.Class(Path, {

      /**
     * Parameter: polygon
     * {<OpenLayers.Feature.Vector>}
     */
    polygon: null,

    /**
     * Constructor: OpenLayers.Handler.Polygon
     * Create a Polygon Handler.
     *
     * Parameters:
     * control - {<OpenLayers.Control>} 
     * callbacks - {Object} An object with a 'done' property whos value is
     *                          a function to be called when the path drawing is
     *                          finished. The callback should expect to recieve a
     *                          single argument, the polygon geometry.
     *                          If the callbacks object contains a 'point'
     *                          property, this function will be sent each point
     *                          as they are added.  If the callbacks object contains
     *                          a 'cancel' property, this function will be called when
     *                          the handler is deactivated while drawing.  The cancel
     *                          should expect to receive a geometry.
     * options - {Object} 
     */
    initialize: function(control, callbacks, options) {
       Path.prototype.initialize.apply(this, arguments);
    },
    
     /**
     * Method: mousedown
     * Handle mouse down.  Add a new point to the geometry and
     * render it. Return determines whether to propagate the event on the map.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mousedown: function(evt) {    	
        if (this.firstDown) {
        	   if (this.layer!=null) {
			        this.layer.renderer.clear();
			        this.layer.destroyFeatures();
		    	}  	
		    	
        	    this.polygon = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Polygon());
        		this.line = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.LinearRing());
        		this.polygon.geometry.addComponent(this.line.geometry);
        		this.point = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
       			this.layer.addFeatures([this.polygon, this.point], {silent: true});
       			var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
	            this.point.geometry.x = lonlat.lon;
	        	this.point.geometry.y = lonlat.lat;
	        	this.point.geometry.clearBounds();
	        	this.addPoint();
	        	this.drawFeature();
	        	this.firstDown = false;
        } else {
        	 if (!this.drawing)
        	 {
        	 	 this.point = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
       		     this.layer.addFeatures([this.point], {silent: true});  
       		     
       		     var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
	       		 this.point.geometry.x = lonlat.lon;
	        	 this.point.geometry.y = lonlat.lat;
	             this.point.geometry.clearBounds();
	             this.addPoint();
	             this.drawFeature();
	             
	             this.point = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
       		     this.layer.addFeatures([this.point], {silent: true});  
       		     
       		     var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
	       		 this.point.geometry.x = lonlat.lon;
	        	 this.point.geometry.y = lonlat.lat;
	             this.point.geometry.clearBounds();
	             this.addPoint();
	             this.drawFeature();
	             
	             this.point = new OpenLayers.Feature.Vector(
                                        new OpenLayers.Geometry.Point());
       		     this.layer.addFeatures([this.point], {silent: true});  
       		     this.point.geometry.x = this.layer.features[1].geometry.x;
	        	 this.point.geometry.y = this.layer.features[1].geometry.y;
	             this.point.geometry.clearBounds();
	             this.addPoint();
	             this.drawFeature();	             
	             
	             this.firstDown = false;
       		     this.drawing = true;
        	 }
        	 else {
        	 	 this.firstDown = true;
        	 	 this.drawing = false;        	 
        	 }
        	
        }      
       
        return false;
    },
    
      /**
     * Method: mousemove
     * Handle mouse move.  Adjust the geometry and redraw.
     * Return determines whether to propagate the event on the map.
     * 
     * Parameters:
     * evt - {Event} The browser event
     *
     * Returns: 
     * {Boolean} Allow event propagation
     */
    mousemove: function (evt) {    	
    	
    	 if (this.drawing) {
    	 	        		 
       		 if (this.layer!=null) {
	        	if (this.layer.features.length==5) {        	
					
					var feature = this.layer.features[4];
	        		var pointx = feature.geometry.x;
					var pointy = feature.geometry.y;
					
					var punto1 = this.layer.features[1];
	        		var point1x = punto1.geometry.x;
					var point1y = punto1.geometry.y;
					var punto2 = this.layer.features[2];
	        		var point2x = punto2.geometry.x;
					var point2y = punto2.geometry.y;
					//costruzione rettangolo come prima cosa
					//calcolo il coefficiente angolare tra i primi dur punti 
					// inseriti 
					//calcolo retta parallela alla retta passante per i primi due punti inseriti
					var m1 = (point2y - point1y) / (point2x - point1x);
					//uso il punto dell'evento in quanto questa retta parallela passa per il punto dell'evento
					var lonlat = this.control.map.getLonLatFromPixel(evt.xy);			    
					//secondo la formula y=mx+q dell aretta calcolo il termine noto				
					var q1 = lonlat.lat - (m1 * lonlat.lon); 
					//calcolo coefficiente angolare della retta perpendicolare alla retta calcolata precedentemente
					var m2 = -1/m1;
					
					var q2 = point1y - (m2 * point1x); 
					
					var x = (q2-q1)/(m1-m2);
					var y = (m1*x)+q1;
					
					this.layer.features[4].geometry.x = x;
		       		this.layer.features[4].geometry.y = y;	  
		       		
		       		this.line.geometry.components[3].x = x;
					this.line.geometry.components[3].y = y;
					this.line.geometry.components[3].clearBounds();  
				    //costruzione terzo punto
				    q2 = point2y - (m2 * point2x); 
					
					x = (q2-q1)/(m1-m2);
					y = (m1*x)+q1;
					
					this.layer.features[3].geometry.x = x;
		       		this.layer.features[3].geometry.y = y;	  
		       		
		       		this.line.geometry.components[2].x = x;
					this.line.geometry.components[2].y = y;
					this.line.geometry.components[2].clearBounds();    		
	       		 	   
                   
				    this.layer.drawFeature(this.polygon, this.style);
				    if (this.layer.features!=null)
			        {
			           for(var i=1; i<this.layer.features.length ; i++){
				 	     this.layer.drawFeature(this.layer.features[i], this.style);
			     	   }
			        }	
				    this.callback("done", [this.getGeometry()]);		          		   
	       		    
	        	}	
       		 }	         
    	 }
    	
        return true;
    },
    
    /**
     * Method: destroyFeature
     * Destroy temporary geometries
     */
    destroyFeature: function() {
    	this.firstDown = true;
        Path.prototype.destroyFeature.apply(this);
        this.polygon = null;
    },

    /**
     * Method: drawFeature
     * Render geometries on the temporary layer.
     */
    drawFeature: function() {
        this.layer.drawFeature(this.polygon, this.style);
        this.layer.drawFeature(this.point, this.style);
        if (this.layer.features!=null)
        {
           for(var i=1; i<this.layer.features.length ; i++){
	 	     this.layer.drawFeature(this.layer.features[i], this.style);
     	   }
        }
    },
    
    /**
     * Method: getGeometry
     * Return the sketch geometry.  If <multi> is true, this will return
     *     a multi-part geometry.
     *
     * Returns:
     * {<OpenLayers.Geometry.Polygon>}
     */
    getGeometry: function() {
        var geometry = this.polygon.geometry;
        if(this.multi) {
            geometry = new OpenLayers.Geometry.MultiPolygon([geometry]);
        }
        return geometry;
    },    
    
    
   

    CLASS_NAME: "Rectangle"
});





