// Procedures globales du projet
// Affiche une bulle d'information à une position
function AfficheInformation(sTexte, nLatitude, nLongitude)
{
	if (!gObjCarte)
		return ;

	var objCoordonnees;
	// Si la longitude et la latitude sont renseignées, on crée une coordonnée avec ces données
	if (nLatitude && nLongitude)
	{
		objCoordonnees = new google.maps.LatLng(nLatitude, nLongitude)
	}else{
		// si la latitude et la longitude ne sont pas renseignées, on prend le centre de la carte
		objCoordonnees = gObjCarte.getCenter();
	}
	
	var infoWindow = new google.maps.InfoWindow({content: sTexte,position:objCoordonnees});
	
	infoWindow.open(gObjCarte);
}
// Affiche un marqueur
function AfficheMarqueur(nLatitude, nLongitude, sIcone, bDragAndDropAutorise, sTexteInfoClic, nPrecision)
{
	
	if (!gObjCarte)
		return ;

	var objCoordonnees;
	var objMarqueur;
	
	// Si la longitude et la latitude sont renseignées, on crée une coordonnée avec ces données
	if (nLatitude && nLongitude)
	{
		objCoordonnees = new google.maps.LatLng(nLatitude, nLongitude)
	}else{
		// si la latitude et la longitude ne sont pas renseignées, on prend le centre de la carte
		objCoordonnees = gObjCarte.getCenter();
	}
	
	if (bDragAndDropAutorise == null)
		bDragAndDropAutorise = true;
		
	// Gestion de l'icône du marqueur
	if(sIcone=="")
	{
		sIcone = null;
	}
	else{
		var tempIcon = {
			url:sIcone
		}
	}
	
	
	// Gestion du cercle de précision
	if (nPrecision != null)
	{
		var options = {
			map:gObjCarte,
			center:objCoordonnees,
			radius:eval(nPrecision),
			fillColor: "#0088FF",
			fillOpacity: 0.2,
			strokeColor: "#0088FF",
			strokeOpacity: 0.5,
			strokeWeight: 1,
			clickable: false
		}
		var cercle = new google.maps.Circle(options);
		circlesArray.push(cercle);
	} 
	
	// Création du marqueur
	// Si on ne spécifie pas cette option, elle ne pourra pas être activée après coup
	var options = {
		draggable:bDragAndDropAutorise,
		position:objCoordonnees,
		map:gObjCarte,
		icon:tempIcon
	};
	// Ajout du marqueur
	objMarqueur = new google.maps.Marker(options); 
	markersArray.push(objMarqueur);
	
	// Ajout de l'info bulle si besoin
	if (sTexteInfoClic) {
		google.maps.event.addListener(objMarqueur, 'click', function() {
			if (!this.getMap()._infoWindow) {
				this.getMap()._infoWindow = new google.maps.InfoWindow();
				}
				this.getMap()._infoWindow.close();
				this.getMap()._infoWindow.setContent(sTexteInfoClic);
				this.getMap()._infoWindow.open(this.getMap(), this);
			});
	}
	
	// On renvoie l'objet marqueur
	return objMarqueur;	
}

var markersArray = [];
var circlesArray = [];
var linesArray = [];
var markerClusterer = null;
var rectangleArray = [];
var polygoneArray = [];
var KMLArray = [];
var directionsArray = [];
// Permet d'activer la gestion des raccourcis clavier
function AjouteGestionClavier()
{
	if (!gObjCarte)
		return null;

	var mapOptions = {
		keyboardShortcuts: true
	};
		
	// Ajoute l'évenement qui gère les touches clavier sur la carte
	gObjCarte.setOptions(mapOptions);
}

// Centre la carte sur une position
function CentreCarte(nLatitude, nLongitude, nZoom)
{
	if (!gObjCarte)
		return ;
		
	// Si le zoom n'est pas spécifié, on le met à la valeur actuelle
	if (!nZoom)
		nZoom = gObjCarte.getZoom();

	// Bouge la carte pour positionner le centre aux coordonnées données
	gObjCarte.setCenter(new google.maps.LatLng(nLatitude, nLongitude), nZoom);

}
// Pose un événement sur le clic sur la carte
function EvenementClic(sNomFonction)
{

	if (!gObjCarte)
		return null;


	if (gnEvenementClic)
		return gnEvenementClic;
	
	
	var objFunction;
	// On a récupéré le nom de la fonction sous forme de chaîne, donc on récupère le pointeur sur cette fonction
	objFunction = eval(sNomFonction);
	
	// sauvegarde de l'évenement Clic (si on veut le supprimer)
	gnEvenementClic = google.maps.event.addListener(gObjCarte,"click", objFunction);
	
	// Ajoute l'évenement click
	return gnEvenementClic;
}

// Pose un événement sur le survol de la carte
function EvenementSurvol(sNomFonction)
{
	
	if (!gObjCarte)
		return null;


	if (gnEvenementSurvol)
		return gnEvenementSurvol;

	// On a récupéré le nom de la fonction sous forme de chaîne, il faut récupérer le pointeur de la fonction
	var objFunction = eval(sNomFonction);
	
	// sauvegarde de l'évenement si on veut le supprimer
	gnEvenementSurvol = google.maps.event.addListener(gObjCarte,"mousemove", objFunction);
	
	// ensuite on ajoute l'évenement sur le mousemove
	return gnEvenementSurvol;
}

// Permet de modifier le zoom de la carte
function ModifieZoom(nZoom){
	if (!gObjCarte)
		return ;

    // Si le zoom n'est pas défini, on sort
	if (!nZoom)
		return false;

	// Le zoom doit être une valeur entre 0 et 17
	nZoom = Math.max(nZoom, 0);
	nZoom = Math.min(nZoom,17);
	
	// Modifie le zoom de la carte
	gObjCarte.setZoom(nZoom);	
}	
// Recherche les coordonnées d'une adresse
function RechercheCoordonneesDepuisAdresse(sAdresse, sNomFonction)
{
	
	// On a récupéré le nom de la fonction sous forme de chaîne, donc on récupère maintenant le pointeur sur cette fonction
	var objFonction = eval(sNomFonction);
	
	// Création de l'objet GeoCoder
	var ObjGeocoder = new google.maps.Geocoder();
	
	// Demande de récupération des coordonnées à partir de l'adresse 
	// => cette procédure est asynchrone, c'est à dire qu'elle va exécuter la procédure passée en paramètre lorsqu'elle aura terminée
	ObjGeocoder.geocode({'address': sAdresse}, objFonction);

}
// Supprime l'événement de clic sur la carte
function SupprimeEvenementClic()
{
	if (gnEvenementClic)
	{
		google.maps.event.removeListener(gnEvenementClic);
		gnEvenementClic = null;
	}
}
// Supprime l'événement de survol sur la carte
function SupprimeEvenementSurvol()
{
	if (gnEvenementSurvol)
	{
		google.maps.event.removeListener(gnEvenementSurvol);
		gnEvenementSurvol = null;
	}
}
// Supprime un marqueur
function SupprimeMarqueur(objMarker)
{
	if (!gObjCarte)
		return ;
		
	// Si le marqueur est spécifié, on supprime celui spécifié
	if (objMarker)
	{
		objMarker.setMap(null);
	}
}

// Affiche les champs qui permettent de choisir le type de carte
function AfficheControleTypesCarte(bAffiche)
{
	// Contrôle de type de carte (Plan, Satellite, Mixe)
	var options ={
		mapTypeIds:[HYBRID,ROADMAP,SATELLITE,TERRAIN]
	}
	gObjCarte.setOptions({mapTypeControl:bAffiche,mapTypeControlOptions:options});
}
// Affiche les champs qui permettent d'utiliser le zoom
function AfficheControleZoom(bAffiche)
{
	// Contrôle de type Zoom, (+ et - en haut à gauche de la carte)
	gObjCarte.setOptions({zoomControl:bAffiche});
}
// Affiche l'image qui permet d'avoir la miniature de la carte
function AfficheControleMiniature(bAffiche)
{
	// Contrôle de type de carte (Plan, Satellite, Mixe)
	var options ={
		opened:true
	}
	// Contrôle qui affiche la miniature de la carte en bas à droite
	gObjCarte.setOptions({overviewMapControl:bAffiche,overviewMapControlOptions:options});
}
// Affiche les champs qui permettent de connaître l'échelle
function AfficheControleEchelle(bAffiche)
{
	// Contrôle qui affiche l'échelle de la carte
	gObjCarte.setOptions({scaleControl:bAffiche});
}

// Affiche les champs qui permettent d'utiliser StreeView
function AfficheControleStreetView(bAffiche)
{
	// Contrôle qui affiche la gestion de streetView
	gObjCarte.setOptions({streetViewControl:bAffiche});
}
// Affiche les champs qui permettent de se déplacer dans la carte
function AfficheControleDeplacement(bAffiche)
{
	// Contrôle qui gère le déplacement
	gObjCarte.setOptions({panControl:bAffiche});
}
// Affiche les champs qui permettent de faire une rotation de la carte
function AfficheControleRotation(bAffiche)
{
	// Contrôle qui gère la rotation
	gObjCarte.setOptions({rotateControl:bAffiche});
}
// Supprime tous les marqueurs
function SupprimeToutMarqeurs()
{
	for (var i = 0; i < markersArray.length; i++ ) {
		markersArray[i].setMap(null);
		circlesArray[i].setMap(null);
	}
	
	markersArray = [];
	circlesArray = [];
	linesArray = [];
}
// Adapte la carte à ses marqueurs
function AdapteZoomEtCentre()
{
	var limits = new google.maps.LatLngBounds();
	for (var i = 0; i < markersArray.length; i++ ) {
		limits.extend(markersArray[i].position);
	}
	gObjCarte.fitBounds(limits);
}
// Renvoie la Latitude à partir de l'événement passé en paramètre
function EvenementVersLatitude(evt)
{
	// Si le point passé est invalide, on renvoie -1
	if (!evt)
	return -1;
	
	// Sinon, on renvoie la position y qui correspond à la latitude (y parce qu'on par de l'équateur et qu'on va vers les pôles donc verticalement)
	return evt.latLng.lat();
	
}
// Renvoie la Longitude à partir de l'événement passé en paramètre
function EvenementVersLongitude()
{
	// Si le point passé est invalide, on renvoie -1
	if (!evt)
	return -1;
	
	// Sinon, on renvoie la position x qui correspond à la longitude
	return evt.latLng.lng();
}
// Centre la carte sur une adresse
function CentreCarteSurAdresse(address)
{
	var geocoder = new google.maps.Geocoder();
	geocoder.geocode( { 'address': address}, function(results, status) {
		if (status == google.maps.GeocoderStatus.OK) {
			gObjCarte.setCenter(results[0].geometry.location);
		}
	});
}
// Affiche un tracé sur la carte
function AfficheTrace(nLatitude1, nLongitude1, nLatitude2, nLongitude2,bgedosic,libelleTrace)
{
	
	if (!gObjCarte)
	return ;
	
	var objCoordonnees1;
	var objCoordonnees2;
	var objTrace;
	
	// Si la longitude et la latitude sont renseignées, on crée des coordonnées avec ces données
	if (nLatitude1 && nLongitude2){
		objCoordonnees1 = new google.maps.LatLng(nLatitude1, nLongitude1);
		objCoordonnees2 = new google.maps.LatLng(nLatitude2, nLongitude2)
	}else{
		return ;
	}
	
	if(bgedosic !=null){
		// on fait rien
		}else{
		bgedosic = false
		}
	
	// Création du tracé
	var polyOptions = {
		strokeColor: '#FF0000',
		strokeOpacity: 0.8,
		strokeWeight: 2,
		icons : [{ // utile si pas de libellé
			icon : {
				path : google.maps.SymbolPath.FORWARD_OPEN_ARROW
				},
			offset : '50%'
			}],
		geodesic : bgedosic
	}
	
	// création polyline
	var poly = new google.maps.Polyline(polyOptions);
	var path = poly.getPath();
	// on ajoute les points ou polyline
	path.push(objCoordonnees1);
	path.push(objCoordonnees2);
	
	// centrer la carte sur le tracé
	var boundspoly = new google.maps.LatLngBounds();
	poly.getPath().forEach(function(e){//can't do polyline.getPath()[i] because it's a MVCArray
		boundspoly.extend(e);
		})         
	gObjCarte.fitBounds(boundspoly);
	// affichage
	poly.setMap(gObjCarte);
	// enregistre ce tracé dans variable globale pour la suppression
	linesArray.push(poly);
	
	if(libelleTrace !=''){
		// Affichage du libellé sur le tracé
		// On détermine le milieu du tracé
		inBetween = google.maps.geometry.spherical.interpolate(objCoordonnees1, objCoordonnees2, 0.5);  
		// Création d'un marker invisible
		labelMarker = new google.maps.Marker({  
			position: inBetween,  
			map: gObjCarte,
			visible: false
			});
		// Création d'un libellé
		objCoordonnees1.label = new Label();
		// Position du nouveau marqueur au milieu dans lequel on va afficher un libellé
		objCoordonnees1.label.bindTo('position', labelMarker, 'position');
		// Libellé
		objCoordonnees1.label.set( 'text',libelleTrace);
		// Affichage du libellé
		objCoordonnees1.label.setMap( gObjCarte);
		// enregistre ce libellé dans variable globale pour la suppression
		listeLabel.push(objCoordonnees1);
		}else{
		// on fait rien - affichage du tracé sans le libellé
		}
	
	
	// On renvoie l'objet tracé
	return poly;	
}


// Supprime tout ce qui est affiché sur la carte
function SupprimeTout()
{
	for (var i = 0; i < markersArray.length; i++ ) {
		markersArray[i].setMap(null);
	}
	for (var i = 0; i < circlesArray.length; i++ ) {
		circlesArray[i].setMap(null);
	}
	for (var i = 0; i < linesArray.length; i++ ) {
		linesArray[i].setMap(null);
	}
	for (var i = 0; i < rectangleArray.length; i++ ) {
		rectangleArray[i].setMap(null);
		}
	for (var i = 0; i < polygoneArray.length; i++ ) {
		polygoneArray[i].setMap(null);
		}
	for (var i = 0; i < directionsArray.length; i++ ) {
		directionsArray[i].setMap(null);
		}
	for (var i = 0; i < KMLArray.length; i++ ) {
		KMLArray[i].setMap(null);
		}
	for (var i = 0; i < listeLabel.length; i++ ) {
		listeLabel[i].label.setMap(null);
		}
	for (var i = 0; i < listeTrajet.length; i++ ) {
		listeTrajet[i].setMap(null);
		}
		
	markersArray = [];
	circlesArray = [];
	linesArray = [];
	rectangleArray = [];
	polygoneArray = [];
	directionsArray = [];
	KMLArray = [];
	listeLabel = [];
	listeTrajet = [];
	
	// Si le markerClusterer est renseigné, on le vide
	if (markerClusterer)
	{
		markerClusterer.clearMarkers();
	}
	
	
}

// Résumé : Permet de brancher la complétion automatique de l'adresse sur un champ
// Syntaxe :
// GoogleMapsAutocomplete ()
//
// Paramètres :
//	AliasChamp : // chaine. Correspond à la propriété ..Alias d'un champ de saisie de la page
// Valeur de retour :
// 	Aucun : 
function AutocompleteSurAdresse(AliasChamp)
{
	//recherche du champ
	var input = document.getElementById(AliasChamp);
	var options = {
		componentRestrictions: {country: 'fr'}
		};
	//Active l'auto-complétion
	var autocomplete = new google.maps.places.Autocomplete(input);
}

// Affiche une liste de marqueurs (liste fournies au format JSON)
function AfficheMarqueurJSON(sListeCoordJSON)
{
	var Pts= eval(sListeCoordJSON);
	
	var markers = [];
	for (var i = 0; i < Pts.length; i++) {
		var dataPhoto = Pts[i];
		var latLng = new google.maps.LatLng(dataPhoto.xLatitude,dataPhoto.xLongitude);
		var marker = new google.maps.Marker({
			position: latLng,
			map: gObjCarte,
			title: dataPhoto.sReference
			});
		markers.push(marker);
		markersArray.push(marker);
		};
}

// Résumé : Permet de créer des regroupements de marqueurs
// Syntaxe :
// GoogleMapsCreerMarkerClusterer (pts)
//
// Paramètres :
//	pts  : tableau de chaines de caractères. Format : ["46.1206559;4.305847","43.518518;1.559973",etc...]
// Valeur de retour :
// 	Aucune
//
function AfficheMarqueurClusterer(pts)
{
	Clustererbounds = new google.maps.LatLngBounds();
	gnListemark = [];
	var point = new Array(pts.length);
	for (i=0;i<pts.length;i++){
		var ch = pts[i];
		var tot = ch.split(";");	
		var latLng = new google.maps.LatLng(tot[0],tot[1]);
		var marker = new google.maps.Marker({
			position: latLng,
			draggable: false
			});
		gnListemark.push(marker);
		// mémorise la position : sert à centrer la carte ultérieurement sur l'ensemble du tracé
		Clustererbounds.extend(latLng);
		
		}
	
	var mcOptions = {gridSize: 50, maxZoom: 15};
	markerClusterer = new MarkerClusterer(gObjCarte, gnListemark,mcOptions);
	
	// création de la vue englobant l'ensemble des marqueurs
	gObjCarte.fitBounds(Clustererbounds);
	
	// on renvoie l'objet clusterer
	return markerClusterer;
}

// Résumé : Permet de tracer un trajet sur une carte et de faire parcourir ce tracé par une flèche par exemple.
// Syntaxe :
// GoogleMapsSymbolsAnime (pts)
//
// Paramètres :
//	pts  : Tableau de chaines de caractères. Format ["lat;lng","lat;lng",....]
// Valeur de retour :
// 	Aucune
function AfficheTraceAnime(pts)
{
	
	PtsBounds = new google.maps.LatLngBounds(); 
	lineCoordinates = [];
	var point = new Array(pts.length);
	for (i=0;i<pts.length;i++){
		var ch = pts[i];
		var tot = ch.split(";");	
		var latLng = new google.maps.LatLng(tot[0],tot[1]);
		
		lineCoordinates.push(latLng);
		// mémorise la position : sert à centrer la carte ultérieurement sur l'ensemble du tracé
		PtsBounds.extend(latLng);
		}
	
	var lineSymbol = {
		path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
		scale: 3,
		strokeColor: '#393'
		};
	
	line = new google.maps.Polyline({
		path: lineCoordinates,
		icons: [{
			icon: lineSymbol,
			offset: '100%'
			}],
		map: gObjCarte
		});
	var count = 0;
	offsetId = window.setInterval(function() {
		count = (count + 1) % 200;
		
		var icons = line.get('icons');
		icons[0].offset = (count / 2) + '%';
		line.set('icons', icons);
		}, 20);
	linesArray.push(line);
	// création de la vue englobant le tracé
	gObjCarte.fitBounds(PtsBounds);
	
	// on renvoie l'objet polyline
	return line;
}

// Résumé : Permet de tracer un polygone sur une carte google maps.
// Syntaxe :
// GoogleMapsPolygone (pts)
//
// Paramètres :
//	pts  : tableau de chaines, format : ["lat;lng","lat;lng",etc...]
// Valeur de retour :
// 	Aucune
//
function AffichePolygone(pts)
{
	CoordBounds = new google.maps.LatLngBounds(); // pour centrer carte sur ensemble des points
	parcelleHeig = [];
	var point = new Array(pts.length);
	for (i=0;i<pts.length;i++){
		var ch = pts[i];
		var tot = ch.split(";");	
		var latLng = new google.maps.LatLng(tot[0],tot[1]);
		//sommets du polygone
		parcelleHeig.push(latLng);
		// mémorise la position du nouveau point sert à centrer la carte ultérieurement sur l'ensemble des points
		CoordBounds.extend(latLng);
		}
	
	polygoneParcelleHeig = new google.maps.Polygon({
		paths: parcelleHeig,//sommets du polygone
		strokeColor: "#0FF000",//couleur des bords du polygone
		strokeOpacity: 0.8,//opacité des bords du polygone
		strokeWeight: 2,//épaisseur des bords du polygone
		fillColor: "#0FF000",//couleur de remplissage du polygone
		fillOpacity: 0.35////opacité de remplissage du polygone
		});
	
	polygoneArray.push(polygoneParcelleHeig);
	//lier le polygone à la carte. Ceci permet au polygone d'être affiché sur la carte
	polygoneParcelleHeig.setMap(gObjCarte);
	// création de la vue englobant le tracé
	gObjCarte.fitBounds(CoordBounds);
	
	// on renvoie l'objet polygon
	return polygoneParcelleHeig;
}

// Permet d'afficher un rectangle
function AfficheRectangle(LatSudOuest,LngSudOuest,LatNordEst,LngNordEst,edit)
{
	
	if (LatSudOuest==0){
		LatSudOuest = 44.490;
		};
	if (LngSudOuest==0){
		LngSudOuest = -78.649;
		};
	if (LatNordEst==0){
		LatNordEst = 44.599;
		};
	if (LngNordEst==0){
		LngNordEst = -78.443;
		};
	var bounds = new google.maps.LatLngBounds(new google.maps.LatLng(LatSudOuest, LngSudOuest),new google.maps.LatLng(LatNordEst, LngNordEst));
	
	var rectangle = new google.maps.Rectangle({
		bounds: bounds,
		editable: edit
		});
	rectangleArray.push(rectangle);
	rectangle.setMap(gObjCarte);
	
	// on renvoie l'objet rectangle
	return rectangle;
}

// Résumé : Permet de tracer un trajet à partir d'un fichier KML
// Syntaxe :
// GoogleMapsDessineKML (sURL)
//
// Paramètres :
//	sURL  : URL du fichier KML (http://..../<fichier.kml>)
// Valeur de retour :

function AfficheKML(sURL)
{
	var ctaLayer = new google.maps.KmlLayer(sURL);
	ctaLayer.setMap(gObjCarte);
	KMLArray.push(ctaLayer);
	// on renvoie l'objet KMLLayer
	return ctaLayer;
}

// Résumé : Création d'un cercle sur la carte google map
// Syntaxe :
// GoogleMapsCreerCercle (lat,lng,rayon,modifiable,func)
//
// Paramètres :
//	nlat  : latitude du centre de la carte
//	nlong : longitude du centre de la carte
//  rayon : rayon du cercle en mètres.
//  modifiable : booléen. Vrai pour permettre d'éditer le cercle sur la carte, faux dans le cas contraire
//  func : Nom de la procédure qui sera appeler lors de la modification du rayon du cercle. dans ce cas le paramètre 'modifiable' doit être à vrai.
// Valeur de retour :
// 	Aucune
//

function AfficheCercle(lat,lng,rayon,modifiable,func)
{
	var radius=rayon*1000; // Radius en Km
	
	var center = new google.maps.LatLng(lat, lng); // lat et lng du centre de cercle
	
	// la variable circle est déclarée dans la création de la carte googleMapsCreeCarte.
		
	var circle = new google.maps.Circle({
		center: center,
		radius: radius,
		strokeColor: "#FF0000", // couleur du tracé
		strokeOpacity: 0.8,
		strokeWeight: 2, // épaisseur du trait
		fillColor: "#FF0000", // couleur de fond
		fillOpacity: 0.35,
		map: gObjCarte,
		editable: modifiable
		});
	gObjCarte.fitBounds(circle.getBounds());
	circlesArray.push(circle);
	if(func !=null){
		google.maps.event.addListener(circle, 'radius_changed', eval(func));
	}
}

// Résumé : Permet de dessiner l'itinéraire entre une adresse de départ et une adresse d'arrivée.
// Syntaxe :
// GoogleMapsCalculItineraire ()
//
// Paramètres :
//	addressStart : // chaine. Correspond à l'adresse de départ
//	adressEnd : // chaine. Correspond à l'adresse d'arrivée
// Valeur de retour :
// 	Aucun : 
//
function AfficheItineraire(addressStart,adressEnd)
{
	var directions = new google.maps.DirectionsRenderer();
	var directionsService = new google.maps.DirectionsService();
	var request = {
		origin:addressStart, 
		destination:adressEnd,
		travelMode: google.maps.DirectionsTravelMode.DRIVING
		};
	directionsService.route(request, function(response, status) {
		if (status == google.maps.DirectionsStatus.OK) {
			directions.setDirections(response);
			}
		});
	directionsArray.push(directions);
	directions.setMap(gObjCarte);
	
	// on renvoie l'objet itinéraire
	return directionsArray;
}
// Résumé : Permet de dessiner l'itinéraire entre une adresse de départ et une adresse d'arrivée.
// Syntaxe :
// AfficheItineraireAvecEtape ()
//
// Paramètres :
//	addressStart : // chaine. Correspond à l'adresse de départ
//	adressEnd : // chaine. Correspond à l'adresse d'arrivée
// Valeur de retour :
// 	Aucun : 
//
function AfficheItineraireAvecEtape(addressStart,adressEnd,listeEtapes,aliasAffDetails)
{
	var waypts = [];
	for (i=0;i<listeEtapes.length;i++){
		waypts.push({
			location:listeEtapes[i],
			stopover:true});
	}

	var directions = new google.maps.DirectionsRenderer();
	var directionsService = new google.maps.DirectionsService();
	var request = {
		origin:addressStart, 
		destination:adressEnd,
		waypoints: waypts,
		optimizeWaypoints: true,
		travelMode: google.maps.DirectionsTravelMode.DRIVING
		};
	directionsService.route(request, function(response, status) {
		if (status == google.maps.DirectionsStatus.OK) {
			directions.setDirections(response);
			var route = response.routes[0];
//			var summaryPanel = document.getElementById('directions_panel');
			var summaryPanel = document.getElementById(aliasAffDetails);
			summaryPanel.innerHTML = '';
			// For each route, display summary information.
			for (var i = 0; i < route.legs.length; i++) {
				var routeSegment = i + 1;
				summaryPanel.innerHTML += '<b>Route Segment: ' + routeSegment + '</b><br>';
				summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
				summaryPanel.innerHTML += route.legs[i].end_address + '<br>';
				summaryPanel.innerHTML += route.legs[i].distance.text + '<br><br>';
				}
			}
		});
	directionsArray.push(directions);
	directions.setMap(gObjCarte);
	
	// on renvoie l'objet itinéraire
	return directionsArray;
}
// Résumé : Calcul le cap vrai (North true)
// Syntaxe :
// CalculCapVrai ()
//
// Paramètres :
//	lat1 : // Latitude du point de départ
//	lng1 : // Longitude du point de départ
//	lat2 : // Latitude du point d'arrivée
//	lng2 : // Longitude du point d'arrivée
// Valeur de retour :
// 	réel : le cap en degré [0,360]  

function CalculCapVrai(lat1,lng1,lat2,lng2)
{

	var pt1 = new google.maps.LatLng(lat1, lng1);
	var pt2 = new google.maps.LatLng(lat2, lng2);
	var heading = google.maps.geometry.spherical.computeHeading(pt1, pt2);
	if (heading>0){
	return heading;
	}else{
	return 360+heading;
	} 
	
}

// Résumé : Calcul la distance (grand cercle) entre deux points.
// Syntaxe :
// CalculDistanceEntreDeuxPoints ()
//
// Paramètres :
//	lat1 : // Latitude du point de départ
//	lng1 : // Longitude du point de départ
//	lat2 : // Latitude du point d'arrivée
//	lng2 : // Longitude du point d'arrivée
// Valeur de retour :
// 	réel : la distance en mètre

function CalculDistanceEntreDeuxPoints(lat1,lng1,lat2,lng2)
{
	var pt1 = new google.maps.LatLng(lat1, lng1);
	var pt2 = new google.maps.LatLng(lat2, lng2);
	var distance = google.maps.geometry.spherical.computeDistanceBetween(pt1, pt2);

	return distance;

}

// Récupération de l'objet carte.
function RecupereAPICarte(obj)
{
	// affectation à la variable globale navigateur.
	gObjCarte = obj;
}

// définition des fonctions et prototype. dérive de la classe : google.maps.OverlayView();
// pour l'affichage des libellés sur les tracés (Fonctions AfficheTracé)
function Label(opt_options) {
	// Initialisation
	this.setValues(opt_options);
	
	// Label spécifique
	var span = this.span_ = document.createElement('span');
	span.style.cssText = 'position: relative; left: -50%; top: -8px; ' +
	'white-space: nowrap; border: 1px solid red; ' +
	'padding: 2px; background-color: white';
	
	var div = this.div_ = document.createElement('div');
	div.appendChild(span);
	div.style.cssText = 'position: absolute; display: none';
}
Label.prototype = new google.maps.OverlayView();

// onAdd
Label.prototype.onAdd = function() {
	var pane = this.getPanes().floatPane;
	pane.appendChild(this.div_);
	
	// Assure que le label est redessiné si le texte ou la position change 
	var me = this;
	this.listeners_ = [google.maps.event.addListener(this, 'position_changed',function() { me.draw(); }),	google.maps.event.addListener(this, 'text_changed',function() { me.draw(); })	];
};
//  onRemove
Label.prototype.onRemove = function() {
	var i, I;
	this.div_.parentNode.removeChild(this.div_);
	
	for (i = 0, I = this.listeners_.length; i < I; ++i) {
		google.maps.event.removeListener(this.listeners_[i]);
		}
};

//  draw
Label.prototype.draw = function(e) {
	var projection = this.getProjection();
	var position = projection.fromLatLngToDivPixel(this.get('position'));
	
	var div = this.div_;
	
	div.style.left = position.x + 'px';
	div.style.top = position.y + 'px';
	div.style.display = 'block';
	
	this.span_.innerHTML = this.get('text').toString();
};

// Résumé : Permet de tracer un trajet sur une carte à partir d'une liste de point (Objet JSON)
// Syntaxe :
// afficheTrajetJson (pts)
//
// Paramètres :
//	sListeCoordJSON  : est un objet JSON Format : ["xLatitude":"32.1222","xLongitude":"-1.325"]
// Valeur de retour :
// 	Aucune
//
function afficheTrajetJson(sListeCoordJSON)
{
	var bounds = new google.maps.LatLngBounds();
	var pts= eval(sListeCoordJSON);
	var flightPlanCoordinates= new Array(pts.length);
	for (i=0;i<pts.length;i++){
		var ch = pts[i];	
		var pt = new google.maps.LatLng(ch.xLatitude,ch.xLongitude);
		flightPlanCoordinates[i]=pt;
		// ajoute la liste des points, pour le centrage de la carte
		bounds.extend(flightPlanCoordinates[i]);
		}
	
	var flightPath = new google.maps.Polyline({
		path: flightPlanCoordinates,
		strokeColor: "#FF0000",
		strokeOpacity: 1.0,
		strokeWeight: 2
		});
	
	// affichage du tracé
	flightPath.setMap(gObjCarte);
	// centre la carte sur le tracé
	gObjCarte.fitBounds(bounds);
	gObjCarte.setCenter(bounds.getCenter());
	
	// enregistre dans var. globale pour la suppression
	listeTrajet.push(flightPath);
}

// Résumé : Permet de tracer un trajet sur une carte à partir d'une liste de point
// Syntaxe :
// GoogleMapsTrajet (pts)
//
// Paramètres :
//	pts  : Tableau de chaines de caractères. Format ["xLatitude":"32.1222","xLongitude":"-1.325"]
// Valeur de retour :
// 	Aucune
//
function AfficheTrajet(sListeCoordJSON)
{
	var bounds = new google.maps.LatLngBounds();
	var pts= eval(sListeCoordJSON);
	var flightPlanCoordinates= new Array(pts.length);
	for (i=0;i<pts.length;i++){
		var ch = pts[i];	
		var pt = new google.maps.LatLng(ch.xLatitude,ch.xLongitude);
		flightPlanCoordinates[i]=pt;
		// ajoute la liste des points, pour le centrage de la carte
		bounds.extend(flightPlanCoordinates[i]);
	}
	
	var flightPath = new google.maps.Polyline({
		path: flightPlanCoordinates,
		strokeColor: "#FF0000",
		strokeOpacity: 1.0,
		strokeWeight: 2
		});
	
	
	
//	for (i=0;i<flightPlanCoordinates.length;i++) {
//		bounds.extend(flightPlanCoordinates[i]);
//		}
	
	flightPath.setMap(gObjCarte);
	// centre la carte sur le tracé
	gObjCarte.fitBounds(bounds);
	gObjCarte.setCenter(bounds.getCenter());
	listeTrajet.push(flightPath);
}

