/**
 * @requires OpenLayers/Ajax.js
 * 
 * Class: InfoSardegnaMappe
 * Allows to do an info. 
 
 */

InfoSardegnaMappe = OpenLayers.Class( OpenLayers.Control,{

  /** 
     * Property: type
     * {OpenLayers.Control.TYPES}
     */
    type: OpenLayers.Control.TYPE_TOOL,   
        
    /**
    * Property: info_format 
    * {String} output format
    */  
    info_format: 'text/html',
    
   
    /**
    * Property: srs
    * {String} srs
    */  
    srs: 'EPSG:3003',
     
     /**
    * Property: lonlatInfo
	* {OpenLayers.LonLat} lonlatInfo point info
	*/
    lonlatInfo: null,   
     
    /**
    * Property: layers
    * {Array(Object)} Layer list
    */
    layers:[],
    
    /**
    * Property: layersOtherWMS
    * {Array(Object)} Layer list
    */
    layersOtherWMS: [],
    
      /**
    * @private 
	* Property: markersLayer
	* {MW.Layer.Markers} marker Layer
	*/
	markersLayer: null,
    
    /**
    * Property: iconUrl
    * {String} The relative path of icon image. This path is added to constant OpenLayers.ImgPath
    */
    iconUrl:  "signal.gif",

    /**
    * Property: iconSize
    * {OpenLayers.Size} size icon associated to markers
    */
    iconSize: new OpenLayers.Size(1, 1), 
     
     
     /**
    * Property: tolerance
    * {Integer} The selection tolerance is used 
    * select features within the specified square side.
    * Default value is 50.
    */
    tolerance: 10,
    
    /**
    * Property: featureCount
    * {Integer} Max number of features.
    * Default value is 50.
    */
    featureCount: 50,
    
    /**
    * Property: extent
    * {OpenLayers.Bounds} extent to search 
    */
     extent: null,
     
     
     /**
      * Property: xslPath
      * path xsl trasforma risposta servizio getfeatureinfo
      */
     xslPath: null,
     
     /**
      * Property: xsl
      */
     xsl: null,
     
     /**
      * Property: xsl
      */
     loading: null,
     
     /**
      * Property: url
      */
     url: null,
     
     /**
      * Property: urlOtherLayer
      */
     urlOtherLayer: null,
     
     
     /**
      * Property: xy
      */
     xy: null,
     
     htmlSITR : null,
     
      /**
      * Property: titleInfoBaloon
       */
     titleInfoBaloon: '<h1 class="featureInfo">Info Tematismi</h1>',
          

	/**
    * @private 
	* Property: EVENT_TYPES
	* {Array}
	*/
    EVENT_TYPES: ["loadComplete","loadFailure","successLoadFeature","activate","deactivate"],
    
    
	/**
	* Constructor: MW.Control.Aci.Info
	* Constructor for a new <MW.Control.Aci.Info> instance.
	*
	* Parameters:
	* options - {Object} layer that the tile will go in.
	*/
    initialize: function (options) {
    	OpenLayers.Control.prototype.initialize.apply(this, [options]);
    	/*this.id = OpenLayers.Util.createUniqueID('InfoSardegna');*/  
    	this.events = new OpenLayers.Events(this, this, this.EVENT_TYPES, this.fallThrough);
    	
    	 
    	//define marker layer
        this.markersLayer = new Roja.Layer.Markers( "markersSardegnaMappe" );		
        this.markersLayer.displayInLayerSwitcher=false;
        
        if (this.xslPath!=null && this.xslPath!='') {
			var successXslFunc = this.successXsl.bind(this);
			var faliureXslFunc = this.failureXsl.bind(this);
	
			// loading xsl file
	        new OpenLayers.Ajax.Request(this.xslPath,  
               {   method: 'get',
                   parameters: null,
                   onComplete: successXslFunc,
                   onFailure: faliureXslFunc
                }
               );
        }                      
           
    },
  
   
   	/**
    * @private 
    * Method: successXsl
    *
	* Parameters:
	* request - {}
	*/
	successXsl: function (request) {
	    this.xsl = request.responseXML;
    },
    
   

	/**
    * @private 
    * Method: failureXsl
    *
	* Parameters:
	* request - {}
	*/
	failureXsl: function (request) {
		alert('xsl not loaded');
		this.events.triggerEvent("loadFailure");
   		return;
    },
  
    /**
    * Method: draw
    * Draws the object on the map
    *
    * Returns:
	* {DOMElement}
	*/
    draw: function() {
    
       	this.handler = new OpenLayers.Handler.Drag(this,{"down": this.defaultMouseDown});
       	this.map.addLayer(this.markersLayer);
       	
         // to wiev loading state
	    this.loading = new Roja.Control.LoadingMessage();
	    if ((this.map != null) && (this.loading != null)) {
		    this.map.addControl(this.loading);		
	    }		
    	
    	
		
    },
    
    
   /**
    * Method: defaultMouseDown
    * This method is called during the handling 
    * of the mouse down event.
    * 
    * Parameters:
    * evt - {OpenLayers.Event} event
    */   
    defaultMouseDown: function (evt) {
    	 var minXY = this.map.getLonLatFromPixel(
                     new OpenLayers.Pixel(evt.x, evt.y));
        var maxXY = this.map.getLonLatFromPixel(
                     new OpenLayers.Pixel(evt.x, evt.y));
        
        
        this.lonlatInfo = this.map.getLonLatFromPixel(
                     new OpenLayers.Pixel(evt.x, evt.y));
        
        t = this.tolerance;
        t /= 2;
        minXY.lon -= t;
        minXY.lat -= t;
        maxXY.lon += t;
        maxXY.lat += t;

        var bounds = new OpenLayers.Bounds(minXY.lon, minXY.lat,
                                           maxXY.lon, maxXY.lat);
        this.extent = bounds;
        
        var layerPhysicalName = [];
        var layerPhysicalNameOther = [];
        
       
        this.urlOtherLayer = null;
    	for (var i = 0; i < this.map.layers.length; i++) {
	        var layer = this.map.layers[i];
	        if (layer.CLASS_NAME == 'OpenLayers.Layer.WMS' || (layer.CLASS_NAME == 'Roja.Layer.WMS' && layer.layers == null)) {
	        	if (layer.params.LAYERS && layer.params.LAYERS != '' && layer.visibility == true) {
	        		layerPhysicalNameOther.push(layer.params.LAYERS);
	        		this.urlOtherLayer = layer.url;
	        	}
	        }
	        else {
	        		if (layer.layers && layer.layers!=null && layer.layers.length>0) {
	        			for (var k = 0; k < layer.layers.length; k++) {
	        				var wmsLayer = layer.layers[k];
	        				if (wmsLayer.CLASS_NAME == 'Roja.WMSLayer' && wmsLayer.visibility == true) {
	        				 	layerPhysicalName.push(wmsLayer.physicalName);
	        				 	if(this.url == null) {
	        				 	    this.url = layer.url;
	        				 	}
	        		        }
	        			}
	        		}
	        }
	    }
	    
	    
	    this.xy = {x: evt.x, y: evt.y};
	    this.layers = layerPhysicalName;
	    this.layersOtherWMS = layerPhysicalNameOther;
	    this.htmlSITR = null;
	    
	   
	    
	    /*
	     * this.events.register('click', this, this.stopevent);
	    if ((this.xy.x == 52 &&  this.xy.x == 236) && this.active==true){
	    	this.deactivate();
	    }*/
	    if(this.layers.length == 0 && this.layersOtherWMS.length == 0) {
        	msg = '<br><br><br><br><h1 class="featureInfo">Per consultare le Info attivare i tematismi dalla colonna del menu a sinistra</h1>';
        	//creo un baloon che comunichi l'errore
        	var lonLat = this.map.getLonLatFromPixel(new OpenLayers.Pixel(this.xy.x,this.xy.y));
        	this.showMarker(lonLat,msg);
        	
        	this.deactivate();
        	this.map.viewPortDiv.style.cursor="default";
        }
        
	    if(this.layers.length > 0) {
	        this.loadFeature();
	    }
	    else {
	        if(this.layersOtherWMS.length > 0) {
	           this.requestOtherWMS();
	        }
	    }                                   
    },
   
    
    /**
    * @private 
    * Method: loadFeature
    * Build and send the AJAX request 
    * to the WMS server.
    */
    loadFeature: function() {
        var uri = this.url;
        if (Roja.Proxy && this.url.startsWith("http")) {
            uri = Roja.Proxy + Roja.Util.escapeUri(this.url);
        }
        if ( !(this.url && this.layers && this.featureCount) ) {
            OpenLayers.Console.error("Some parameters are missing");
        }
        else {
            uri += '?REQUEST=GetFeatureInfo'
                + '&INFO_FORMAT=' + this.info_format
                + '&FORMAT=jpeg'
                + '&SRS=' + this.srs
                + '&VERSION=1.1.1'
                + '&HEIGHT=' + this.map.size.h
                + '&WIDTH=' + this.map.size.w
                + '&X=' + this.xy.x
                + '&Y=' + this.xy.y
                + '&BBOX=' + this.map.getExtent().toBBOX()
                + '&FEATURE_COUNT=' + this.featureCount
                + '&QUERY_LAYERS=' + this.layers.join(",")
                + '&STYLES=' 
                + '&LAYERS=' + this.layers.join(",");        
        
        		new OpenLayers.Ajax.Request(
			            uri, 
			            {   method: 'get', 
			                parameters: null,
			                onComplete: this.successLoadFeature.bind(this),
			                onFailure: this.errorLoadFeature.bind(this)
			            }
			        );
        }
        
    },
  
  	/**
    * @private 
    * Method: destroy
    * Eliminate circular references
	*/
    destroy: function () {

        /*if (this.map != null) {
        	
        	if (this.markersLayer != null) {
	            this.map.removeLayer(this.markersLayer, true);
		        this.markersLayer = null;
        	}
        }
        this.map = null;
        this.div = null;*/
        
        if (this.events) {
            this.events.destroy();
        }

        this.events = null;
        
        // destroy method of the superclass
		OpenLayers.Control.prototype.destroy.apply(this, arguments);
    },

    
    /**
    * @private
    * Method: successLoadFeature
    * This method is called when the WFS request 
    * is sent successfully.
    * Set the main div content with the xml received.
    * 
    * Parameters:
    * response
    */
    requestOtherWMS: function () {
      	var uri = this.urlOtherLayer;
        if (Roja.Proxy && this.urlOtherLayer.startsWith("http")) {
            uri = Roja.Proxy + Roja.Util.escapeUri(this.urlOtherLayer);
        }
        
        uri += '?REQUEST=GetFeatureInfo'
            + '&INFO_FORMAT=' + this.info_format
            + '&FORMAT=jpeg'
            + '&SRS=' + this.srs
            + '&VERSION=1.1.1'
            + '&HEIGHT=' + this.map.size.h
            + '&WIDTH=' + this.map.size.w
            + '&X=' + this.xy.x
            + '&Y=' + this.xy.y
            + '&BBOX=' + this.map.getExtent().toBBOX()
            + '&FEATURE_COUNT=' + this.featureCount
            + '&QUERY_LAYERS=' + this.layersOtherWMS.join(",")
            + '&STYLES=' 
            + '&LAYERS=' + this.layersOtherWMS.join(",");        
    
    		new OpenLayers.Ajax.Request(
		            uri, 
		            {   method: 'get', 
		                parameters: null,
		                onComplete: this.successLoadFeatureOtherWMS.bind(this),
		                onFailure: this.errorLoadFeature.bind(this)
		            }
		        );
        
     },
    
    /**
    * @private
    * Method: successLoadFeature
    * This method is called when the WFS request 
    * is sent successfully.
    * Set the main div content with the xml received.
    * 
    * Parameters:
    * response
    */
   
    successLoadFeature: function (request) {
      	var xml = request.responseText;
	    xml = this.replaceSpecialChars(xml);
	    var html = Roja.transformXml(xml,this.xsl);
		html=html.replace(/&lt;/g , "<");
		html=html.replace(/&gt;/g , ">");
		
		this.markersLayer.clearMarkers(); 	
		//Remove html page tags
		//	html=html.substring(html.indexOf('<body>'));
		//	html=html.substring(0,html.indexOf('</body>'));
      	var lonLat = this.map.getLonLatFromPixel(new OpenLayers.Pixel(this.xy.x,this.xy.y)); 
      	if(this.urlOtherLayer == null) {
      	   this.showMarker(lonLat,this.titleInfoBaloon+html);
      	   /*this.showMarker(lonLat,html);*/
      	    this.events.triggerEvent("loadComplete");
	 	    this.deactivate();
	 	    this.map.viewPortDiv.style.cursor="default";
      	}
      	else {
      	    this.htmlSITR = html;
      	    this.requestOtherWMS();
      	}
    	
     },
     
     /**
    * @private
    * Method: successLoadFeature
    * This method is called when the WFS request 
    * is sent successfully.
    * Set the main div content with the xml received.
    * 
    * Parameters:
    * response
    */
    successLoadFeatureOtherWMS: function (request) {
      	var xml = request.responseText;
	    xml = this.replaceSpecialChars(xml);
	    var html = Roja.transformXml(xml,this.xsl);
		html=html.replace(/&lt;/g , "<");
		html=html.replace(/&gt;/g , ">");
		
		this.markersLayer.clearMarkers(); 	
		//Remove html page tags
		//	html=html.substring(html.indexOf('<body>'));
		//	html=html.substring(0,html.indexOf('</body>'));
      	var lonLat = this.map.getLonLatFromPixel(new OpenLayers.Pixel(this.xy.x,this.xy.y)); 
      	
      	if(this.htmlSITR != null) {
  	        this.showMarker(lonLat,this.titleInfoBaloon+this.htmlSITR + html);
  	       /* this.showMarker(lonLat,this.htmlSITR + html );*/
      	}
      	else {
      	    this.showMarker(lonLat, this.titleInfoBaloon+html);
      	   /* this.showMarker(lonLat,html );*/
      	}
  	    this.events.triggerEvent("loadComplete");
 	    this.deactivate();
 	    this.map.viewPortDiv.style.cursor="default";
      	
    	
	 	//document.getElementsByClassName('olFramedCloudPopupContent').style.height='180'; 
        // 180 =  200-20
     },     
     
     
     
     
     
     
     
     /**
    * @private
    * Method: replaceSpecialChar
    * Remove special characters from a string
    * 
    * Parameters:
    * string {String}
    * 
    * Returns: {String}
    */   
    replaceSpecialChars: function(string){
    	var ret = string.replace('&','&amp;');
    	ret = ret.replace(/à/gi,'&agrave;');
    	ret = ret.replace(/è/gi,'&egrave;');
    	ret = ret.replace(/é/gi,'&eacute;');
    	ret = ret.replace(/ì/gi,'&igrave;');
    	ret = ret.replace(/ò/gi,'&ograve;');
    	ret = ret.replace(/ù/gi,'&ugrave;');
        return ret;
    },
     
     /**
    * Method: showMarker
    * create marker for object aci.
    * 
	* Parameters:
	* lonlat - {OpenLayers.LonLat}
	* text - {String}
	*/
	showMarker: function(lonlat,text) {
		
	
        AutoSizeFramedCloud = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {
            'autoSize': false/*,
            'fixedRelativePosition':true,
            'panMapIfOutOfView': false*/
            
        });        
      	
		popupClass = AutoSizeFramedCloud;
		popupContentHTML = text;
		
		var feature = new OpenLayers.Feature(this.markersLayer, lonlat); 
        feature.closeBox = true;
        feature.popupClass = popupClass;
        feature.data.popupContentHTML = popupContentHTML;
        feature.data.overflow = "auto";
        feature.data.popupSize = new OpenLayers.Size(400,200);
        
                       
        var offset = new OpenLayers.Pixel(-(this.iconSize.w/2), -this.iconSize.h);
	    var icon =  new OpenLayers.Icon(OpenLayers.ImgPath + this.iconUrl,this.iconSize,offset);
	    
	    icon.imageDiv.style.cursor='pointer';  

        feature.data.icon = icon;
        var marker = feature.createMarker();
        
        this.markersLayer.addMarker(marker);
              
        if (marker.popup == null) {
            marker.popup = feature.createPopup(feature.closeBox);
            this.map.addPopup(marker.popup);
        }
        marker.popup.show();
        
        stato=document.getElementById('toggle').value;
            	
        if (this.xy.x < 400 && stato=='close') 
        	this.map.pan(-100,0);
        else if (this.xy.x < 100 && stato=='open') 
        	this.map.pan(-100,0);
        	
        var markerClick = function (evt) {
                this.popup.toggle();
                OpenLayers.Event.stop(evt);
            };
        
        marker.events.register("click", feature, markerClick);    
        
        marker.events.register('dblclick', feature, this.stopevent);
    	marker.events.register('mousedown', feature, this.stopevent);
    		
//       this.panIntoView();
 	    
    },  
     
     
    
    /**
    * @private
    * Method: errorLoadFeature
    * Display a GetFeature loading error.
    * 
    * Parameters:
    * request
    */
    errorLoadFeature: function (request) { 
       
		//this.findResult = 'Errore nella chiamata wfs';
		this.events.triggerEvent("loadFailure");
		this.map.viewPortDiv.style.cursor="default";
   		return;
     },
    
       /**
    * Method: reset
	* Reset object to initial status
    */
    reset: function() {
        
        
        this.markersLayer.clearMarkers();       
        this.findResult = null;    
        if (this.diverrore!=null) {
		 	 	this.diverrore.style.display = 'none';
				this.spanerrore.innerHTML = '';	
		}    
		if (this.divDetail != null) {
				this.divDetail.style.display = 'none';
				this.divDetail.innerHTML = '';
		}	  
		this.htmlDetail = null;    
    },
    
    /**
     * Method: activate
     * Explicitly activates a control and it's associated
     * handler if one has been set.  Controls can be
     * deactivated by calling the deactivate() method.
     * 
     * Returns:
     * {Boolean}  True if the control was successfully activated or
     *            false if the control was already active.
     */
    activate: function () {
        if (this.active) {
        	/* in questo caso è GIA' ATTIVO
        	 * faccio in modo che un secondo click sull'icona dell'info
        	 * disattivi le sue funzionalità
        	 * INIZIO disattivazione*/
        	this.active=false;
        	this.handler.deactivate();
        	this.events.triggerEvent("deactivate");
        	this.events.triggerEvent("loadFailure");
 	    	this.deactivate();
 	    	this.map.viewPortDiv.style.cursor="default";
      		/* FINE disattivazione */
      		
            return false;
            
        }
        if (this.handler) {
            this.handler.activate();
        }
        this.active = true;
        if(this.map) {
            OpenLayers.Element.addClass(
                this.map.viewPortDiv,
                this.displayClass.replace(/ /g, "") + "Active"
            );
            this.map.viewPortDiv.style.cursor="help";
        }
        this.events.triggerEvent("activate");
        this.closeBaloon();
        return true;
    },
    
     /**
     * Method: closeBaloon
     * It closes the baloon on demand.
     * 
     */
    closeBaloon: function () {
    	if (this.markersLayer && this.markersLayer != null ){
        	this.markersLayer.clearMarkers();
    	}
    }, 
     
    
      
     /** @final @type String */
    CLASS_NAME: "InfoSardegnaMappe"
});





