/* Js pour le frontend essentiellement, notamment IGN */

/**
 * Permet de faire un lien qui ouvre la popup de détail d'une entité
 * @param url Url de la page de détail
 * @return
 */
function linkToDetailEntite(url) {
	window.open(url,"Annuaire",'width=990,height=600,status=0,toolbar=0,location=0,menubar=0,resizable=1,directories=0,scrollbars=1');
	return false;
}

/******************************************************/
/* IGN */
/******************************************************/
//Paramètres généraux
function initIGNParameters(adresse, ville, longitude, latitude) {
	ign_adresse = (adresse ? adresse : '');
	ign_ville = (ville ? ville : '');
	ign_longitude = (longitude ? longitude : '');
	ign_latitude = (latitude ? latitude : '');
}

function initPositionModeOption()
{
  formOptions= {
    containerId:'GeoportalVisuDiv',            // obligatoire
    lonId:'entite_longitude_entite',               // obligatoire
    latId:'entite_latitude_entite',               // obligatoire
    //waitImage:wimg,                     // facultatif.
    projection:'IGNF:RGF93G',           // facultatif. Defaut : 'IGNF:RGF93G'
    precision:100000,                   // facultatif. Defaut: 1000000
    marker:'/images/target.gif',                        // facultatif
    scale:14                            // facultatif (5 a 20). Defaut: 14
  };
}

/**
 * Fonction de mise à jour de la carte par rapport aux données du formulaire
 * 
 * @author Joachim Martin
 * @date 2010-09-17
 * @param 
 *
 **/
function updateFeature (elt, val) {
    var vlayer= VISU.getMap().getLayersByName(VIEWEROPTIONS.vectorLayerName)[0];
    var feature= vlayer.features[0];
    var gpForm= VISU.getVariable('gpForm');
    var x= gpForm.getX();
    var y= gpForm.getY();
    if (!isNaN(x) && !isNaN(y)) {
        // Supprimer l'ancien point
        vlayer.destroyFeatures();
        // transfo geo -> coord geop
        var geometry= new OpenLayers.Geometry.Point(x,y);
        geometry.transform(gpForm.getNativeProjection(), VISU.getMap().getProjection());

        // Ajouter l'objet
        feature= new OpenLayers.Feature.Vector(geometry);
        feature.state= OpenLayers.State.INSERT;
        vlayer.addFeatures(feature);

        // Si on n'a pas d'arguments à la fonction , on utilise l'échelle par défaut
        if (arguments.length == 0)
        {
          VISU.getMap().setCenterAtLonLat(x, y,formOptions.scale);
        }
        else
        {
          // Centrer sur le point - on garde la même échelle que l'échelle courante
          VISU.getMap().setCenterAtLonLat(x, y);
        }
    }
    // Initialiser
    updateXYForm(feature);

    return true;
}

/**
 * Fonction de mise à jour du formulaire sur le déplacement du marqueur
 * 
 * @author Joachim Martin
 * @date 2010-09-15
 * @param 
 *
 **/
function updateXYForm (feature, pix) {
    if (!feature || !feature.geometry  || !feature.geometry.x || !feature.geometry.y) {
        return;
    }
    var gpForm= VISU.getVariable('gpForm');
    var pt= feature.geometry.clone();
    pt.transform(VISU.getMap().getProjection(), gpForm.getNativeProjection());
    // Affichage dans l'élément
    var invp= gpForm.getPrecision();
    gpForm.setX(Math.round(pt.x*invp)/invp);
    gpForm.setY(Math.round(pt.y*invp)/invp);
    delete pt;
}

/**
 * Initialise le graphique de positionnement
 * 
 * @author Joachim Martin
 * @date 2010-09-15
 * @param int ign_longitude : Longitude du point
 * @param int ign_latitude : Latitude du point
 *
 **/
function setPositionPoint(ign_longitude, ign_latitude)
{
    var styles= null;

    var gpForm= new Geoportal.GeoXYForm(formOptions);

    // Définition des coordonées
    gpForm.setX(ign_longitude);
    gpForm.setY(ign_latitude);

    VISU.addVariable('gpForm',gpForm);
    styles= new OpenLayers.StyleMap({
      'default': OpenLayers.Util.extend(
        OpenLayers.Feature.Vector['default'],{
            externalGraphic: gpForm.marker,
            pointRadius: 10,
            fillOpacity: 1
      })
    });

        // Affichage des couches
        for (var i= 0, len= VISU.getMap().getNumLayers(); i<len; i++) {
            var lyr= VISU.getMap().layers[i];
            if (!lyr.isBaseLayer) {
                if (VIEWEROPTIONS.layerOptions.hasOwnProperty(lyr.name)) {
                    var o= VIEWEROPTIONS.layerOptions[lyr.name];
                    if (o.opacity!==undefined) {
                        lyr.setOpacity(o.opacity);
                    }
                    if (o.visibility!==undefined) {
                        lyr.setVisibility(o.visibility);
                    }
                }
            }
        }
    // Couche vecteur pour la saisie
    var vlayer= new OpenLayers.Layer.Vector(
      VIEWEROPTIONS.vectorLayerName,
      {
          projection: gpForm.vectorLayerName,
          displayInLayerSwitcher:false,
          calculateInRange: function() { return true; },
          styleMap: styles
      }
    );
    VISU.getMap().addLayer(vlayer);
    
    if((hidePanels != 'undefined') && hidePanels) {
	    VISU.openLayersPanel(false);
	    VISU.openToolsPanel(false);
    }

    if (positionMode)
    {
    // Controle pour le deplacement
      var drag_feature= new OpenLayers.Control.DragFeature(
                                  vlayer,
                                  {
                                      onDrag : updateXYForm,
                                      onComplete : updateXYForm
                                  }
      );
      VISU.getMap().addControl(drag_feature);
      drag_feature.activate();

      // Controle pour la saisie
      var draw_feature= new OpenLayers.Control();
      OpenLayers.Util.extend(draw_feature, {
          draw: function (px) {
              this.div= OpenLayers.Control.prototype.draw.apply(this,arguments);
              // Ajoute un Handler.Point qui intercepte l'evenement ctrl+mousedown
              if (this.handler==null) {
                  this.handler= new OpenLayers.Handler.Point(
                      draw_feature,
                      {
                          done: function (pt) {
                              // Supprimer l'ancien point
                              vlayer.destroyFeatures();
                              // Creer le nouveau point
                              var feature= new OpenLayers.Feature.Vector(pt);
                              feature.state= OpenLayers.State.INSERT;
                              vlayer.addFeatures(feature);
                              updateXYForm(feature);
                          }
                      },
                      {
                          persist: false,//true pour tester le Cntrl-Clic
                          layerOptions: {
                              projection: gpForm.vectorProjection
                          },
                          keyMask: OpenLayers.Handler.MOD_CTRL
                      });
              }
              return this.div;//null
          }
      });
      VISU.getMap().addControl(draw_feature);
      draw_feature.activate();

      // Ajouter un observateur sur les donnees du formulaire
      OpenLayers.Event.observe(gpForm.getXInput(),"change",updateFeature);
      OpenLayers.Event.observe(gpForm.getYInput(),"change",updateFeature);

    }

    // A conserver cazr provoque l'afffichage du point dans tous les modes
    updateFeature();
}

function setDefaultCenter() {
	VISU.getMap().setCenterAtLonLat(2.608428, 46.5, 5);
}

/*function addPositionLayer(point, lon, lat) {
	// Ajout de la couche du picto de position
	var vector_layer = new OpenLayers.Layer.Vector('Position'); 
	
	// Ajout de la couche à la carte
	VISU.getMap().addLayer(vector_layer);

	var finalLon = '';
	var finalLat = '';

	var stylepoi = {externalGraphic:'/images/target.gif',	graphicWidth:20, graphicHeight:20 };

	// On a directement le point (car de recherche par adresse)
	if(point) {		
		var mon_poi = new OpenLayers.Feature.Vector(point, null, stylepoi);

		// On transforme le point pour récupérer ses coordonnées GPS (longitude et latitude)
		point2 = point.clone();
		point2.transform(VISU.getMap().getProjection(), OpenLayers.Projection.CRS84);		

		finalLon = point2.x;
		finalLat = point2.y;
	}

	// On a déjà la longitude et la latitude
	if(lon && lat) {
		var mon_point = new OpenLayers.Geometry.Point(lon, lat);
		var mon_poi = new OpenLayers.Feature.Vector(mon_point, null, stylepoi);
 
		// Passage en projection Géoportail
		mon_point.transform(OpenLayers.Projection.CRS84, VISU.getMap().getProjection());

		finalLon = lon;
		finalLat = lat;
	}

	if(mon_poi && finalLon && finalLat) {
		// Ajout du POI à la couche créée et affichage de la couche
		vector_layer.addFeatures([mon_poi]);
	
		// on centre la map sur ce point avec le bon zoom
		VISU.getMap().setCenterAtLonLat(finalLon, finalLat, 14);
	}
	else {
		setDefaultCenter();
	}

	// Ajout de l’info bulle 
	
	//var popup = new OpenLayers.Popup('id', 
	//				new OpenLayers.LonLat(point2.x, point2.y), 
	//				new OpenLayers.Size(200,50), 
	//				 '<b>Commune de Souillac</b><br/>5 Avenue de Sarlat<br/>46200 Souillac', 
	//				 true
	);

	// Affiche la popup
	VISU.getMap().addPopup(popup, true);

}*/

function addPositionLayer(point, lon, lat) {
	// Ajout de la couche du picto de position
	//var vector_layer = new OpenLayers.Layer.Vector('Position'); 
	
	// Ajout de la couche à la carte
	//VISU.getMap().addLayer(vector_layer);

	var finalLon = '';
	var finalLat = '';

	//var stylepoi = {externalGraphic:'/images/target.gif',	graphicWidth:20, graphicHeight:20 };

	// On a directement le point (car de recherche par adresse)
	if(point) {		
		//var mon_poi = new OpenLayers.Feature.Vector(point, null, stylepoi);

		// On transforme le point pour récupérer ses coordonnées GPS (longitude et latitude)
		point2 = point.clone();
		point2.transform(VISU.getMap().getProjection(), OpenLayers.Projection.CRS84);		

		finalLon = point2.x;
		finalLat = point2.y;

	}

	// On a déjà la longitude et la latitude
	if(lon && lat) {
		//var mon_point = new OpenLayers.Geometry.Point(lon, lat);
		//var mon_poi = new OpenLayers.Feature.Vector(mon_point, null, stylepoi);
 
		// Passage en projection Géoportail
		//mon_point.transform(OpenLayers.Projection.CRS84, VISU.getMap().getProjection());

		finalLon = lon;
		finalLat = lat;
	}

	//if(mon_poi && finalLon && finalLat) {
	if(finalLon && finalLat) {
		// Ajout du POI à la couche créée et affichage de la couche
		//vector_layer.addFeatures([mon_poi]);
    setPositionPoint(finalLon,finalLat);
	
		// on centre la map sur ce point avec le bon zoom
		//VISU.getMap().setCenterAtLonLat(finalLon, finalLat, 14);
	}
	else {
		setDefaultCenter();
	}

	// Ajout de l’info bulle 
	/*
	var popup = new OpenLayers.Popup('id', 
					new OpenLayers.LonLat(point2.x, point2.y), 
					new OpenLayers.Size(200,50), 
					 '<b>Commune de Souillac</b><br/>5 Avenue de Sarlat<br/>46200 Souillac', 
					 true
	);

	// Affiche la popup
	VISU.getMap().addPopup(popup, true);
	*/
}
function searchByAddress() {
	// Ajout du layer de recherche par adresse
	var gcOptions = {	name: 'ADDRESSES.CROSSINGS:OPENLS',
		formatOptions: {
			version:'1.0'
		}
	}
	gcLayer = new Geoportal.Layer.OpenLS.Core.LocationUtilityService('ADDRESSES.CROSSINGS:OPENLS', gcOptions);

	VISU.getMap().addLayer(gcLayer);

	// Construction de l'adresse OLS
	var a = new Geoportal.OLS.Address('FR');
	var s = new Geoportal.OLS.Street();
	s.name= OpenLayers.String.trim(ign_adresse);
	var sa = new Geoportal.OLS.StreetAddress();
	sa.addStreet(s);
	a.streetAddress = sa;
	var p = new Geoportal.OLS.Place({
		'classification':'Municipality',
		'name': OpenLayers.String.trim(ign_ville)
	});
	a.addPlace(p);
	//a.postalCode= new Geoportal.OLS.PostalCode({'name':'86000'});

	// Envoi de la requête au serveur OpenLS	
	gcLayer.GEOCODE(
		[a],
		{
			onSuccess: ignOnSuccess,
			onFailure: ignOnFailure,
			scopeOn: window
		}
	);

	// Ne pas mettre ce destroy
	//a.destroy();
	//a= null;
}

function ignOnSuccess(request){
	Geoportal.Layer.OpenLS.prototype.success.apply(gcLayer,arguments);
	if (!gcLayer.ols) {
		return;
	}
	
	ok = false;

	// we have one query => one body
	var b= gcLayer.ols.getBodies()[0];
	if (b) {
		var rp= b.getResponseParameters();

		if (rp || (rp.getNbGeocodeResponseList() == 1)) {
			var grl= rp.getGeocodeResponseList()[0];
			if (grl || (grl.getNbGeocodedAddresses() == 1)) {
				var first = grl.getGeocodedAddresses()[0]

        // Au moins une adresse de trouvée
			  if (typeof(first) != 'undefined')
        {
          var point = first.lonlat;

          // Ajout du layer
          addPositionLayer(point, null, null);
				}
        // Non, on affiche le point par défaut
        else
        {
          setDefaultCenter();
        }
				ok = true;
			}
		}
	}
	
	if(!ok) {
		setDefaultCenter();
	}

	gcLayer.ols.destroy();
	gcLayer.ols= null;
};

function ignOnFailure(){
	alert("L'adresse demandé n'a pas pu être localisée.");
	setDefaultCenter();
};

function initGeoportalMap() {
  OpenLayers.Lang.setCode('fr'); // ensure French
  OpenLayers.Console.log('initialisation');
	//geoportalLoadVISU("GeoportalVisuDiv", "normal");
	geoportalLoadVISU("GeoportalVisuDiv");
        VIEWEROPTIONS= {
            mode: 'normal',
            territory: 'FXX',
            projection: 'IGNF:GEOPORTALFXX',
            displayProjection: ['IGNF:RGF93G', 'IGNF:LAMB93', 'IGNF:LAMBE'],
            layerSwitcher: 'mini',  // on, off, mini
            toolboxCtrl: 'off',      // on, off, mini
            infoPanel: true,        // true, false
            vectorLayerName: 'POINT_XY',
            layerOptions: {
                'GEOGRAPHICALGRIDSYSTEMS.MAPS' : {
                    opacity : 1
                },
                'ORTHOIMAGERY.ORTHOPHOTOS'     : {
                    visibility : true
                },
                global                         : {
                    transitionEffect : 'resize'
                }
            }
        };
	
	if (VISU) {
		/*****************************************************************/
		/* Généralités */
		/*****************************************************************/
		// La taille de la map
	    if (!positionMode && !boShowMode)
	    {
	      VISU.setSize(900,630);
	    }
	    else
	    {
	      VISU.setSize(660,630);
	    }
	
		// Obligatoire : le proxy
		VISU.getMap().setProxyUrl('/proxy/proxy.pl?url=');
	
		// Définit la langue à utiliser
			//VISU.getMap().setLocale("fr");
	
			// Maque lepanneau de contrôle des layers
			//VISU.setLayersPanelVisibility(false);
		//VISU.setInformationPanelVisibility(false);
	
		/*
		for (var i= 0; i<VISU.getMap().controls.length;i++) {
			var control= VISU.getMap().controls[i];
			if (control.CLASS_NAME == 'Geoportal.Control.Projections') {
			control.deactivate();
		}
		}
		*/
	
		// Centre la carte
			//VISU.getMap().setCenterAtLonLat("1° 28' 43 E","44° 53' 38 N",14);
		//VISU.getMap().setCenterAtLonLat(1.4787345, 44.8940390, 14);
	
		
		/*****************************************************************/
		/* Affichage du point */
		/*****************************************************************/
		addPositionLonLatLayer = false;
		if(ign_longitude && ign_latitude) {
			// On a déjà les coordonnées
			//addPositionLayer(null, ign_longitude, ign_latitude);
			
			// On doit le mettre en dernier pour qu'il s'affiche en premier
			addPositionLonLatLayer = true;
		}
		else if(ign_adresse && ign_ville) {
			// Recherche par adresse
			searchByAddress();
		}
		else {
			// Cas de secours
			// on centre la map sur la France avec le bon zoom
			setDefaultCenter();
		}


		// Mettre le controleur de recherche par adresse	
		/*
			var tbx= VISU.getMap().getControlsByClass('Geoportal.Control.ToolBox')[0];
		
			// add "Search Toolbar" :
			var searchbar= new Geoportal.Control.SearchToolbar(
				{
					div: OpenLayers.Util.getElement(tbx.id+'_search'),
					geocodeOptions: {
						layerOptions: {
							name: 'ADDRESSES.CROSSINGS:OPENLS',
							formatOptions: {
								version:'1.0'
							}
						}
					}
				}
			);
			VISU.getMap().addControl(searchbar);
		*/

		/*****************************************************************/
		/* Couches */
		/*****************************************************************/
		// On les ajoute dans l'ordre inverse d'affichage
		// Carte vue du ciel
		overloaded_options = { name: 'Vue du ciel', visibility: false };
		VISU.addGeoportalLayer('ORTHOIMAGERY.ORTHOPHOTOS:WMSC',overloaded_options);
	
		// Cartes standard IGN
		overloaded_options2 = { opacity: 1.0 };
		VISU.addGeoportalLayer('GEOGRAPHICALGRIDSYSTEMS.MAPS:WMSC',overloaded_options2);
		
        /**
         * Class: GeoXYForm
         * La classe de geoformulaire de saisie de (X,Y).
         */
        Geoportal.GeoXYForm = OpenLayers.Class({

            /**
             * APIProperty: containerId
             * {String} Identifiant du container HTML auquel sera ajouté la
             *      visualisation Géoportail.
             */
            containerId: null,

            /**
             * APIProperty: buttonId
             * {String} identifiant du container HTML activant/désactivant la
             *      visualisation Géoportail.
             */
            buttonId: null,

            /**
             * APIProperty: imgButton
             * {String} image associée au container HTML.
             */
            imgButton: null,

            /**
             * APIProperty: lonId
             * {String} identifiant du champ HTML contenant l'abscisse/longitude.
             */
            lonId: null,

            /**
             * APIProperty: latId
             * {String} identifiant du champ HTML contenant l'ordonnée/latitude.
             */
            latId: null,

            /**
             * APIProperty: vectorProjection
             * {String} nom de la projection associée aux coordonnées. Par défaut,
             * 'IGNF:RGF93G'.
             */
            vectorProjection: 'IGNF:RGF93G',

            /**
             * APIProperty: precision
             * {Number} 10**nombre de chiffres significatifs. Par défaut, 1000000 (30
             *      cm de précision en géographique).
             */
            precision: 1000000,

            /**
             * APIProperty: marker
             * {String} chemin d'accès à l'image figurant les coordonnées. Par défaut,
             *      aucune image.
             */
            marker: null,

            /**
             * Property: container
             * {DOMElement}
             */
            container: null,

            /**
             * Property: button
             * {DOMElement}
             */
            button: null,

            /**
             * Property: Lon
             * {DOMElement}
             */
            Lon: null,

            /**
             * Property: Lat
             * {DOMElement}
             */
            Lat: null,

            /**
             * Constructor: Geoportal.GeoXYForm
             * Définit un formulaire HTML lié à la visualisation Géoportail au travers
             * de la saisie d'un paire de coordonnées.
             *
             * Parameters:
             * options - {Object} les options du formulaire.
             *      Elles sont nombreuses :
             * - containerId
             * - buttonId
             * - imgButton
             * - lonId
             * - latId
             * - vectorProjection
             * - precision
             * - marker
             * - scale
             */
            initialize : function(options) {
                OpenLayers.Util.extend(this, options);

                if (typeof(this.vectorProjection)=='string') {
                    this.vectorProjection= new OpenLayers.Projection(this.vectorProjection);
                }
                this.container= parent.document.getElementById(this.containerId);
                this.button= parent.document.getElementById(this.buttonId);
                this.Lon= parent.document.getElementById(this.lonId);
                this.Lat= parent.document.getElementById(this.latId);
            },

            /**
             * APIMethod: getXInput
             * Returns the coordinates input field associated with abscissa or
             * longitude.
             *
             * Returns:
             * {DOMElement}
             */
            getXInput : function() {
                return this.Lon;
            },

            /**
             * APIMethod: getYInput
             * Returns the coordinates input field associated with ordinate or
             * latitude.
             *
             * Returns:
             * {DOMElement}
             */
            getYInput : function() {
                return this.Lat;
            },

            /**
             * APIMethod: getX
             * Returns the coordinates input field value associated with abscissa or
             * longitude.
             *
             * Returns:
             * {Number}
             */
            getX : function() {
                if (this.Lon) {
                    return parseFloat(this.Lon.value);
                }
                return NaN;
            },

            /**
             * APIMethod: getY
             * Returns the coordinates input field value associated with ordinate or
             * latitude.
             *
             * Returns:
             * {Number}
             */
            getY : function() {
                if (this.Lat) {
                    return parseFloat(this.Lat.value);
                }
                return NaN;
            },

            /**
             * APIMethod: setX
             * Assigns the coordinates input field value associated with abscissa or
             * longitude.
             *
             * Parameters:
             * x - {Number}
             */
            setX : function(x) {
                if (this.Lon && !isNaN(parseFloat(x))) {
                    this.Lon.value= x;
                }
            },

            /**
             * APIMethod: setY
             * Assigns the coordinates input field value associated with ordinate or
             * latitude.
             *
             * Parameters:
             * y - {Number}
             */
            setY : function(y) {
                if (this.Lat && !isNaN(parseFloat(y))) {
                    this.Lat.value= y;
                }
            },

            /**
             * APIMethod: getPrecision
             * Returns the 10**number of figures
             *
             * Returns:
             * {Number}
             */
            getPrecision : function() {
                return this.precision? this.precision : 1000000;
            },

            /**
             * APIMethod: getNativeProjection
             * Returns the projection of the vector layer
             *
             * Returns:
             * {<OpenLayers.Projection>}
             */
            getNativeProjection : function() {
                return this.vectorProjection;
            },

            /**
             * Constant: CLASS_NAME
             * {String} *"Geoportal.GeoXYForm"*
             */
            CLASS_NAME: 'Geoportal.GeoXYForm'
        });
		// Ajout du layer que maintenant si c'est par lonlat
		if(addPositionLonLatLayer) {
			  addPositionLayer(null, ign_longitude, ign_latitude);
		}
	}
}

