/**
* Page		: itineraires.js
* Contenu	: Code javascript lié aux itinéraires
* Date		: 24/08/10
* @author	Gael Sauvanet
* @version	1.0
*/

var solution_actuelle = -1;		// Itinéraire sélectionn
var nb_sols = 0;			// Nombre d'itinéraires
var layerItineraires = [];		// Tableau des couches contenant les itinéraires
var layerGares = 0;		// Tableau des couches contenant les itinéraires
var typeRequete = 1;
var geometriesItineraires;

/**
 * Chargement de l'itineraire suite au calcul
 */
function onLoadItineraire(r)
{
	if(dynamic)controlDrag.activate();
	supprimerItineraires();
	
	if(typeof(r["error"]) != "undefined")
	{
		if(r["error"] == "No geographical point 1 ")
			messageModal("Point de départ placé en dehors de la zone de couverture");
		else if(r["error"] == "No geographical point 2 ")
			messageModal("Point d'arrivée placé en dehors de la zone de couverture");
		else if(r["error"] == "No geographical point E")
			messageModal("Point étape placé en dehors de la zone de couverture");
		else 
			alert("Erreur non identifiée ("+r["error"]+")");
		
		restaurer(ancienItineraire);
		return;
	}

	ancienItineraire = sauver();
	
	linestringstyle2 = [];
	distance = [];

	var p = new OpenLayers.Format.GeoJSON();
	var f = p.read(r,'FeatureCollection');
	geometriesItineraires = f;

	if(f != null)
	{
		var best = 0;
		var numitineraire = 0;
		var nbSol= f[f.length-1].attributes.itinerary;
		if (chargement && chargement>nbSol) chargement=0;

		if(dynamic)
		{
			for (var i=0; i<f.length; i++)
			{
				var obj = f[i];
				var feature = obj.geometry;
				feature.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
				feature.attributes = obj.attributes;
				if(feature.attributes.itinerary != numitineraire)
				{
					numitineraire = feature.attributes.itinerary;
					layerItineraires[numitineraire] = new OpenLayers.Layer.Vector("itineraire"+numitineraire);
					layerItineraires[numitineraire].displayInLayerSwitcher = false;
					distance[numitineraire] = feature.attributes.distance;
		
					// Si l'itinéraire vient de la BDD, on affiche le choix sauvegardé, sinon on affiche le meilleur compromis
					if((feature.attributes.best == "true" && !chargement) || feature.attributes.itinerary == chargement)
					{
						map.addLayer(layerItineraires[numitineraire]);
						best = numitineraire;
						
						linestringstyle2[numitineraire] = [];
						linestringstyle2[numitineraire][0] = OpenLayers.Util.extend({}, linestringstyle[0]);
						linestringstyle2[numitineraire][1] = OpenLayers.Util.extend({}, linestringstyle[1]);
						linestringstyle2[numitineraire][3] = OpenLayers.Util.extend({}, linestringstyle[3]);
					}
					else
					{
						linestringstyle2[numitineraire] = [];
						linestringstyle2[numitineraire][0] = OpenLayers.Util.extend({}, linestringstylepetit[0]);
						linestringstyle2[numitineraire][1] = OpenLayers.Util.extend({}, linestringstylepetit[1]);
						linestringstyle2[numitineraire][3] = OpenLayers.Util.extend({}, linestringstylepetit[3]);
					}
				}

				if((feature.attributes.category > 7 && feature.attributes.category < 10) || (feature.attributes.category < 1)) feature.attributes.category = 6;

				itineraire = new OpenLayers.Feature.Vector(feature,null,linestringstyle2[numitineraire][categorie_couleur[feature.attributes.category]]);
				layerItineraires[numitineraire].addFeatures(itineraire);
				layerItineraires[numitineraire].setOpacity(0.6);

			}
			
			if(layerGares == 0)
			{
				layerGares = new OpenLayers.Layer.Vector("gares",{displayInLayerSwitcher:false,visibility:true});
				layerGares.setOpacity(1);
				map.addLayer(layerGares);
			}
			else
			{
				layerGares.removeAllFeatures();
				map.removeLayer(layerGares);map.addLayer(layerGares);
			}
			for (var i=0; i<f.length; i++)
			{
				var obj = f[i];
				var feature = obj.geometry;
				feature.attributes = obj.attributes;
				if(feature.attributes.itinerary != 1 && feature.attributes.category == 20)
				{
					var image;
					if(i < f.length && f[i-1].attributes.category == 21 && f[i+1].attributes.category == 21)
						image = "gare_etape";
					else if(i < f.length && f[i+1].attributes.category == 21)
						image = "gare_dep";
					else if(f[i-1].attributes.category == 21)
						image = "gare_arr";
					var iconeSpec = OpenLayers.Util.extend({}, iconeTrain);
					iconeSpec.externalGraphic = URL_BASE_SITEWEB+DOSSIER_SITEWEB+"res/img/"+image+".png";
					layerGares.addFeatures(new OpenLayers.Feature.Vector(feature.getVertices()[0],null,iconeSpec));
				}
			}

			// Ajout des itinéraires sur la barre de sélection
			set_nb_sols(numitineraire);

			if(numitineraire > 1)
			{
				max = 200 - 20;
				intervalle = (max / (numitineraire-1));
	
				for(var i=1; i<=numitineraire; i++)
				{
					if(best == i)
						ajouter_sol2(i,(i-1)*intervalle);
					else
						ajouter_sol(i,(i-1)*intervalle);
				}
			}
			else if(numitineraire == 1)
				ajouter_sol2(1,90);

			if(feuille_visible) $j('#colonne_droite').show();
		}
		else
		{
			for (var i=0; i<f.length; i++)
			{
				var obj = f[i];
				var feature = obj.geometry;
				feature.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
				feature.attributes = obj.attributes;
				if(feature.attributes.itinerary == path_static)
				{
					if(feature.attributes.itinerary != numitineraire)
					{
						solution_actuelle = feature.attributes.itinerary;
						numitineraire = feature.attributes.itinerary;
						best = feature.attributes.itinerary;
						layerItineraires[numitineraire] = new OpenLayers.Layer.Vector("itineraire"+numitineraire);
						layerItineraires[numitineraire].displayInLayerSwitcher = false;
						distance[numitineraire] = feature.attributes.distance;
						map.addLayer(layerItineraires[numitineraire]);
						linestringstyle2[numitineraire] = [];
						linestringstyle2[numitineraire][0] = OpenLayers.Util.extend({}, linestringstyle[0]);
						linestringstyle2[numitineraire][1] = OpenLayers.Util.extend({}, linestringstyle[1]);
					}
					
					if((feature.attributes.category > 7) || (feature.attributes.category < 1)) feature.attributes.category = 6;

					itineraire = new OpenLayers.Feature.Vector(feature,null,linestringstyle2[numitineraire][categorie_couleur[feature.attributes.category]]);
					layerItineraires[numitineraire].addFeatures(itineraire);
//						layerItineraires[numitineraire].setOpacity(0.6);
				}
			}
		}

//		chargement=0; // Une fois le premier calcul d'itinéraire fait, chargement ne sert plus
		maj_alti();
		maj_distance();
		maj_fdr();
	}

	finChargement();
	
	if(typeof(BALADE_CHARGER) != 'undefined')
	{
		afficherInfosBalade(BALADE_CHARGER);
		afficherNotation(4);
		$j("#radioModeBalade").attr("checked",true).trigger("change");
	}
	marqueurPoint.initialiser();
}

/**
 * Supprime les itinéraires et solutions
 */
function supprimerItineraires()
{
	for(var i=1; i<=nb_sols; i++)
		layerItineraires[i].destroy();

	remove_sols();

	layerItineraires = [];

	set_nb_sols(0);
}

/**
 * Fonction préparant la requête au serveur de calcul en fonction des noeud à visiter
 */
function demandeServer()
{		
	if(defItineraire.lon1 == 0 || defItineraire.lat1 == 0 || defItineraire.lon2 == 0 || defItineraire.lat2 == 0)
	{
		$j("#cacherfeuille").hide();
		feuille_visible = true;switchfeuille();
		$j("#preferences1").hide();$j("#ombre-preferences").hide();
		return;
	}
	else
	{
		$j("#cacherfeuille").show();
		feuille_visible = false;switchfeuille();
		$j("#preferences1").show();$j("#ombre-preferences").show();
	}
	var tenirCompteTravaux = 0;
    if(dynamic && ZONE_TRAVAUX && document.formTravaux.calculer.checked)
    {
            tenirCompteTravaux = 1;
    }

    if(typeRequete != 1)
    	req = URL_SERVER_TRAIN;
    else if(tenirCompteTravaux == 1)
		req = URL_SERVER_TRAVAUX;
	else 
		req = URL_SERVER;
	req+='?req='+typeRequete+'&lon1='+defItineraire.lon1+'&lat1='+defItineraire.lat1+'&lon2='+defItineraire.lon2+'&lat2='+defItineraire.lat2;
	if (defItineraire.ListemarkerEtape!=null)
	{
		ListeCoordEtape=new Array();
		for (i=1; i<defItineraire.ListemarkerEtape.length; i++)
		{
			ll = new OpenLayers.LonLat(defItineraire.ListemarkerEtape[i].geometry.x,defItineraire.ListemarkerEtape[i].geometry.y);
			ll=MToLonLat(ll);
			req+='&lonE'+i+'='+ll.lon + '&latE'+i+'='+ll.lat;
//			if(Math.abs(ll.lon) < 0.01 && Math.abs(ll.lat) < 0.01)return;
		}
	}

	if (perso)
	{
		req+='&perso=1';
		for (var i=0; i<criteres_perso.length; i++)
			req+='&pref'+i+'='+criteres_perso[i];
	}

	if(defItineraire.ListemarkerEtape.length > 0)
		req+='&nb_etapes='+(defItineraire.ListemarkerEtape.length-1);
	else
		req+='&nb_etapes=0';
	
	$j.ajax({
		dataType:'jsonp',
		url: req,
		success: onLoadItineraire,
		error: function(){alert('Erreur calcul itineraire 2')}
	    });

	$j('#colonne_droite').hide();
}


/**
 * Modifie le coefficient de compromis
 * 
 * @param newCoeff le nouveau coefficient de compromis
 * @param num le numéro de la solution */
function changeSolution(num)
{
	// On change la classe de tous les points solutions comme points non sélectionnés
	for(var i=1; i<=nb_sols; i++)
	{
		if(i == num)
		{
			if(!perso)	// Uniquement si on est pas en mode de compromise personnalisé
			{
				// On change la classe du point sélectionné
				var el2 = document.getElementById("sol"+i);
				el2.className = "solution2";
			}
			linestringstyle2[i][0].strokeWidth = linestringstyle[0].strokeWidth;
			linestringstyle2[i][1].strokeWidth = linestringstyle[1].strokeWidth;
		}
		else
		{
			if(!perso)	// Uniquement si on est pas en mode de compromise personnalisé
			{
				var el1 = document.getElementById("sol"+i);
				el1.className = "solution";
			}
			linestringstyle2[i][0].strokeWidth = linestringstylepetit[0].strokeWidth;
			linestringstyle2[i][1].strokeWidth = linestringstylepetit[1].strokeWidth;
		}
	}
	onmouseoutSolution(solution_actuelle);

	map.removeLayer(layerItineraires[solution_actuelle]);

	// On affecte le nouveau coefficient
	solution_actuelle = num;
	onmouseoverSolution(solution_actuelle);

	map.removeLayer(layerItineraires[solution_actuelle]);
	map.addLayer(layerItineraires[solution_actuelle]);
	if(layerGares !=0){map.removeLayer(layerGares);map.addLayer(layerGares);}

	maj_distance();
	maj_fdr();
	chargeAlti(solution_actuelle);
	marqueurPoint.supprimer();
}	

function onmouseoverSolution(num)
{
	layerItineraires[solution_actuelle].setOpacity = 0.9;

	map.addLayer(layerItineraires[num]);

	map.removeLayer(layerItineraires[solution_actuelle]);
	map.addLayer(layerItineraires[solution_actuelle]);
	if(layerGares !=0){map.removeLayer(layerGares);map.addLayer(layerGares);}

	chargeAlti2(solution_actuelle,num);
}

function onmouseoutSolution(num)
{
	if(num != solution_actuelle)
		map.removeLayer(layerItineraires[num]);

	layerItineraires[solution_actuelle].setOpacity = 0.6;

	map.removeLayer(layerItineraires[solution_actuelle]);
	map.addLayer(layerItineraires[solution_actuelle]);
	if(layerGares !=0){map.removeLayer(layerGares);map.addLayer(layerGares);}

	chargeAlti(solution_actuelle);
}


/**
 * Ajoute une solution sélectionnable
 * 
 * @param id l'identifiant de la solution
 * @param x la coordonnée x du div de la solution
 */
function ajouter_sol(id,x)
{
	if(!perso)	// Uniquement si on est pas en mode de compromise personnalisé
	{
		// On se positionne sur le père
		var div_pere = document.getElementById("barre_criteres");

		// div d'affichage de la solution
		var sol = document.createElement("div");
		sol.id = "sol"+id;
		sol.style.left = x+"px";
		sol.className = "solution";
		sol.onclick = function(){changeSolution(id); return false;}
		sol.onmouseover = function(){onmouseoverSolution(id); return false;}
		sol.onmouseout = function(){onmouseoutSolution(id); return false;}
		div_pere.appendChild(sol);
	}
}

/**
 * Ajoute une solution sélectionnée
 * 
 * @param id l'identifiant de la solution
 * @param x la coordonnée x du div de la solution
 */
function ajouter_sol2(id,x)
{
	solution_actuelle = id;

	if(!perso)	// Uniquement si on est pas en mode de compromise personnalisé
	{
		// On se positionne sur le père
		var div_pere = document.getElementById("barre_criteres");

		// div d'affichage de la solution
		var sol = document.createElement("div");
		sol.id = "sol"+id;
		sol.style.left = x+"px";
		sol.className = "solution2";
		sol.onclick = function(){changeSolution(id); return false;}
		sol.onmouseover = function(){onmouseoverSolution(id); return false;}
		sol.onmouseout = function(){onmouseoutSolution(id); return false;}
		div_pere.appendChild(sol);
	}
}

/**
 * Défini le nombre de solutions
 * 
 * @param nombre_sols le nombre de solutions
 */
function set_nb_sols(nombre_sols)
{
	nb_sols = nombre_sols;
}

/**
 * Supprime les solutions
 */
function remove_sols()
{
	if(!perso)	// Uniquement si on est pas en mode de compromise personnalisé
	{
		// On se positionne sur le père
		var div_pere = document.getElementById("barre_criteres");

		// On supprime toutes les solutions
		for(var i=1; i<=nb_sols; i++)
		{
			var el1 = document.getElementById("sol"+i);
			div_pere.removeChild(el1);
		}
	}
}

function plusProchePOI(type)
{
	$j.ajax( {
		type : "GET",
		url : "get_poi.php",
		data : {
			'types' : type,
			'lon':defItineraire.lon1,
			'lat':defItineraire.lat1,
			'nearest':1
		},
		success : function(msg) {
			var reader = new OpenLayers.Format.KML();
			data = reader.read(msg);
			defItineraire.lon2 = data[0].geometry.x;
			defItineraire.lat2 = data[0].geometry.y;
			
			layerMarkers.removeFeatures(markerArrivee);
			markerArrivee = new OpenLayers.Feature.Vector(LonLatToPoint(LonLatToM(new OpenLayers.LonLat(defItineraire.lon2,defItineraire.lat2))),null,iconArrivee);
			markerArrivee.attributes.nom = 'arrivee';
			layerMarkers.addFeatures(markerArrivee);
			geocoderPosition(defItineraire.lat2,defItineraire.lon2,'arrivee');
			demandeServer();
		}
	});
}

function changeTypeRequete(type)
{
	typeRequete = type;
	var offsetTop = 0;
	var mapElem = document.getElementById("map");
	for (var elem = mapElem; elem != null; elem = elem.offsetParent)
		offsetTop += elem.offsetTop;
	var height = getWindowHeight() - offsetTop - 25 - 40;
	if(type == 1)
	{
		$j('#fdr_contenu').css("height",(height-150) + "px");
		$j("#fdr #infos").show();
		$j("#ombre-etapes #etapes2").show();
		$j("#etapes1").show();
	}
	else
	{
		$j('#fdr_contenu').css("height",(height) + "px");
		$j("#fdr #infos").hide();
		$j("#ombre-etapes #etapes2").hide();
		$j("#etapes1").hide();
	}
		
	demandeServer()
}

/**
 * Sauvergarde de l'itinéraire sous forme d'objet, lon1, lat1, lon2, lat2, avec liste d'étapes
 * @returns objet itinéraire
 */
function sauver()
{
	var ancienItineraire = {lon1: defItineraire.lon1,lat1: defItineraire.lat1,lon2: defItineraire.lon2,lat2: defItineraire.lat2,etapes:new Array()};
	for(var i = 0; i < defItineraire.ListemarkerEtape.length-1; i++)
	{
		var ll = new OpenLayers.LonLat(defItineraire.ListemarkerEtape[i+1].geometry.x,defItineraire.ListemarkerEtape[i+1].geometry.y);
		ll=MToLonLat(ll);
		ancienItineraire.etapes.push({lon:ll.lon,lat:ll.lat});
	}
	return ancienItineraire;
}

/**
 * Restaurer un itinéraire précédemment sauvegardé
 * @param ancienItineraire
 */
function restaurer(ancienItineraire)
{
	// restauration de l'ancien itinéraire
	defItineraire = {lon1: ancienItineraire.lon1,lat1: ancienItineraire.lat1,lon2: ancienItineraire.lon2,lat2: ancienItineraire.lat2,ListemarkerEtape:new Array()};
	layerMarkers.removeAllFeatures();
	markerDepart = new OpenLayers.Feature.Vector(LonLatToPoint(LonLatToM(new OpenLayers.LonLat(ancienItineraire.lon1,ancienItineraire.lat1))),null,iconDepart);
	markerArrivee = new OpenLayers.Feature.Vector(LonLatToPoint(LonLatToM(new OpenLayers.LonLat(ancienItineraire.lon2,ancienItineraire.lat2))),null,iconArrivee);
	markerDepart.attributes.nom = 'depart';
	markerArrivee.attributes.nom = 'arrivee';
	layerMarkers.addFeatures(markerDepart);
	layerMarkers.addFeatures(markerArrivee);
	defItineraire.ListemarkerEtape = [[]];
	for(var i = 0; i < ancienItineraire.etapes.length; i++)
	{
		defItineraire.ListemarkerEtape[i+1] = new OpenLayers.Feature.Vector(LonLatToPoint(LonLatToM(new OpenLayers.LonLat(ancienItineraire.etapes[i].lon,ancienItineraire.etapes[i].lat))),null,iconEtape[i+1]);
		defItineraire.ListemarkerEtape[i+1].attributes.nom = 'etape'+(i+1);
		layerMarkers.addFeatures(defItineraire.ListemarkerEtape[i+1]);
	}
	// geocoder à nouveau les points
	if(MIN_LON <= defItineraire.lon1 && defItineraire.lon1 <= MAX_LON && MIN_LAT <= defItineraire.lat1 && defItineraire.lat1 <= MAX_LAT)
	{
		geocoderPosition(defItineraire.lat1,defItineraire.lon1,'depart');
	}
	if(MIN_LON <= defItineraire.lon2 && defItineraire.lon2 <= MAX_LON && MIN_LAT <= defItineraire.lat2 && defItineraire.lat2 <= MAX_LAT)
	{
		geocoderPosition(defItineraire.lat2,defItineraire.lon2,'arrivee');
	}
	for(i=0;i < NB_ETAPES_MAX;i++)
	{
		if(i < defItineraire.ListemarkerEtape.length -1)
		{
			$j("#etape"+(i+1)).show();
			cacherAstuce();
		}
		else
			$j("#etape"+(i+1)).hide();
	}
	
	for(i = 1; i < layerItineraires.length; i++)
	{
	    layerItineraires[i].setVisibility(false);
	}
	
	demandeServer();
}
