/**
 * Définition des variables 
 */
var bglib = {};
bglib.google = {};
bglib.google.gservletUrl = "http://afpa.business-geografic.com/afpa";
bglib.google.geocoder = {};
bglib.google.processingData = {};
bglib.google.mapsApiLoadedCallBack = {};
bglib.google.key = null;

bglib.google.ctrFMap = {};
bglib.google.infoWindowCtrF = null;
bglib.google.bounds = null;
bglib.google.zonesArray = [];
bglib.google.curReg = "";
bglib.google.curDep = "";
bglib.google.regions = "afpa.regions";
bglib.google.departements = "afpa.departements";
bglib.google.ctrf = "afpa.centreformation";

/**
 * Fonction d'entrée pour le chargement de la carte
 * Affiche une carte dans un container de type "DIV" dont la valeur de l'identifiant est passée en paramètre.
 * Cette carte situe les centres de formation en fonction de l'emprise courante.
 * @param {String} i_IdNodeContainer : identifiant du node contenant la carte
 */
bglib.google.loadMapFrance = function loadMapFrance(idMapContainer){
	var data = {};
	data.container = idMapContainer;

	this.processingData = data;
	bglib.google.mapsApiLoadedCallBack = this.callBackLoadMapFrance;

	this.initLoader();
};

/**
 * Initialise le chargement des apis google (jsApi, gmaps)
 */
bglib.google.initLoader = function initLoader(){
		
	 bg.utils.communication.initProperties(null, bglib.google.gservletUrl);
	
	 this.communication = bg.utils.Jsonp.getInstance();
	 
	 this.getApiKey(function(key) {
	   // chargement de la feuille de style par défaut
       var cssLink = document.createElement('link');
       cssLink.setAttribute('rel', 'stylesheet');
       cssLink.setAttribute('type', 'text/css');
       cssLink.setAttribute('media', 'all');
       cssLink.setAttribute('href',
             bg.utils.communication.properties.siteurl + '/resources/css/default.css');
       document.getElementsByTagName('head')[0].appendChild(cssLink);
      
       var script = document.createElement('script');
       bglib.google.key = key.key;
       if (/key/.test(bglib.google.key)) {
         script.src = 'http://www.google.com/jsapi?' + bglib.google.key + '&callback=bglib.google.loadMapsApi';
       } else {
         script.src = 'http://www.google.com/jsapi?callback=bglib.google.loadMapsApi';
       }
       script.type = 'text/javascript';
       document.getElementsByTagName('head')[0].appendChild(script);
     });
};

/**
 * Renvoi la clé google maps en fonction du domaine de l'url
 * @param callback
 */
bglib.google.getApiKey = function getApiKey(callback){

	this.communication.request('GetGoogleKey', {
	    f: bg.utils.communication.properties.domain
	  }, callback);
};

/**
 * Charge l'api Google Maps v3
 */
bglib.google.loadMapsApi = function loadMapsApi(){
	google.load("maps", "3.2", {"callback" : this.mapsLoaded, "language" : "fr", "other_params" : bglib.google.key + "&sensor=false"});
};

/**
 * Lance la callback après avoir chargée l'api Google Maps v3
 */
bglib.google.mapsLoaded = function mapsLoaded(){  
	bglib.google.mapsApiLoadedCallBack();
};


/**
 * Affiche une carte centrée sur la France.
 * Cette carte situe les centres de formation en fonction de l'emprise courante.
 */
bglib.google.callBackLoadMapFrance = function callBackLoadMapFrance(){
	
	var data = bglib.google.processingData;
	var divMap = document.getElementById(data.container);
	divMap.style.display = "block";

	this.gmap = bglib.google.createMap(divMap, true);
	
	var SWLatLng = new google.maps.LatLng(42.220381 , -6.097412);
	var NELatLng = new google.maps.LatLng(51.227527 , 9.283447);
	var bounds = new google.maps.LatLngBounds(SWLatLng, NELatLng);
	this.gmap.fitBounds(bounds);

	bglib.google.bounds = bounds;
	
	google.maps.event.addListener(this.gmap, "idle", function() {
		bglib.google.bounds = this.getBounds();
		bglib.google.updateMarkers();
	});
	
	google.maps.event.addListener(this.gmap, "click", function(event) {
		bglib.google.getZoneExtent(event.latLng);
	});
	
	// info bulle centre formation
	this.infoWindowCtrF = new google.maps.InfoWindow({
		content: ""
	});
	
	this.refreshLayerTMSMap();
	this.getFirstExtent();
};

/**
 * Créer une carte dans un conteneur
 * @param (Element) divMap
 * @param (Boolean) controls
 * @returns {google.maps.Map}
 */
bglib.google.createMap = function createMap(divMap, controls){
    var myOptions = {
    	navigationControl: controls,
    	scaleControl: controls,
    	mapTypeControl: controls,
    	streetViewControl: false,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(divMap, myOptions);
   	return map;
};

/**
 * Centre la carte sur la région ou département passé en paramètre
 */
bglib.google.getFirstExtent = function getFirstExtent(){
	
	curReg = this.getUrlParameter("reg");
	curDep = this.getUrlParameter("dep");

	filter = "";
	layer = "";
	
	if(curDep != ""){
		layer = bglib.google.departements;
		filter = "(DEPART:\"" + curDep + "\")";
	
	}else if(curReg != ""){
		layer = bglib.google.regions;
		filter = "(CODE_REG:\"" + curReg + "\")";
	}
	
	if(curReg != ""){
				
		this.communication.externalRequest(bglib.google.gservletUrl + '/zones', {
			r: "search",
			t: layer,
			p: filter
		  }, bglib.google.zoomToExtent);
	}
};

/**
 * affiche les départements sur la carte
 */
bglib.google.refreshLayerTMSMap = function refreshLayerTMSMap(){
	
	var overlayIndexDep = bglib.google.getOverlayIndex("map_departements");		
	
	if(overlayIndexDep == null){
		bglib.google.addMapOverlay("map_departements");
	}
};

/**
 * renvoie l'index de l'overlay passé en paramètre
 * @overlayName (String)
 * @returns (int)
 */
bglib.google.getOverlayIndex = function getOverlayIndex(overlayName){
	var i = null;
	bglib.google.gmap.overlayMapTypes.forEach(
		function(element, index){
			if(element.name == overlayName){
				i = index;
			}
		}
	);
	return i;
};

/**
 * ajoute un overlay à la carte
 * @param overlayName (String)
 */
bglib.google.addMapOverlay = function addMapOverlay(overlayName){
	var zonesMapOptions = {
			name: overlayName,
			getTileUrl: function(coord, zoom) {
				var tileUrl = "";
				if(curReg != ""){
					tileUrl = bglib.google.gservletUrl + "/kml/afpazones/" + overlayName + "/" + zoom + "/" + coord.x + "/" + coord.y + ".png?p=(CODE_REG%3A%22" + curReg + "%22)";
				}else{
					tileUrl = bglib.google.gservletUrl + "/kml/afpazones/" + overlayName + "/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
				}
				return tileUrl;
		    },
		    tileSize: new google.maps.Size(256, 256),
		    isPng: true
	};
	var zonesMapType = new google.maps.ImageMapType(zonesMapOptions);
	bglib.google.gmap.overlayMapTypes.insertAt(0, zonesMapType);
};

/**
 * Supprime un overlay de la carte
 * @param index (int)
 */
bglib.google.removeMapOverlay = function removeMapOverlay(index){
	bglib.google.gmap.overlayMapTypes.removeAt(index);
};


/**
 * Supprime les marqueurs de la carte
 */
bglib.google.clearMapMarkers = function clearMapMarkers(){
	bglib.google.clearCtrF();
};

/**
 * Supprime les marqueurs centres de formation de la carte, vide les centres de formation
 */
bglib.google.clearCtrF = function clearCtrF() {
	if(this.ctrFMap) {
		for(var i in this.ctrFMap) {
			this.ctrFMap[i].setMap(null);
		}
	}	
	this.ctrFMap = {};
};

/**
 * Récupère les centres de formation situés dans l'emprise courante
 */
bglib.google.updateMarkers = function updateMarkers(){
	
	curReg = this.getUrlParameter("reg");
	curDep = this.getUrlParameter("dep");

	filter = "";
	layer = "";
	
	if(curDep != ""){
		layer = bglib.google.departements;
		filter = "(id_departement:\"" + curDep + "\")";
	
	}else if(curReg != ""){
		layer = bglib.google.regions;
		filter = "(code_region:\"" + curReg + "\")";
	}
	
	// récupère les centres de formation
	var zoomLevel = this.gmap.getZoom();	
	var boundingBox = '' +  bglib.google.bounds.getSouthWest().lng() + ',' + bglib.google.bounds.getSouthWest().lat() + ',' + bglib.google.bounds.getNorthEast().lng() + ',' + bglib.google.bounds.getNorthEast().lat();

	if(filter!=""){
		this.communication.request('placemark', {
		    t: "afpa.centreformation",
		    zl: zoomLevel,
		    bb: boundingBox,
		    gf: 0.2,
		    p: filter
		  }, bglib.google.placeMarkers);
		
	}else {
		this.communication.request('placemark', {
		    t: "afpa.centreformation",
		    zl: zoomLevel,
		    bb: boundingBox,
		    gf: 0.2
		  }, bglib.google.placeMarkers);
	}
};

/**
 * Parse les informations des centres de formation pour la création des marqueurs
 * @param (Object) data
 */
bglib.google.placeMarkers = function placeMarkers(data){
	// clean ctrF markers
	bglib.google.clearCtrF();
	
	var ctrFs = data["afpa.centreformation"];
	
	for(var i in ctrFs){
		var obj = {};
		var ctrF = ctrFs[i];

		if(!ctrF.cluster){ //ctrF
			obj.isCluster = false;
			obj.point = new google.maps.LatLng(ctrF["latitude"], ctrF["longitude"]);
			obj.info = bglib.google.buildCtrFInfoHTML([ctrF]);
			obj.id = ctrF.code_etablissement;
			 
		}else{ //cluster
			obj.isCluster = true;
			obj.point = new google.maps.LatLng(ctrF["center"]["y"], ctrF["center"]["x"]);
			
			SWLatLng = new google.maps.LatLng(ctrF["extent"]["miny"], ctrF["extent"]["minx"]);
			NELatLng = new google.maps.LatLng(ctrF["extent"]["maxy"], ctrF["extent"]["maxx"]);
			obj.boundingBox = new google.maps.LatLngBounds(SWLatLng, NELatLng);
			if(ctrF["info"] != null){
				obj.info = bglib.google.buildCtrFInfoHTML(ctrF["info"]);
			}
			obj.latMin = ctrF["extent"]["miny"];
			obj.latMax = ctrF["extent"]["maxy"];
			obj.lngMin = ctrF["extent"]["minx"];
			obj.lngMax = ctrF["extent"]["maxx"];
			obj.size = ctrF["size"];
			obj.id = ctrF["center"]["y"] + " " + ctrF["center"]["x"];
		}
		
		var marker = bglib.google.createMarker(obj);
		bglib.google.ctrFMap[obj["id"]] = marker;
		bglib.google.ctrFMap[obj["id"]].setMap(bglib.google.gmap);
	}
};

/**
 * Construit l'infobulle des centres de formation
 * @param (Object) ctrFs
 * @returns (String)
 */
bglib.google.buildCtrFInfoHTML = function buildCtrFInfoHTML(ctrFs){
	
	html = "<div id=\"divInfoWindowCtrF\">";
	
	for(var id in ctrFs){
		
		var ctrF = ctrFs[id];
		
		if(id>0){
			html += "<hr class=\"lineSeparator\" />";
		}
		
		html += "<span class=\"ctrFName\"><b>AFPA " + ctrF.nom + "</b></span><br/>";
	
		var addr = ctrF.adresse + " " + "<br/>" + ctrF.cp + " " + ctrF.ville;
	   	
		html += "<span class=\"infoAddr\">" + addr + "</span><br/>";
		
		if( ctrF.tel && ctrF.tel != ""){
			html += "<span class=\"infoValue\">Tél. : " + ctrF.tel + "</span><br/>";
		}
		if( ctrF.fax && ctrF.fax != ""){
			html += "<span class=\"infoValue\">Fax : " + ctrF.fax + "</span><br/>";
		}
		
		url = window.location.href;		
		if(url.indexOf("?") > 0){
			url = url.substr(0, url.indexOf("?"));
		}
		
		curReg = this.getUrlParameter("reg");
		
		html += "<span class=\"linkCtrFPage\"><br/><a href=\"" + url + "?reg=" + curReg + "&dep=" + ctrF.id_departement + "&ctr=" + ctrF.nom + "&etab=" + ctrF.code_etablissement + "#liste\">Plus d'informations</a></span><br/>";
	}
	
	html += "</div>";
	
	return html;
};

/**
 * Créer un marqueur ou cluster centre de formation
 * @param {Object} object
 * @returns (google.maps.Marker)
 */
bglib.google.createMarker = function createMarker(object){
		
	var imgURL = "";
	var imageSize;
	var imageAnchor;
	if(object.isCluster){
		imgURL = bglib.google.gservletUrl + "/IconServlet?iu= " + bglib.google.gservletUrl + "/resources/icons/afpa.png&it=" + object.size + "&fs=16";
		imageSize = new google.maps.Size(28, 28);
		imageAnchor = new google.maps.Point(14, 14);
	}else{
		imgURL = bglib.google.gservletUrl + "/resources/icons/afpa.png";
		imageSize = new google.maps.Size(22, 22);
		imageAnchor = new google.maps.Point(11, 11);
	}
	var markerIcon = new google.maps.MarkerImage(imgURL, imageSize, new google.maps.Point(0, 0), imageAnchor);
			
	var marker = new google.maps.Marker({
		position: object.point,
		icon: markerIcon
	});
	
    marker.marker = object;
    
    if(!object.isCluster || (object.isCluster && object.info!=null)){
		google.maps.event.addListener(marker, "click", function(){
			bglib.google.infoWindowCtrF.setContent(object.info);
			bglib.google.infoWindowCtrF.open(bglib.google.gmap, marker);
		});
		
	}else{
		google.maps.event.addListener(marker, "click", function(){
			bglib.google.gmap.fitBounds(object.boundingBox);
		});
	}
	return marker;
};

/**
 * Récupère l'emprise du département cliqué et se centre dessus
 * @param ptLatLng
 */
bglib.google.getZoneExtent = function getZoneExtent(ptLatLng){
	if(ptLatLng == null){
		return;
	}
	
	this.communication.externalRequest(bglib.google.gservletUrl + '/zones', {
		r: "search",
		t: "afpa.departements",
		sp: "(WithinDistance:" + ptLatLng.lng() + "," + ptLatLng.lat() + "[distance:0,srid:4326])"
	  }, bglib.google.zoomToExtent);
};

/**
 * Zoom à une emprise donnée
 * @param result
 */
bglib.google.zoomToExtent = function zoomToExtent(result){

	var zone = null;
	
	if(result[bglib.google.regions] != null){
	  zone = result[bglib.google.regions][0];
	}else if(result[bglib.google.departements] != null){
		zone = result[bglib.google.departements][0];
	}
		
	if(zone){
		extentArray = zone["Extent"].split(" - ");
		minx = extentArray[0].split(":")[1];
		miny = extentArray[1].split(":")[1];
		maxx = extentArray[2].split(":")[1];
		maxy = extentArray[3].split(":")[1];
	
		SWLatLng = new google.maps.LatLng(miny, minx);
		NELatLng = new google.maps.LatLng(maxy, maxx);
	
		bglib.google.gmap.fitBounds(new google.maps.LatLngBounds(SWLatLng, NELatLng));
	}
};

/**
 * Déchargement de la page
 */
bglib.google.unload = function unload(){
	bglib.google.processingData = {};
	bglib.google.mapsApiLoadedCallBack = {};
	bglib.google.ctrFMap = {};
	GUnload();
};

/**
 * Masque le conteneur de la carte
 */
bglib.google.hideMap = function hideMap(){  
	var divMap = document.getElementById(this.processingData.container);
	divMap.style.display = "none";
	divMap.innerHTML = "";
};

/**
 * Affiche le conteneur de la carte
 */
bglib.google.showMap = function showMap(){  
	var divMap = document.getElementById(this.processingData.container);
	divMap.style.display = "block";
};

/**
 * Renvoi la valeur d'un paramètre de l'url
 * @param paramName
 * @returns (String)
 */
bglib.google.getUrlParameter = function getUrlParameter( paramName ){
	paramName = paramName.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]"+paramName+"=([^&#]*)";
	var regex = new RegExp( regexS );
	var results = regex.exec( window.location.href );
	if( results == null )
		return "";
	else
		return results[1];
};

