var eMap, eDirections, eForm;
var oMap, oDirections, oBounds, oIcon, oGPS, oHover;
var aWaypoints;

window.addEvent('domready', function(){
	
	eMap = $('gmaps-map');
	eForm = $('gmaps-form');
	eDirections = new Element('div', {'class': 'gmaps-directions'}).inject(eForm, 'after');
	
	aWaypoints = {starts: [], ends: [], directions: []};
	
	$$(eForm.getElements('.gmaps-start'), eForm.getElements('.gmaps-end')).each(function(input){
		if(input.hasClass('gmaps-start')) var sWaypoint = 'start';
		else var sWaypoint = 'end';
		var sGeocode = input.value.substr(0, input.value.lastIndexOf('@'));
		var aLatLng = input.value.substr(input.value.lastIndexOf('@')+1).split(',');
		aWaypoints[sWaypoint+'s'].push({
			'title': (input.get('tag') == 'option') ? input.get('text') : sGeocode,
			'geocode': sGeocode,
			'latitude': aLatLng[0],
			'longitude': aLatLng[1],
			'item': input,
			'waypoint': sWaypoint
		});
	});
	
	if(GBrowserIsCompatible()){
		oMap = new GMap2(eMap);
		oBounds = new GLatLngBounds();
		oDirections = new GDirections(oMap);
		oGPS = new GPS(4, true);
		oMap.setCenter(new GLatLng(0, 0), 1);
		oMap.setUIToDefault();
		oMap.disableScrollWheelZoom();
		
		oIconEnd = new GIcon(G_DEFAULT_ICON);
		/*oIconEnd.image = '/img/gmaps/end.png';
		oIconEnd.shadow = null;
		oIconEnd.iconSize = new GSize(30, 40);
		oIconEnd.iconAnchor = new GPoint(15, 40);*/
		
		oIconStart = new GIcon(oIconEnd, '/img/gmaps/start.png');
		oIconStep = new GIcon(oIconEnd, '/img/gmaps/step.png');
		
		aWaypoints.ends.each(function(end){
			var oLatLng = new GLatLng(end.latitude, end.longitude);
			end.marker = new GMarker(oLatLng, {clickable: (end.item.get('tag') == 'option' ? true : false), icon: oIconEnd, title: end.geocode});
			if(end.item.get('tag') == 'option'){
				GEvent.bind(end.marker, 'click', end, function() {
					end.item.selected = true;
				});
			}
			oBounds.extend(oLatLng);
			oMap.addOverlay(end.marker);
		});
		//oMap.setCenter((oGmaps.latLng ? new GLatLng(oGmaps.latLng[0], oGmaps.latLng[1]) : oBounds.getCenter()), (oGmaps.zoom ? oGmaps.zoom : oMap.getBoundsZoomLevel(oBounds)));
		oMap.setCenter(oBounds.getCenter(), oMap.getBoundsZoomLevel(oBounds));
		
		eForm.addEvent('submit', function(event){
			event = new Event(event).stop();
			aWaypoints.directions.empty();
			eForm.getElements('*[name^=waypoints]').each(function(item, i){
				if(item.get('tag') == 'input') var sValue = item.value;
				else if(item.get('tag') == 'select') var sValue = item.options[item.selectedIndex].value;
				if(sValue != '') aWaypoints.directions.push(sValue);
			});
			if(aWaypoints.directions.length > 1){
				new Element('p', {'class': 'loading', text: 'Calcul de votre itinéraire en cours...'}).inject(eDirections.empty());
				oDirections.loadFromWaypoints(aWaypoints.directions, {getPolyline: true, getSteps: true, locale: 'fr'});
			}
		});
		
		GEvent.addListener(oDirections, 'error', function(){
			if(oDirections.getStatus().code == G_GEO_UNKNOWN_ADDRESS) var erreur = 'Aucune position géographique ne peut être trouvée pour une des adresses spécifiées. Ceci peut être du au fait que cette adresse est nouvelle, ou peut être incorrecte. Code de l\'erreur : '+oDirections.getStatus().code;
			else if(oDirections.getStatus().code == G_GEO_SERVER_ERROR) var erreur = 'Une requête de géolocalisation n\'a pas pu être exécutée. Code de l\'erreur : '+oDirections.getStatus().code;
			else if(oDirections.getStatus().code == G_GEO_MISSING_QUERY) var erreur = 'Vous devez entrer une adresse de départ. Code de l\'erreur : '+oDirections.getStatus().code;
			else if(oDirections.getStatus().code == G_GEO_BAD_KEY) var erreur = 'La licence est invalide, veuillez vérifier l\'intégrité de la clé. Code de l\'erreur : '+oDirections.getStatus().code;
			else if(oDirections.getStatus().code == G_GEO_BAD_REQUEST) var erreur = 'Une requête de n\'a pas pu être exécutée. Code de l\'erreur : '+oDirections.getStatus().code;
			else var erreur = 'Une erreur inconnue est survenue. Essayez de préciser l\'adresse (ville, pays).';
			new Element('p', {'class': 'error', text: erreur}).inject(eDirections.empty());
		});
		
		GEvent.addListener(oDirections, 'load', function(){
			oMap.clearOverlays();
			var sInfos = 'Itinéraire de <em>'+oDirections.getGeocode(0).address+'</em> à <em>'+oDirections.getGeocode(oDirections.getNumRoutes()).address+'</em>';
			if(oDirections.getNumRoutes() == 2) sInfos += ' en passant par <em>'+oDirections.getGeocode(1).address+'</em>';
			else if(oDirections.getNumRoutes() == 3) sInfos += ' en passant par <em>'+oDirections.getGeocode(1).address+'</em> et <em>'+oDirections.getGeocode(2).address+'</em>';
			else if(oDirections.getNumRoutes() > 3){
				sInfos += ' en passant par ';
				for(var i = 1; i < oDirections.getNumRoutes()-2; i++) sInfos += '<em>'+oDirections.getGeocode(i).address+'</em>, ';
				sInfos += '<em>'+oDirections.getGeocode(oDirections.getNumRoutes()-2).address+'</em> et <em>'+oDirections.getGeocode(oDirections.getNumRoutes()-1).address+'</em>';
			}
			sInfos += '.<br/>Distance totale : '+oDirections.getDistance().html+' (environ '+oDirections.getDuration().html+')';
				
			new Element('p', {html: sInfos, 'class': 'information'}).inject(eDirections.empty());
			var eSteps = new Element('ul', {'class': 'gmaps-steps'}).inject(eDirections);
			var i = 0;
			
			oHover = new GMarker(new GLatLng(0, 0), {icon: oIconStep});
			oMap.addOverlay(oHover);
			oHover.hide();
			aWaypoints.ends.each(function(end){
				end.marker.hide();
			});
					
			for(i = 0; i < this.getNumRoutes(); i++){
				var oRoute = this.getRoute(i);
				
				// Départ/arrêt
				var eStep = new Element('li', {
					'class': 'groute '+((i == 0) ? 'start' : 'pause'),
					id: 'groute-'+i,
					title: 'Coordonnées GPS : '+oGPS.format(oRoute.getStep(0).getLatLng().lat(), true)+', '+oGPS.format(oRoute.getStep(0).getLatLng().lng(), false),
					html: '<strong>'+((i == 0) ? 'Départ' : 'Arrêt')+' :</strong> '+oRoute.getStartGeocode().address+' <em><span class="distance">'+oRoute.getDistance().html+'</span> <span class="duration">environ '+oRoute.getDuration().html+'</span></em>'
				});
				eStep.oRoute = oRoute;
				eStep.addEvents({
					click: function(event){
						event = new Event(event).stop();
						oMap.showMapBlowup(oRoute.getStep(0).getLatLng());
					},
					mouseenter: function(event){
						this.addClass('hover');
					},
					mouseleave: function(event){
						this.removeClass('hover');
					}
				});
				eStep.injectInside(eSteps);
				
				// Etapes
				var sNbSteps = oRoute.getNumSteps();
				for (var j = 0; j < sNbSteps; j++){
					var oStep = oRoute.getStep(j);
					
					var eStep = new Element('li', {
						'class': 'gstep '+(j%2 == 1 ? 'alt' : ''),
						id: 'gstep-'+j,
						title: 'Coordonnées GPS : '+oGPS.format(oStep.getLatLng().lat(), true)+', '+oGPS.format(oStep.getLatLng().lng(), false),
						html: '<strong><span>Étape </span>'+(j+1)+'<span> :</span> </strong> '+oStep.getDescriptionHtml()+' <em><span class="distance">'+oStep.getDistance().html+'</span>'+(oStep.getDuration().seconds > 60 ? ' <span class="duration">'+oStep.getDuration().html+'</span>' : '')+'</em>'
					});
					eStep.oStep = oStep;
					eStep.addEvents({
						click: function(event){
							event = new Event(event).stop();
							oMap.showMapBlowup(this.oStep.getLatLng());
						},
						mouseenter: function(event){
							this.addClass('hover');
							oHover.setPoint(this.oStep.getLatLng());
							oHover.show();
						},
						mouseleave: function(event){
							this.removeClass('hover');
							oHover.hide();
						}
					});
					if(j == 0) eStep.addClass('first');
					else if(j == sNbSteps-1) eStep.addClass('last');
					eStep.inject(eSteps);
				}
			}
			
			// Arrivée
			var eStep = new Element('li', {
				'class': 'groute end',
				id: 'groute-'+i,
				title: 'Coordonnées GPS : '+oGPS.format(oRoute.getEndLatLng().lat(), true)+', '+oGPS.format(oRoute.getEndLatLng().lng(), false),
				html: '<strong>Arrivée :</strong> '+oRoute.getEndGeocode().address+' <em><span class="gps">Coordonnées GPS : '+oGPS.format(oRoute.getEndLatLng().lat(), true)+', '+oGPS.format(oRoute.getEndLatLng().lng(), false)+'</span></em>'
			});
			eStep.oRoute = oRoute;
			eStep.addEvents({
				click: function(event){
					event = new Event(event).stop();
					oMap.showMapBlowup(this.oRoute.getEndLatLng());
				},
				mouseenter: function(event){
					this.addClass('hover');
				},
				mouseleave: function(event){
					this.removeClass('hover');
				}
			});
			eStep.injectInside(eSteps);
			
			new Element('a', {'href': '#', 'text': 'Imprimer l\'itinéraire', 'events': {'click': function(event){event.stop(); window.print();}}}).inject(new Element('p', {'class': 'print'}).inject(eDirections));
		});
		
		GEvent.addListener(oDirections, 'addoverlay', function(){
			var oFirstMarker = oDirections.getMarker(0);
			oFirstMarker.hide();
			oFirstMarker = new GMarker(oFirstMarker.getPoint(), {icon: oIconStart});
			oMap.addOverlay(oFirstMarker);
			
			var oLastMarker = oDirections.getMarker(oDirections.getNumRoutes());
			oLastMarker.hide();
			oLastMarker = new GMarker(oLastMarker.getPoint(), {icon: oIconEnd});
			oMap.addOverlay(oLastMarker);
		});
	}
});
window.addEvent('unload', function(){
	GUnload();
});
var GPS = new Class({
	initialize: function(prec, card){
		if (prec) this.prec = prec;
		else this.prec = 0;
		if (card) this.card = true;
		else this.card = false; 
	},
	getCard: function(positive, lat) {
		if (lat) return positive ? "N" : "S";
		else return positive ? "E" : "O";
	},
	formatToDegMinSec : function(value, lat) {
		var prec = this.prec;
		var precMul = Math.pow(10, prec);
		var neg = value < 0 ? true : false;
		if (neg) value = -value;
		var degs = Math.floor(value);
		value -= degs;
		value *= 60;
		degs = degs.toString();
		if (neg && ! this.card) degs = "-"+degs;
		var mins = Math.floor(value);
		value -= mins;
		value *= 60;
		mins = mins.toString();
		var secs = value.toFixed(prec).toString();
		if (prec > 0) prec++;
		while(degs.length < 2) degs = "0" + degs;
		while(mins.length < 2) mins = "0" + mins;
		while(secs.length < 2 + prec) secs = " " + secs;
		return degs + '°' + mins + "'" + secs + '"' + (this.card ? this.getCard(!neg, lat) : "");
	},   
	formatToDegMin: function (value, lat) {
		var prec = this.prec;
		var precMul = Math.pow(10, prec);
		var neg = value < 0 ? true : false;
		if (neg) value = -value;
		var degs = Math.floor(value);
		value -= degs;
		value *= 60;
		degs = degs.toString();
		if (neg && ! this.card) degs = "-"+degs;
		var mins = value.toFixed(prec).toString();
		if (prec > 0) prec++;
		while(degs.length < 2) degs = "0" + degs;
		while(mins.length < 2 + prec) mins = "0" + mins;
		return degs + '°' + mins + "'" + (this.card ? this.getCard(!neg, lat) : "");
	},    
	formatToDec: function (value, lat) {
		var prec = this.prec;
		var precMul = Math.pow(10, prec);
		var neg = value < 0 ? true : false;
		if (neg) value = -value;
		var degs = value.toFixed(prec).toString();
		if (neg && ! this.card) degs = "-"+degs;
		if (prec > 0) prec++;
		while(degs.length < 3 + prec) degs = "0" + degs;
		return degs + '°' + (this.card ? this.getCard(!neg, lat) : "");
	}, 
	format: function(value, lat) {
		return this.formatToDegMin(value, lat);
	}
});