function Directions(map, panel, callback) {
	this.directions = new GDirections(map, panel);
	this.callback = callback;

	var me = this;
	GEvent.addListener(this.directions, "addoverlay", function() {
		if (typeof me.callback == "function") {
			me.callback.call();
		}
		if (typeof check_loader == "function") {
			check_loader({directions: false});
		}
	});
        GEvent.addListener(this.directions, "error", this.onError);
};

Directions.prototype.onError = function (dir) {
	if (typeof check_loader == "function") {
		check_loader({directions: false});
	}
	var code = dir.getStatus().code;
	if (code == G_GEO_UNKNOWN_ADDRESS) {
		alert("Erreur : Addresse inconnue ou incomplête");
	} else if (code == G_GEO_SERVER_ERROR) {
		alert("Erreur : Calcul d'itinéraire indisponible.");
	} else if (code == G_GEO_MISSING_QUERY) {
		alert("Erreur : Addresse incomplête.");
	} else if (code == G_GEO_BAD_KEY) {
		alert("Erreur : clé google incorrecte");
	} else if (code == G_GEO_BAD_REQUEST) {
		alert("Erreur : Addresse mal formulée.");
	} else if (code == G_GEO_TOO_MANY_QUERIES) {
		alert("Erreur : Nombre maximal de requêtes atteint pour la journée.");
	} else {
		alert("Erreur");
	}
};

Directions.prototype.markerToDirectionQuery = function (marker) {
	var coords = marker.getPoint().lat()+','+marker.getPoint().lng();
	var nom = "";

	// TODO: à revoir quand il y aura une methode setTitle().
	if (marker.nom) {
		nom = marker.nom;
	} else  {
		nom = marker.getTitle();
	}
	if (nom.length == 0) {
		return coords;
	} else {
		return nom + '@' + coords;
	}
};

Directions.prototype.load = function (from, to) {

	if (typeof check_loader == "function") {
		check_loader({directions: true});
	}
	
	this.from = from;
	this.to = to;

	var query = 'from: ';
	if (typeof(from) == "object") {
		query += this.markerToDirectionQuery(from);
	} else {
		query += from;
	}
	query += ' to: ';
	if (typeof(to) == "object") {
		query += this.markerToDirectionQuery(to);
	} else {
		query += to;
	}
	// On efface l'ancienne recherche, meme si il n'y avait pas d'ancienne recherche
	this.directions.clear();
	this.directions.load(query, {locale: 'fr'});
};

Directions.prototype.retour = function () {
	this.load(this.to, this.from);
};

Directions.prototype.clear = function () {
	this.directions.clear();
};

/** 
 * ajoute un petit formulaire pour selectionner la direction depuis/vers un marker.
 * @param Object marker le marker depuis/vers lequel on veut calculer une direction
 * @param Object html le noeud DOM correspondant à l'infoWindow du marker auquel sera ajouté le formulaire.
 * @param Object labels (optional) pour changer les labels par defaut
 * @return data renvoie le formulaire qu'il faudra ajouter à l'objet html
 */
Directions.prototype.getForm = function (marker, html, labels) {
	var direction = this;

	var lbls = {
		itineraire: "Itinéraire",
		apartirde: "A partir de cette agence",
		vers: "Vers cette agence",
		arrivee: "Lieu d'arrivée",
		depart: "Lieu de départ",
		submit: "Envoyer",
		cancel: "« Retour"
	};

	$.extend(lbls, labels);

	var data = $('<div class="gmnoprint">'
	+'	'+lbls.itineraire+' :'
	+'	<a class="dfm" href="javascript:void(0);">'+lbls.vers+'</a><span class="dtm">'+lbls.vers+'</span>'
	+'	-'
	+'	<a class="dtm" href="javascript:void(0);">'+lbls.apartirde+'</a><span class="dfm">'+lbls.apartirde+'</span>'
	+'	<div class="dform">'
	+'		<span class="dfm">'+lbls.arrivee+'</span>'
	+'		<span class="dtm">'+lbls.depart+'</span>'
	+'		<br/>'
	+'		<form>'
	+'			<input type="text" value="" name="address" /><input type="submit" value="'+lbls.submit+'">'
	+'		</form>'
	+'		<br/>'
	+'		<a class="retour" style="cursor: pointer;">'+lbls.cancel+'</a>'
	+'	</div>'
	+'</div>');

	// On cache les spans et le formulaire
	$('span, div.dform', data).hide();

	// Si on clique sur "Vers ..." ou "A partir de ..."
	$('a.dfm, a.dtm', data).click(function() {
		// Si direction.fromMarker est defini, on lance directement la recherche de l'itineraire
		// sans afficher le champ adresse
		if (direction.fromMarker) {
			direction.versAgence = $(this).is('.dfm');
			// Desactivation du lancemenat automatique de la recherche demandé
			//$('form',data).submit();
			//return;
		}

		// En fonction que c'est l'un ou l'autre,
		// on affiche ce qui est de classe dfm (Directions From Marker) ou (Directions To Marker)
		if ($(this).is('.dfm')) {
			direction.versAgence = true;
			$('.dfm',data).hide();
			$('.dtm',data).show();
		} else {
			direction.versAgence = false;
			$('.dtm',data).hide();
			$('.dfm',data).show();
		}

		// si le champ d'adresse n'est pas encore visible, l'affiche.
		// Pour cela on ferme et reouvre l'infoWindow pour qu'elle ait les bonnes dimensions.
		if (! $('div.dform',data).is(':visible')) {
			$('div.dform',data).show();

			// bidouille permettant de mettre le focus sur le champ de recherche
			// apres que l'infoWindow soit affichée.
			var listener = GEvent.addListener(marker, "infowindowopen",  function() {
				$('form',data)[0].address.focus();
				GEvent.removeListener(listener);
			});

			marker.openInfoWindow(html[0]);
		} else {
			$('form',data)[0].address.focus();
		}

	});

	// Si on clique sur "Retour", on masque le champ d'adresse
	$('a.retour', data).click(function(){
		$('span',data).hide();
		$('a',data).show();
		$('div.dform',data).hide();
		marker.openInfoWindow(html[0]);
	});

	// Si on submit, on lance la recherche d'itineraire
	$('form', data).submit(function() {
		var address = this.address.value;

		// On précise si nécéssaire que la recherche se limite à la france :
		if (null == address.match(/[\W,-]+fr(?:ance)?$|@/i)) {
			address += ", France";
		}

		if (direction.versAgence) {
			direction.load(address, marker);
		} else {
			direction.load(marker, address);
		}
		return false;
	});

	return data;

};
