//Cette fonction utilise les JS :
//<script type="text/javascript" src="/base/js/me3/mapME.js"></script>
//<script type="text/javascript" src="/base/js/me3/minMax.js"></script>

(function(){
	var WIN=this,
		ev=WIN.ev;
	function Gmap(noeud) {
		this.noeud=noeud;
		// adresse des icones hotel, PI, pays, aéroport, ....
		var HOTEL_CENTRAL = "http://cdn.easyvoyage.com/imgs/icons/iconsGMap/markerH_Rouge.png", // icone hotel
			HOTEL = "http://cdn.easyvoyage.com/imgs/icons/iconsGMap/markerH.gif", // icone hotel
			HOTEL_CATEGORY = "http://cdn.easyvoyage.com/imgs/meddle/meh/hub/p-map-", // icone hotel de category
			VILLE = "http://cdn.easyvoyage.com/imgs/icons/iconsGMap/markerCV.png", // icone centre ville
			PAYS  = "http://cdn.easyvoyage.com/imgs/icons/iconsGMap/marker_Poi.png", // icone pays
			AIRPO = "http://img.easyvoyage.com/atom/mev/hub/avion_google_map.png", // icone aeroport
			AIRPO_CENTRAL = "http://cdn.easyvoyage.com/imgs/icons/iconsGMap/markerAvion.png", // icone aeroport
			POINT = "http://cdn.easyvoyage.com/imgs/icons/iconsGMap/markerPoi.png", // icone point d'interet
			METNEXT = WIN.path.cdn+"/imgs/icons/iconsGMap/MetNext.png", // icone MetNext
		// taille des icones pour qu'il apparaisse bien sur la google map
			HOTEL_CENTRAL_SIZE = new WIN.GSize(20, 39),
			HOTEL_SIZE = new WIN.GSize(20, 34),
			HOTEL_CATEGORY_SIZE = new WIN.GSize(20, 34),
			VILLE_SIZE = new WIN.GSize(20, 34),
			PAYS_SIZE = new WIN.GSize(20, 34),
			AIRPO_CENTRAL_SIZE = new WIN.GSize(23, 35),
			AIRPO_SIZE = new WIN.GSize(32, 34),
			POINT_SIZE = new WIN.GSize(20, 34),
			METNEXT_SIZE = new WIN.GSize(21, 21),
			icon;
		/**
		 * attribut correspondant a la google map
		 */
		this.googleMap=null;

		this.mapStreet=null;

		/**
		 * liste contenant les marqueurs pour affichage sur googlemap
		 * Utiliser pour zoomer: visualiser tous les marker sur la gmap
		 */
		this.markersList = [];

		/**
		 * fonction permettant d'initialiser la google map
		 */
		this.mapLoad = function() {
			if (typeof(WIN.GBrowserIsCompatible) !== "undefined" && WIN.GBrowserIsCompatible() && ev.dom.element(this.noeud) !== null)
			{
				 this.googleMap = new WIN.GMap2(ev.dom.element(this.noeud));
				 this.googleMap.setUIToDefault();
				 var point = new WIN.GLatLng(0, 0);
				 this.googleMap.setCenter(point, 12);
			}
			else
			{ //Si le navigateur n'est pas compatible avec l'API de Google Maps ...
				if(typeof(WIN.log)==="function"){WIN.log('Desole, mais votre navigateur n\'est pas compatible avec Google Maps', 'warn');}
			}
		};

		/**
		 * fct permettant d'ajouter un point sur la google map
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} icone : url de l'icone
		 * @param {Object} titre : titre de l'info bulle
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 */
		this.addMarker = function(id, lat, lgt, icone, titre, texte, iconSize) {
			if(!this.googleMap) {
				return;
			}
			if(lat==="Infinity" || lgt==="Infinity") {
				return;
			}
			icon = new WIN.GIcon(WIN.G_DEFAULT_ICON, icone);
			icon.shadow = "";
			icon.iconSize = iconSize;
			icon.iconAnchor = new WIN.GPoint(10, 29);
			icon.infoWindowAnchor = new WIN.GPoint(10, 10);
			var point = new WIN.GLatLng(lat, lgt, 10),
				marker = new WIN.GMarker(point, {icon:icon, title:titre});
			marker.bindInfoWindowHtml(texte);
			this.markersList[id] = marker;
			this.googleMap.addOverlay(marker);
		};

		/**
		 * fct permettant de supprimer un point de la google map
		 */
		this.removeMarkerById = function(id) {
			if(this.markersList[id]) {
				this.googleMap.removeOverlay(this.markersList[id]);
			}
		};

		/**
		 * fct permettant de recrée un point supprimé précédement sur la google map en utilisant le markerList
		 */
		this.addMarkerById = function(id) {
			if(this.markersList[id]) {
				this.googleMap.addOverlay(this.markersList[id]);
			}
		};


		/**
		 * fct permettant d'ajouter un point correspondant a l'hotel principale
		 * sur la google map (celui dont la page traite)
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomHotel : nom de l'hotel
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 *
		 *
		 */
		this.addHotelCentral = function(id, lat, lgt, nomHotel, texte) {
			this.addMarker(id, lat, lgt, HOTEL_CENTRAL, nomHotel, texte, HOTEL_CENTRAL_SIZE);
		};


		/**
		 * fct permettant d'ajouter un point correspondant a un hotel sur la google map
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomHotel : nom de l'hotel
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 *
		 *
		 */
		this.addHotel = function(id, lat, lgt, nomHotel, texte) {
			this.addMarker(id, lat, lgt, HOTEL, nomHotel, texte, HOTEL_SIZE);
		};

		/**
		 * fct permettant d'ajouter un point correspondant a un hotel sur la google map.
		 * La categorie de l'hotel permet de demarquer le point sur la google map.
		 * @param {Object} indexHotel : index de l'hotel par rapport aux autre hotels
		 * @param {Object} idHotel : id de l' hotel
		 * @param {Object} idCategory : id de la category de l'hotel
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomHotel : nom de l'hotel
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 *
		 *
		 */
		this.addHotelCategory = function(indexHotel, idHotel, idCategory, lat, lgt, nomHotel, texte){
			var iconHotel;
			switch(idCategory){
			case '1'://famille
				iconHotel = HOTEL_CATEGORY+"r0"+indexHotel+'.png';
				break;
			case '2'://charme
				iconHotel = HOTEL_CATEGORY+"b0"+indexHotel+'.png';
				break;
			case '3'://design
				iconHotel = HOTEL_CATEGORY+"v0"+indexHotel+'.png';
				break;
			case '4':// premier prix
				iconHotel = HOTEL_CATEGORY+"j0"+indexHotel+'.png';
				break;
			}
			this.addMarker(idHotel, lat, lgt, iconHotel, nomHotel, texte, HOTEL_CATEGORY_SIZE);
		};

		/**
		 * fct permettant d'ajouter un point correspondant a une ville sur la google map
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomVille : nom de la ville
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 */
		this.addVille= function(id, lat, lgt, nomVille, texte) {
			this.addMarker(id, lat, lgt, VILLE, nomVille, texte, VILLE_SIZE);
		};

		/**
		 * fct permettant d'ajouter un point correspondant a un pays sur la google map
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomPays : nom du pays
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 */
		this.addPays = function(id, lat, lgt, nomPays, texte) {
			this.addMarker(id, lat, lgt, PAYS, nomPays, texte, PAYS_SIZE);
		};

		/**
		 * fct permettant d'ajouter un point correspondant a un aeroport sur la google map
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomAeroport : nom de l'aeroport
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 */
		this.addAeroportCentral = function(id, lat, lgt, nomAeroport, texte) {
			this.addMarker(id, lat, lgt, AIRPO_CENTRAL, nomAeroport, texte, AIRPO_CENTRAL_SIZE);
		};

		/**
		 * fct permettant d'ajouter un point correspondant a un aeroport sur la google map
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomAeroport : nom de l'aeroport
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 */
		this.addAeroport = function(id, lat, lgt, nomAeroport, texte) {
			this.addMarker(id, lat, lgt, AIRPO, nomAeroport, texte, AIRPO_SIZE);
		};

		/**
		 * fct permettant d'ajouter un point correspondant a un point d'interet sur la google map
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomPI : nom du point d interet
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 */
		this.addPI = function(id, lat, lgt, cat, nomPI, texte) {
			if (cat === 1){this.addAeroport(id, lat, lgt, nomPI, texte);}else if (cat === -1){this.addAeroportCentral(id, lat, lgt, nomPI, texte);} else {this.addMarker(id, lat, lgt, POINT, nomPI, texte, POINT_SIZE);}
		};

		/**
		 * fct permettant d'ajouter un point correspondant a un lieu référencé par MetNext sur la google map
		 * @param {Object} lat : latitude
		 * @param {Object} lgt : longitude
		 * @param {Object} nomLieu : nom du lieu
		 * @param {Object} texte : texte a mettre dans la bulle au format HTML
		 *
		 *
		 */
		this.addLieuMetNext = function(id, lat, lgt, nomLieu, texte) {
			this.addMarker(id, lat, lgt, METNEXT, nomLieu, texte, METNEXT_SIZE);
		};

		/**
		 * permet de choisir la taille d'un zoom centré sur un point définit par sa latitude et sa longitude.
		 */
		this.setZoom= function(lat, lgt, zoom) {
			if(!this.googleMap) {
		        return null;
	        }
			var point = new WIN.GLatLng(lat, lgt, 10);
			this.googleMap.setCenter(point, zoom);
		};


		/**
		 *
		 * @param lat : latitude du marqueur
		 * @param lng : longitude du marqueur
		 */
		this.zoomOn = function(id) {
			// Si la google map n'a pas ete initialise, on sort
			if(!this.googleMap) {
				return null;
			}
			if (typeof(this.markersList[id]) !== "undefined")
			{
				var marker = this.markersList[id];
				//recentre la carte sur l'hotel selectionne
				this.googleMap.setCenter(marker.getPoint(),12);
				//permet d'ouvrir l'info bulle
				WIN.GEvent.trigger(marker, "click");
			}
		};


		/**
		 * "surcharge de la fonction removeOverlay de google
		 * @param {Object} marker
		 */
		this.removeMarker = function(marker) {
			// Si la google map n'a pas ete initialise, on sort
			if(!this.googleMap) {
		        return null;
	        }

			return this.googleMap.removeOverlay(marker);
		};


		/**
		 * ci-dessous les focntions permettant de calculer le centre et le zoom de la google map
		 */

		/**
		 * Cette fonction permet de calculer les latitudes min et max des points listes
		 * un tableau (variable globale) de marqueurs : markersList stockees dans une structure MinMax.
		 * Dans le cas ou cette variable ne contiendrait aucun point, la fonction retourne les latitudes -90 a 90.
		 */
		this.getLatMinMax = function() {
			var i, latMin=90, latMax=-90;
			if(this.markersList.length===0){// Si markersList est vide
				return new WIN.MinMax(-90.0,90.0);
			}
			// toute valeur de latitude (par definition inferieure a 90) diminuera latMin
			for (i=0; i< this.markersList.length; i++){
				if (this.markersList[i].getLatLng().lat()<latMin) {
					latMin=parseFloat(this.markersList[i].getLatLng().lat());
				}
			}
			// Meme principe pour latMax que pour latMin
			for (i=0; i< this.markersList.length; i++){
				if (this.markersList[i].getLatLng().lat()>latMax) {
					latMax=parseFloat(this.markersList[i].getLatLng().lat());
				}
			}
			// Si le tableau markersList etait vide latMin=90, latMax=-90, et la moyenne vaut bien zero.
			return new WIN.MinMax(latMin,latMax);
		};

		this.triNum =  function(a,b) {
			return a-b;
		};


		/**
		 * Cette fonction permet de calculer les longitudes min et max des points listes
		 * un tableau (varible globale) de marqueurs : markersList. Dans le cas ou cette variable ne
		 * contiendrait aucun point, la fonction retourne les latitudes -180 a 180.
		 */
		this.getLngMinMax = function() {
			if(this.markersList.length===0){
				return new WIN.MinMax(-180,180);
			}
			if(this.markersList.length===1){
				return new WIN.MinMax(this.markersList[0].getLatLng().lng(),this.markersList[0].getLatLng().lng());
			}
			var i=0, lngSortedArray=[], indexDeltaMax=0, deltaMax, lngMin, delta, lngMax;
			for (i=0; i< this.markersList.length; i++){
				lngSortedArray.push(parseFloat(this.markersList[i].getLatLng().lng()));
			}
			lngSortedArray.sort(this.triNum);
			// On va chercher l'index du delta maximal, i.e. le point dont lelongation angulaire est
			// maximale avec son predecesseur.
			deltaMax=lngSortedArray[0]-lngSortedArray[lngSortedArray.length-1]+360;
			for(i=1; i<lngSortedArray.length; i++){
				delta=lngSortedArray[i]-lngSortedArray[i-1];
				if(delta>deltaMax){
					deltaMax=delta;
					indexDeltaMax=i;
				}
			}
			lngMin=lngSortedArray[indexDeltaMax];
			if(indexDeltaMax!==0){
				lngMax=lngSortedArray[indexDeltaMax-1];
			}
			else{
				lngMax=lngSortedArray[lngSortedArray.length-1];
			}
			if(lngMin>lngMax){
				lngMax+=360;
			}
			return new WIN.MinMax(lngMin,lngMax);
		};

		/**
		 * Cette fonction permet de definir le zoom optimal en fonction de l'ecart des
		 * longitudes maximums et minimums
		 * @param {Object} lngMinMax
		 */
		this.getZoomX =  function(lngMinMax,widthMarker) {
			//var width=ev.dom.element(this.noeud).clientWidth;
			var width=ev.dom.element(this.noeud).clientWidth-(widthMarker*2);
			return Math.log(width*180/40.93/lngMinMax.getDelta()/Math.PI)/Math.LN2;
		};

		/**
		 * Cette fonction permet de definir le zoom optimal en fonction de l'ecart des
		 * latitudes maximums et minimums
		 * @param {Object} latMinMax
		 */
		this.getZoomY =  function(latMinMax,heightMarker) {
			//var height=(ev.dom.element(this.noeud).clientHeight);
			var height=(ev.dom.element(this.noeud).clientHeight)-heightMarker;
			return Math.log(height*180*Math.cos(latMinMax.getMean()*Math.PI/180)/40.93/latMinMax.getDelta()/Math.PI)/Math.LN2;
		};

		/**
		 * Cette fonction definit le niveau de zoom en prenant la plus petite valeur entre
		 * les zooms optimals des longitudes et latitudes
		 * @param {Object} lngMinMax
		 * @param {Object} latMinMax
		 */
		this.getZoom = function(lngMinMax,latMinMax) {
			//dimensions du marqueur (en pixel)
			var widthMarker=26, heightMarker=34,
				Zx=this.getZoomX(lngMinMax,widthMarker),
				Zy=this.getZoomY(latMinMax,heightMarker);
			return Math.floor(Math.min(Zx,Zy));
		};

		/**
		 * Cette fonction calcule le centre et le zoom de la carte
		 * apres que tous les markers ont ete places
		 */
		this.zoomToFit = function(){
			// Si la google map n'a pas ete initialisee, on sort
			if(!this.googleMap) {
				return;
			}
			var latMinMax=this.getLatMinMax(),
				lngMinMax=this.getLngMinMax(),
				zoom;
			if (!isNaN(latMinMax.getMean()) && !isNaN(lngMinMax.getMean())){
				zoom = this.getZoom(lngMinMax,latMinMax);
				if(zoom === Infinity){zoom = 11;}
				this.googleMap.setCenter(new WIN.GLatLng(latMinMax.getMean(),lngMinMax.getMean()),zoom);
			}
		};

		/**
		 * "surcharge" de la fonction setCenter de google
		 * @param {Object} Lat
		 * @param {Object} Long
		 * @param {Object} zoom
		 */
		this.updateCenter = function(lat,lng, zoom){
			// Si la google map n'a pas ete initialisee, on sort
			if(!this.googleMap) {
		        return;
	        }

			var gLatLng = new WIN.GLatLng(lat,lng);
			this.googleMap.setCenter(gLatLng, zoom);
		};

		/**
		 * Fonction permettant de cacluler la distance entre deux points dont les
		 * coordonnees sont passees en parametres en utilisant l'API Google
		 * @param {Object} lat1
		 * @param {Object} lgt1
		 * @param {Object} lat2
		 * @param {Object} lgt2
		 */
		this.calculDistance = function(lat1, lng1, lat2, lng2){
			return WIN.CalculDistance().compute(lat1, lng1, lat2, lng2);
		};


		/**
		 * permet de dessiner un cercle sur la gmap
		 * @param {Object} centre
		 * @param {Object} rayon : Rayon du cercle en kilometre(s)
		 * @param {Object} cercleCouleur : Couleur du cercle
		 * @param {Object} cercleEpaisseur : Epaisseur du trait tracant le cercle (en pixel)
		 * @param {Object} cercleOpacite : Opacitï¿½ du trait tracant le cercle (de 0 ï¿½ 1)
		 * @param {Object} disqueCouleur : Couleur du disque
		 * @param {Object} disqueOpacite : Opacitï¿½ du disque (de 0 ï¿½ 1)
		 */
		//var cercleHotel = new WIN.GLatLng(${hotel.latitude},${hotel.longitude});
		this.drawCircle = function(lat, lng, rayon, cercleCouleur, cercleEpaisseur, cercleOpacite, disqueCouleur, disqueOpacite  ){
			// Si la google map n'a pas ete initialise, on sort
			if(!this.googleMap) {
				return;
			}

			//Nombre de segments composant le cercle
			var segment = 60, points = [], i, point, cercle,
				centreCercle = new WIN.GLatLng(lat, lng),
				latConv = centreCercle.distanceFrom(new WIN.GLatLng(parseFloat(lat)+0.1, parseFloat(lng)))/100,
				lngConv = centreCercle.distanceFrom(new WIN.GLatLng(parseFloat(lat), parseFloat(lng)+0.1))/100,
				step = parseInt(360/segment,10)||10;
			for(i=0; i<=360; i+=step){
				point = new WIN.GLatLng(parseFloat(lat) + (rayon/latConv * Math.cos(i * Math.PI/180)), parseFloat(lng) + (rayon/lngConv * Math.sin(i * Math.PI/180)));
				points.push(point);
			}
			cercle = new WIN.GPolygon(points, cercleCouleur, cercleEpaisseur, cercleOpacite, disqueCouleur, disqueOpacite);

			this.googleMap.addOverlay(cercle);
		};
	}

	function poiSlide(nbPOI,idPOI){
		var menuPOI, blockMenuPOI,
		//On définit la max-height en fonction du nombre de POI contenu
		hauteurPOI=13,//en px
		hauteurUL=nbPOI*hauteurPOI + 10;//on rajoute une marge basse de 10px
		// Defines the block's DOM element.
		blockMenuPOI=ev.dom.element(idPOI);
		blockMenuPOI.style.maxHeight=hauteurUL+"px";
		// Defines the slider affected to the block, it will open/close in 250ms.
		menuPOI=new WIN.SliderESV(blockMenuPOI,250,false);
		// Hack for safari & opera
		if(WIN.genericNavigator.navigator.id===WIN.SAFARI||WIN.genericNavigator.navigator.id===WIN.OPERA){
			menuPOI.setMaxWidth(330);
		}
		return menuPOI;
	}
	WIN.poiSlide=poiSlide;
	WIN.Gmap=Gmap;

} ());
