var map;
var marker_recherche;   //marker placé en cas de recherche d'une adresse
var mgr;
var geocoder;
var loadMsg;
var adresse_pointclic;     //adresse du marker cliqué pour le passer en parametre de la page print_roadmap
var init_streetview = false;    //variable d'initialisation de streetview pour ne pas cacher les marker au premier lancement
var id_parametre;               //id de l'agence ou du relais passé en parametre et qui sera affiché
var mapping_code_place = new Array();		    //Permet de retrouver dans le tableau relaisColis un marker a l'aide de son code

var contentTo = [
                 '<br/><div>',
                     'Itin&#233;raire : <b>Vers ce lieu</b> - <a href="javascript:fromhere(0)">A partir de ce lieu</a><br/>',
                     'Lieu de d&#233;part<br/>',
                     '<input type="text" id="saisie" name="saisie" value="" maxlength="500" size="30">',
                     '<input type="hidden" id="mode" name="mode" value="toPoint">',
                     '<input type="hidden" id="point_choisi" name="point_choisi" value="">',
                     '<input type="submit" onclick="popup_roadmap();" value="Ok">',
                     '<br/>Ex: 58 avenue Leclerc 69007 Lyon',
                 '</div>'].join('');
     
var contentFrom = [
                  '<br/><div>',
                      'Itin&#233;raire : <a href="javascript:tohere(0)">Vers ce lieu</a> - <b>A partir de ce lieu</b><br/>',
                      'Lieu d\'arriv&#233;e<br/>',
                      '<input type="text" id="saisie" name="saisie" value="" maxlength="500" size="30">',
                      '<input type="hidden" id="mode" name="mode" value="fromPoint">',
                      '<input type="hidden" id="point_choisi" name="point_choisi" value="">',
                      '<input type="submit" onclick="popup_roadmap();" value="Ok">',
                      '<br/>Ex: 58 avenue Leclerc 69007 Lyon',
                  '</div>'].join('');
		
var infowindow;		
		
var agenceMarkers = [];
var relaisMarkers = [];
var reasons = [];

var iconAgence = new google.maps.MarkerImage(
	pathToImages + "/agenceTnt.png", 
	new google.maps.Size(50, 19), 
	new google.maps.Point(0, 0), 
	new google.maps.Point(25, 19))

var iconRelais = new google.maps.MarkerImage(
		pathToImages + "/relaisColis.png", 
		new google.maps.Size(40, 30), 
		new google.maps.Point(0, 0), 
		new google.maps.Point(20, 30))

var customIcons = [];
customIcons["ag"] = iconAgence;
customIcons["rc"] = iconRelais;

//Limites de la France
var allowedBounds = new google.maps.LatLngBounds(
		new google.maps.LatLng(39.56533418570851, -7.41426946590909), 
		new google.maps.LatLng(52.88994181429149, 11.84176746590909));

var defaultCenter = new google.maps.LatLng(46.2276380, 2.2137490); // the center ???
var defaultZoom = 5; 						// default zoom level
var aberration = 0.2; 						// this value is a good choice for france (?!)
var minMapScale = 5;
//var maxMapScale = 20;

var dtNow = new Date();
var aujourdhui = dtNow.getFullYear() * 10000 + (dtNow.getMonth() + 1) * 100 + dtNow.getDate();  

var modeAffichage = "TOUT";
var adresseSaise = "";

function getURLParam(name) {
	name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]" + name + "=([^&#]*)";
	var regex = new RegExp( regexS );
	var results = regex.exec( window.location.href );
	if( results == null ) return "";
	else return results[1];
};

function getDateStr(dateAS400) {
	if (dateAS400 != '')
		return dateAS400.substr(6, 2) + "/" + dateAS400.substr(4, 2) + "/" + dateAS400.substr(0, 4);
	else
		return '';
};

function formatMessage(message, append, args) {
	if (append != '')
		for (var i = 0; i < args.length; i++) {
			append = append.replace("\{" + i + "\}", args[i]);
		}
	if (message != '' && append != '') message = message + "<br/>";
	return message + append; 
};

function msgRelais(etat, premier, dernier, fermeture) {

	var message = "";

	var args = new Array();
	args[0] = getDateStr(fermeture);
	args[1] = getDateStr(premier);
	args[2] = getDateStr(dernier);
	
	// Transformation des dates "cha?nes" en entiers	
	if (premier == '') premier = 0;
	else premier = parseInt(premier);
	
	if (dernier == '') dernier = 0;
	else dernier = parseInt(dernier);
	
	if (fermeture == '') fermeture = 0;
	else fermeture = parseInt(fermeture);

	if (etat == 'S') {
		message = formatMessage(message, $("#msgInfoRelaisEtaS").html(), args);
	}
	else if ((etat == 'C') && (premier == 0) && (dernier == 0)) {
		message = formatMessage(message, $("#msgInfoRelaisEtaC").html(), args);
	}
	else {
		var indispo = false; 
		
		// ------------------------------------------
		// Indisponibilites
		if ((dernier != 0) && (premier != 0) && (dernier <= aujourdhui) && (premier >= aujourdhui)) {
			message = formatMessage(message, $("#msgInfoRelaisCas1").html(), args);
			indispo = true;
		}
		
		if ((dernier != 0) && (premier == 0) && (dernier > aujourdhui)) {
			message = formatMessage(message, $("#msgInfoRelaisCas3").html(), args);
			indispo = true;
		}
		
		if ((etat == 'R') && (premier == 0) && (dernier != 0) && (dernier < aujourdhui) &&	(fermeture != 0) && (fermeture < aujourdhui))
			message = formatMessage(message, $("#msgInfoRelaisCas3Bis").html(), args);
		
		// ------------------------------------------
		// Cas specifiques
		if ((premier != 0) && (dernier == 0) && (premier > aujourdhui))
			message = formatMessage(message, $("#msgInfoRelaisCas4").html(), args);

		// ------------------------------------------
		// Retrait des colis
 		if ((fermeture != 0) && (fermeture > aujourdhui))
			message = formatMessage(message, $("#msgInfoRelaisCas2").html(), args);

		// ------------------------------------------
		// Commande suite indisponibilite
		if (indispo && (etat != 'R'))
			message = formatMessage(message, $("#msgInfoRelaisCas5").html(), args);
	}	
		
	return message;
};

function createMarker(markerData) {

	var type = markerData[0];
	var code = markerData[5];
	var nom = markerData[3];
	var adresse = markerData[4];
	var point = new google.maps.LatLng(parseFloat(markerData[1]), 
							parseFloat(markerData[2]));

	var dataExt = new Array();
	if (type == "ag") {
		dataExt[0] = markerData[13];
	}
	else {
		dataExt = markerData[14].split("|");  // 3 dates
		dataExt[3] = markerData[13];
	}

	var horaires = new Array();
	horaires['lundi'] = markerData[6] + ",1";
	horaires['mardi'] = markerData[7] + ",2";
	horaires['mercredi'] = markerData[8] + ",3";
	horaires['jeudi'] = markerData[9] + ",4";
	horaires['vendredi'] = markerData[10] + ",5";
	horaires['samedi'] = markerData[11] + ",6";
	horaires['dimanche'] = markerData[12] + ",0";

	var marker = new google.maps.Marker({
		icon: customIcons[type],
		position: point,
		title:nom
	});
	
	google.maps.event.addListener(marker, "click", function() {
		openInfowindow(type, code, nom, adresse, dataExt, horaires, marker);
		if (marker_recherche) $("#saisie").val(marker_recherche.getTitle());
	});

	if (type == "ag")
		agenceMarkers.push(marker);
	else
		mapping_code_place[code] = relaisMarkers.push(marker) - 1;
	
	//////////////////////////////////////////////////////////////////////////////
	//   lien mail : zoom sur l'agence ou le relais colis et affiche la popup   //
	//////////////////////////////////////////////////////////////////////////////
	
	if (code == id_parametre && id_parametre != "") {
		map.setCenter(marker.getPosition());
		map.setZoom(11);

		openInfowindow(type, code, nom, adresse, dataExt, horaires, marker);
		id_parametre = "";
	}
	
};

function openInfowindow(type, code, nom, adresse, dataExt, horaires, marker) {
	
	// Création du contenu de l'onglet info
	var htmlInfo = "<div class='" + type + "'>";
	if(type == "ag") {
		htmlInfo = htmlInfo + "<b>" + nom + "</b>";
	}
	else {
		htmlInfo = htmlInfo + "<b>RELAIS COLIS N&#176; " + code + "</b><br/><b>" + nom + "</b>";
	}
	
	var tabAdr = adresse.split("|");
	for (var i = 0; i < tabAdr.length; i++)
		htmlInfo = htmlInfo + "<br/>" + tabAdr[i]; 
	htmlInfo = htmlInfo + "</div>";
	
	if (type == "ag") {
		htmlInfo = "<div>" + htmlInfo + "<div><br/>" 
				  + $("#msgInfoAgence").html() + " " + dataExt[0] + "</div></div>";
	}
	else {
		htmlInfo = "<div>" + htmlInfo + "<div><br/>" 
				  +  msgRelais(dataExt[3], dataExt[2], dataExt[0], dataExt[1]) 
				  +  "</div></div>";
	}
	
	htmlInfo = htmlInfo + "<div id='trajet'>" + contentTo + "</div>";
	
	//Création du contenu de l'onglet horaire
	var htmlHoraires = "<table class='horairesRC'>";
	var jourSemaine = (new Date()).getDay();
	for (jour in horaires) {
		var heures = (horaires[jour]).split(",");
		if (heures[0] == '' && heures[1] == '') heures[0] = "ferm&#233;";
		htmlHoraires = htmlHoraires  + "<tr" + (jourSemaine == parseInt(heures[2]) ? " class='selected'" : "") + "><td class='horairesRCJour'>&nbsp;" + jour + "</td><td>" + heures[0] + "</td><td>" + heures[1] + "</td></tr>";
	}
	htmlHoraires = htmlHoraires + "</table>";
	
	adresse_pointclic = adresse;

	var contentString = [
         '<div id="tabs" style="width:340px;">',
         '<ul>',
           '<li><a href="#tabInfos"><span>Infos</span></a></li>',
           '<li><a href="#tabHoraires"><span>Horaires</span></a></li>',
         '</ul>',
         '<div id="tabInfos">',
           htmlInfo,
         '</div>',
         '<div id="tabHoraires">',
           htmlHoraires,
         '</div>',
         '</div>'
       ].join('');

    if (infowindow) infowindow.close();
    infowindow = new google.maps.InfoWindow({content: contentString});
       
	google.maps.event.addListener(infowindow, "domready", function() {  
		$("#point_choisi").attr("value", adresse_pointclic);
		$("#tabs").tabs();
		$("#tabs").parent().removeAttr("style");
	});

    infowindow.open(map, marker);

}

function doAfterLoad() {

	// ====== Array for decoding the failure codes ======
	reasons[google.maps.GeocoderStatus.OK]            	= "Succ\u00e8s";
	reasons[google.maps.GeocoderStatus.INVALID_REQUEST] = "Adresse manquante: L'adresse est manquante ou n'a pas de valeur.";
	reasons[google.maps.GeocoderStatus.ZERO_RESULTS]    = "Adresse inconnue :  Aucune correspondance g\u00e9ographique n'a pas pu \u00eatre obtenue pour l'adresse sp\u00e9cifi\u00e9e.";
	reasons[google.maps.GeocoderStatus.REQUEST_DENIED]  = "Adresse indisponible:  Le g\u00e9ocodage de l'adresse fournie ne peut \u00eatre fourni pour des raisons l\u00e9gales ou contractuelles.";
	reasons[google.maps.GeocoderStatus.OVER_QUERY_LIMIT]= "Trop de requ\u00eate: Le quota journalier de demande de g\u00e9ocodage a \u00e9t\u00e9 d\u00e9pass\u00e9.";
	 			 		
	var myOptions = {
		zoom: defaultZoom,
		center: defaultCenter,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		navigationControl: true,
		scaleControl: true,
		mapTypeControl: true,
		streetViewControl: true
	};
	
	map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
	
	loadMsg = new OverlayMessage(document.getElementById("map_canvas"));      
	loadMsg.Set('<b>Chargement en cours...</b>');
	
    // If the map position is out of range, move it back
    function checkBounds() {

		// Perform the check and return if OK
		var currentBounds = map.getBounds();
		var cSpan = currentBounds.toSpan(); // width and height of the bounds
		var offsetX = cSpan.lng() / (2+aberration); // we need a little border
		var offsetY = cSpan.lat() / (2+aberration);
		var C = map.getCenter(); // current center coords
		var X = C.lng();
		var Y = C.lat();
	
		// now check if the current rectangle in the allowed area
		var checkSW = new google.maps.LatLng(C.lat()-offsetY,C.lng()-offsetX);
		var checkNE = new google.maps.LatLng(C.lat()+offsetY,C.lng()+offsetX);
	
		if (allowedBounds.contains(checkSW) &&
			allowedBounds.contains(checkNE)) {
			return; // nothing to do
		}
	
		var AmaxX = allowedBounds.getNorthEast().lng();
		var AmaxY = allowedBounds.getNorthEast().lat();
		var AminX = allowedBounds.getSouthWest().lng();
		var AminY = allowedBounds.getSouthWest().lat();
	
		if (X < (AminX+offsetX)) {X = AminX + offsetX;}
		if (X > (AmaxX-offsetX)) {X = AmaxX - offsetX;}
		if (Y < (AminY+offsetY)) {Y = AminY + offsetY;}
		if (Y > (AmaxY-offsetY)) {Y = AmaxY - offsetY;}
	
		map.setCenter(new google.maps.LatLng(Y,X));
		return;
    };
    
	google.maps.event.addListener(map, "drag", function() {
		checkBounds();
	});
	
	google.maps.event.addListener(map, "zoom_changed", function() {
		if (map.getZoom() < minMapScale) {
			map.setZoom(minMapScale);
		}
	});
	
	google.maps.event.addListener(map.getStreetView(), "visible_changed", function() {
		//premier accès lors du chargement de la page, il ne faut pas cacher les markers
		if(init_streetview == true){
			if(map.getStreetView().getVisible() == true) {
				mgr.hide();
				if(marker_recherche) marker_recherche.setVisible(false);
			}
			else {
				mgr.show();
				if(marker_recherche) marker_recherche.setVisible(true);
			}
		}
		else init_streetview = true;
	});

	var listener = google.maps.event.addListener(map, 'bounds_changed', function(){

		mgr = new MarkerManager(map);
		
		var listener2 = google.maps.event.addListener(mgr, 'loaded', function(){

			marker_recherche = new google.maps.Marker({
				position: defaultCenter,
				map: map,
				visible:false
			});
			
			id_parametre = getURLParam("xett");
			if(id_parametre == "") id_parametre = getURLParam("pex");
			
			// Chargement des marqueurs
		    $.ajax({
		        type: "GET",
		        url: "find.do",
		        dataType: "script"
		    });
		
			geocoder = new google.maps.Geocoder();
			checkBounds();
			
			google.maps.event.removeListener(listener2);
			
		});
		
		google.maps.event.removeListener(listener);
	});
};

function chargementAgenceRelais(Json){
	for (var i = 0; i < Json.length; i++) {
		createMarker(Json[i]);
	}
	loadMsg.Clear();
	refreshMarkers(true);
};

function refreshMarkers(isFinal) {
	mgr.clearMarkers();
	if (modeAffichage == "TOUT" || modeAffichage == "AGENCE") mgr.addMarkers(agenceMarkers, 6);
	if (modeAffichage == "TOUT" || modeAffichage == "RELAIS") mgr.addMarkers(relaisMarkers, 11);
	if (isFinal) mgr.refresh();
};

function onKeyPress(e) {
	var code;
	if ($.browser.mozilla) {
		code = e.charCode;
		if (code == 0) return true;
	}
	else code = e.keyCode;
	
	var bOk = (code == 13);  // Touche ENTREE
	if (!bOk) {
		// Liste des codes ASCII accept?s pour la saisie d'un code postal ou du nombre de colis
		bOk = ((code >= 48) && (code <= 57));
	}
	return bOk;
};

// ====== Plot a marker after positive reponse to "did you mean" ======
function place(lat, lng, adresse) {
	
	if (infowindow) infowindow.close();
	
	var point = new google.maps.LatLng(lat,lng);
	map.setZoom(13);
	map.setCenter(point);
	$("#message").html("");

	//suppression de l'ancien marqueur
	marker_recherche.setMap(null);
	
	// Indication du résultat de la recherche
	marker_recherche = new google.maps.Marker({
		position: point,
		map: map,
		title: adresse
	});
	
	//Si on veut afficher les agence, on ne s'occupe pas de la zone de chalandise
	if (modeAffichage == "TOUT" || modeAffichage == "RELAIS") {

		refreshMarkers(false);

		// Récupération de l'adresse pour la zone de chalandise
		var tmp_adr_decoup = adresse.split(',');

		// Récupération de l'avant dernier élément du tableau
		// => contient la commune, et éventuellement le code postal
		var adresse_decoupe = tmp_adr_decoup[tmp_adr_decoup.length - 2];
		
		adresse_decoupe = $.trim(adresse_decoupe);
		
		var codepostal = "";
		var commune = "";
		
		// Test si le premier caractère est numérique => indique la présence du code postal
		if (!isNaN(adresse_decoupe.charAt(0))) {
			codepostal = adresse_decoupe.split(' ')[0];
			commune = $.trim(adresse_decoupe.substr(5));
		}
		else {
			codepostal = "";
			commune = $.trim(adresse_decoupe);
		}
		
		var url = "findZoneChalandise.do?codePostal="+codepostal+"&commune="+commune+"";
		
		$.ajax({
	        type: "GET",
	        url: url,
	        dataType: "script"
	    });
	}
	else {
		refreshMarkers(true);
	}
};

function zoomZoneChalandise(zoneChalandise){
	
	if (zoneChalandise.length > 0) {
		
		var zoom_chalandise = new google.maps.LatLngBounds();
		var tab_relais_chalandise = new Array();
		
		for (i = 0; i < zoneChalandise.length; i++) {
			zoom_chalandise.extend(new google.maps.LatLng(zoneChalandise[i][0], zoneChalandise[i][1]));
			
			//suppression des marqueurs de la zone et rajout de ces derniers avec un zoom de 9
			var place_tab_relais = mapping_code_place[zoneChalandise[i][2]];
			mgr.removeMarker(relaisMarkers[place_tab_relais]);

			tab_relais_chalandise.push(relaisMarkers[place_tab_relais]);
		}
		
		zoom_chalandise.extend(marker_recherche.getPosition());
		map.setCenter(zoom_chalandise.getCenter());
		map.fitBounds(zoom_chalandise);
		var zoom_calcule = map.getZoom();
		mgr.addMarkers(tab_relais_chalandise, (zoom_calcule < 11) ? zoom_calcule : 11);
		mgr.refresh();
	}
	else {
		mgr.refresh();
	}
};

function displayMap() {
	
	if (geocoder) {

		map.getStreetView().setVisible(false);
		
		modeAffichage = $("#modeAffichage option:selected").val();
		var adresse = $("#adresse").val();
		
		var queryFull;
		if (adresse != "") queryFull = adresse + ", France, FR";
		else {
			map.setCenter(defaultCenter, defaultZoom);
			refreshMarkers(true);
			return;
		}
		
		geocoder.geocode({ 
				address: queryFull,
				region: 'fr'
			}, function(results, status) {
    	  
			if (status == google.maps.GeocoderStatus.OK) {
      		
			// ===== If there was more than one result, "ask did you mean" on them all =====
			if (results.length > 1) { 
				$("#message").html("Plusieurs r&#233;ponses possibles :");
				// Loop through the results
				for (var i=0; i<results.length; i++) {
					var p = results[i].geometry.location;
					$("#message").append("<br>"+(i+1)+": <a href='javascript:place(" +p.lat()+","+p.lng()+",\""+ results[i].formatted_address+"\")'>"+ results[i].formatted_address+"<\/a>");
				}
			}
			// ===== If there was a single marker =====
			else {
				$("#message").html("");
				place(results[0].geometry.location.lat(),results[0].geometry.location.lng(), results[0].formatted_address);
			}
      	} 
      	// ====== Decode the error status ======
      	else {
			var reason = "Code " + status;
			if (reasons[status]) {
				reason = reasons[status]
			} 
			alert('Impossible de localiser "' + adresse + '" ' + reason);
      	}
      });
		
	}
};

function fromhere() {
	var adresse_saisie = $("#saisie").val();
	$("#trajet").html(contentFrom);
	$("#point_choisi").attr('value', adresse_pointclic);
	$("#saisie").val(adresse_saisie);
};

function tohere() {
	var adresse_saisie = $("#saisie").val();
	$("#trajet").html(contentTo);
	$("#point_choisi").attr('value', adresse_pointclic);
	$("#saisie").val(adresse_saisie);
};

function popup_roadmap() {
	if ($("#saisie").val() == "") return;
	window.open("/public/geolocalisation/print_roadmap.do?mode="+ $("#mode").val() +"&point_choisi="+ $("#point_choisi").val() +"&saisie="+ $("#saisie").val());
};
