function TarifCourse(itineraire) {
    this._visible = false;

    this._itineraire = itineraire; // Adresse de départ et d'arrivée
    this._datasUpdated = false;

    this._distance = 0; // distance de l'itinéraire itineraire en kilomètres
    this._duree = 0; // Durée de l'itinéraire en secondes
    this._dureeHtml = 0; // Durée de l'itinéraire
    this._prix = 0; // Coût de l'itinéraire (ne prend pas en compte l'approche du taxi)

    this._table = null;
    this._prixTaxis = new Array(); // Tableau de résultat de l'approche des taxis (objets ResultApprocheTaxi)

    /**
     * jour pour calculer la course :
     * jo : jour ouvrable
     * dim : dimanche
     * jf : jour férié
     */
    var date = new Date();
    this._heure = date.getHours();

    this._jour = "jo";
    if (date.getDay()==0) this._jour = "dim";

    this._typeCourse = 0; // Aller simple, 1=Aller retour

    /* Un itinéraire, ou un nouvel itineraire a été défini (itineraire a été modifié)
     * Si le calque est ouvert
     *   1. Recalculer le prix de la course
     *   2. Recalculer la course de tous les taxis définis
     *   3. Mettre à jour le contenu du calque
     * Sinon
     *   1. Mettre un flag indiquant que les calculs doivent être réactualisés
     *      Ne seront effectués qu'à l'appel de open()
     */
    var s = this;
    GEvent.addListener(itineraire, "itineraireChanged", function() {
	    if (!s._visible) {
		s._datasUpdated = false;
		return;
	    }

	    s.calculTarifs();

	    var divPrix = document.getElementById('idResultatPrixCourse');
	    divPrix.innerHTML = "";
	    divPrix.appendChild(s.resultsNode());

	    s.loadTable();
	});
};
TarifCourse.PRIX_MINIMUM = 5.8;

/**
 * Montre les informations de l'itinéraire
 * Cache le prix de la course si est visible
 */
TarifCourse.prototype.toggleDisplay = function(a) {
    var divPrix = document.getElementById('idResultatPrixCourse');

    if (this._visible) {
	divPrix.style.display = "none";
	a.innerHTML = "Estimer le prix de la course";
    } else {
	divPrix.style.display = "block";
	a.innerHTML = "Cacher l'estimation du prix de la course";
	itineraire.hide();

	if (!this._datasUpdated) this.calculTarifs();
	divPrix.innerHTML = "";
	divPrix.appendChild(this.resultsNode());
	
	this.loadTable();	

    }
    this._visible = !this._visible;
};
TarifCourse.prototype.hide = function() {
    if (!this._visible) return;

    this._visible = false;
    var divItineraire = document.getElementById('idResultatPrixCourse');
    divItineraire.style.display = "none";
    var a = document.getElementById('btDisplayPrix');
    a.innerHTML = "Estimer le prix de la course";
};

TarifCourse.prototype.centerToDepart = function() { 
    var adresse = this._itineraire._adresses[0];
    this._itineraire._gmap.setCenter(adresse.point());
    this._itineraire._gmap.setZoom(10);
};

TarifCourse.prototype.centerToArrivee = function() { 
    var adresse = this._itineraire._adresses[1];
    this._itineraire._gmap.setCenter(adresse.point());
    this._itineraire._gmap.setZoom(10);
};

TarifCourse.prototype.calculTarifs = function() { 
    this._prixTaxis = new Array();
    this._datasUpdated = true;

    this._distance = this._itineraire.distanceKm();
    this._duree = this._itineraire.dureeSecs();
    this._dureeHtml = this._itineraire.dureeHtml();

    // PRIX : requête au serveur :
    // Adresse de départ :
    //   département
    //   commune
    //   lat
    //   lng
    // Adresse d'arrivée :
    //   département
    //   commune
    //   lat
    //   lng
    // jour (jo | dim | jf)
    // heure
    // distance
    // durée
    // type de course : course (approche lorsque c'est le trajet d'approche du taxi)
    var prix = this.getPrixCourse();
    if (prix==null) return;
    this._prix = Math.round(prix);
};

TarifCourse.prototype.getPrixCourse = function() {
    var url = "./admin/index.php";
    var parameters = "obj=JsonTaxisPublic&action=getPrix";

    var adresse = this._itineraire._adresses[0];
    parameters += "&d1="+adresse.departement();
    parameters += "&c1="+adresse.commune();
    parameters += "&lat1="+adresse.lat();
    parameters += "&lng1="+adresse.lng();

    adresse = this._itineraire._adresses[1];
    parameters += "&d2="+adresse.departement();
    parameters += "&c2="+adresse.commune();
    parameters += "&lat2="+adresse.lat();
    parameters += "&lng2="+adresse.lng();    

    parameters += "&j="+this._jour;
    parameters += "&h="+this._heure;
    parameters += "&tc="+this._typeCourse;

    parameters += "&d="+this._distance;
    parameters += "&t="+this._duree;
    parameters += "&type=course";

    this._prix = -1;
    res = Ajax.makeRequestSynchroneJson(url, parameters);
    if (res==null) return null;

    return res['prix'];
};

TarifCourse.prototype.resultsNode = function() { // Contenu du calque
    var div = document.createElement('div');

    var itineraire = this._itineraire;
    if (itineraire._result==null) {
	div.innerHTML = "<h2>Aucun itinéraire n'est défini !</h2>";
	return div;
    }

    var adresses = itineraire._adresses;

    var innerHTML = '<h2>Jour et heure de la course</h2>';
    innerHTML += '<form name="formConfigCourse">';
    innerHTML += 'Heure : <select name="selectHourConfigCourse" onchange="return tarifCourse.recalculTarifs();">';
    for (var i=0;i<24;i++) {
	var j = i;
	if (j<10) j = "0"+i;
	var selected = "";
	if (i==this._heure) selected = "selected";
	innerHTML += '<option value="'+i+'" '+selected+'>'+j+' h</option>';
    }
    innerHTML += '</select>';

    var jo = "";
    var dim = "";
    if (this._jour=="dim") dim = "checked";
    else jo = "checked";
    innerHTML += '<input type="radio" value="jo" name="jourConfigCourse" '+jo+' onclick="return tarifCourse.recalculTarifs();" />Jour ouvrable ';
    innerHTML += '<input type="radio" value="dim" name="jourConfigCourse" '+dim+' onclick="return tarifCourse.recalculTarifs();" />Dimanche ';
    innerHTML += '<input type="radio" value="jf" name="jourConfigCourse" onclick="return tarifCourse.recalculTarifs();" />Jour férié';

    var aller = "";
    var allerRetour = "";
    if (this._typeCourse==0) aller = "checked";
    else allerRetour = "checked";
    innerHTML += '<input type="radio" value="0" name="typeConfigCourse" '+aller+' onclick="return tarifCourse.recalculTarifs();" /> Aller simple ';
    innerHTML += '<input type="radio" value="1" name="typeConfigCourse" '+allerRetour+' onclick="return tarifCourse.recalculTarifs();" /> Aller retour';
    innerHTML += '</form>';

    innerHTML += '<h2>Estimation du prix de cet itinéraire</h2>';
    innerHTML += '<table class="prixTaxis">';

    innerHTML += '<tr>';
    innerHTML += '<th>Adresse de départ</th>';
    innerHTML += '<th>Adresse d\'arrivée</th>';
    innerHTML += '<th>Distance</th>';
    innerHTML += '<th>Durée</th>';
    innerHTML += '<th>Prix</th>';
    innerHTML += '<tr>';

    innerHTML += '<tr>';
    innerHTML += '<td><a href="#" onclick="tarifCourse.centerToDepart(); return false;">' + adresses[0].adresse() + '</a></td>';
    innerHTML += '<td><a href="#" onclick="tarifCourse.centerToArrivee(); return false;">' + adresses[1].adresse() + '</a></td>';
    innerHTML += '<td>'+this._distance+' Kms</td>';
    innerHTML += '<td>'+this._dureeHtml+'</td>';
    innerHTML += '<td><span id="prixCourse">'+this._prix+'</span> €</td>';
    innerHTML += '<tr>';

    innerHTML += '</table>';

    innerHTML += "<h2>Estimation du prix de la course</h2>";
    innerHTML += '<p style="font-size: 11px;">1. Cliquez sur l\'adresse de départ ci-dessus pour centrer la carte sur ce lieu<br/>';
    innerHTML += "2. Trouvez le taxi le plus proche de l'adresse de départ<br/>";
    innerHTML += "3. Cliquez sur l'icone du taxi pour obtenir une estimation du prix de la course</p>";

    innerHTML += '<table class="prixTaxis" id="idTablePrixTaxis"></table>';
    innerHTML += '<br/><br/>';

    div.innerHTML = innerHTML;

    return div;
};

TarifCourse.prototype.loadTable = function() {
    this._table = new Table('idTablePrixTaxis');

    //this._table.addDeleteButton(true);
    
    th = new TH('distanceApproche', 'number', 'Distance d\'approche');
    th.setInnerHTML = function(data) {
	return {'html': data+' Kms', 'data': data}
    };
    this._table.addTH(th);
    
    th = new TH('dureeApproche', 'string', 'Durée d\'approche');
    this._table.addTH(th);
    
    th = new TH('prixApproche', 'number', 'prix d\'approche');
    th.setInnerHTML = function(data) {
	return {'html': data+' €', 'data': data}
    };
    this._table.addTH(th);

    th = new TH('prixTotal', 'number', 'prix total', true);
    th.setInnerHTML = function(data) {
	return {'html': data+' €', 'data': data}
    };
    this._table.addTH(th);

    th = new TH('dureeTotal', 'string', 'durée totale');
    this._table.addTH(th);
    
    this._table.createHeader();    
    
    var s = this;
    this._table.onRemove = function(id) {
	for (var i=0;i<s._prixTaxis.length;i++) {
	    if (s._prixTaxis[i].taxi().id()==id) {
		s._prixTaxis.splice(i, 1);
		return true;
	    }
	}
    };

    for (var i=0;i<this._prixTaxis.length;i++) {
	var approche = this._prixTaxis[i];
	var taxi = approche.taxi();

	var row = {};
	row['distanceApproche'] = approche.distanceKm();
	row['dureeApproche'] = approche.dureeHtml();
	row['prixApproche'] = approche.prix();
	row['prixTotal'] = approche.prix() + this._prix;
	if (row['prixTotal']<TarifCourse.PRIX_MINIMUM) row['prixTotal'] = TarifCourse.PRIX_MINIMUM;
	
	row['dureeTotal'] = Tools.secsToHuman(approche.dureeSecs() + this._duree);
	
	this._table.addRow(taxi.id(), row);
    }
};

/**
 * Calcul le prix de la course pour ce taxi
 * Est appelé lorsqu'un taxi est cliqué
 * Ne fait rien si le calque n'est pas ouvert
 */
TarifCourse.prototype.prixCourse = function(taxi) {
    if (!this._visible) return;

    for (var i=0;i<this._prixTaxis.length;i++) if (this._prixTaxis[i].taxi()==taxi) return;

    var s = this;
    var approche = new ResultApprocheTaxi(taxi, this);
    GEvent.addListener(approche, "loaded", function() {
	    s._prixTaxis.push(approche);

	    var row = {};
	    row['distanceApproche'] = approche.distanceKm();
	    row['dureeApproche'] = approche.dureeHtml();
	    row['prixApproche'] = approche.prix();
	    row['prixTotal'] = approche.prix() + s._prix;
	    if (row['prixTotal']<TarifCourse.PRIX_MINIMUM) row['prixTotal'] = TarifCourse.PRIX_MINIMUM;

	    row['dureeTotal'] = Tools.secsToHuman(approche.dureeSecs() + s._duree);

	    s._table.addRow(taxi.id(), row);
	});

    approche.calcul();
};

/**
 * La configuration (heure, jour...) a été modifiée
 * Recalculer les tarifs et mettre à jour le contenu HTML
 */
TarifCourse.prototype.recalculTarifs = function() {
    this._heure = document.forms['formConfigCourse'].elements['selectHourConfigCourse'].value;
    var radios = document.forms['formConfigCourse'].elements['jourConfigCourse'];
    for (var i=0;i<radios.length;i++) {
	if (radios[i].checked) {
	    this._jour = radios[i].value;
	    break;
	}
    }
    radios = document.forms['formConfigCourse'].elements['typeConfigCourse'];
    for (var i=0;i<radios.length;i++) {
	if (radios[i].checked) {
	    this._typeCourse = radios[i].value;
	    break;
	}
    }

    var prix = this.getPrixCourse();
    if (prix==null) return;
    this._prix = Math.round(prix);

    document.getElementById('prixCourse').innerHTML = this._prix;
    
    // Puis les prix d'approche des taxis
    for (var i=0;i<this._prixTaxis.length;i++) {
	this._prixTaxis[i].setPrix();
	
	// Mettre le tableau à jour
	var row = new Array();
	row['id'] = this._prixTaxis[i]._taxi.id();
	row['datas'] = new Array();
	row['datas']['prixApproche'] = this._prixTaxis[i].prix();
	row['datas']['prixTotal'] = this._prixTaxis[i].prix() + this._prix;
	if (row['datas']['prixTotal']<TarifCourse.PRIX_MINIMUM) row['datas']['prixTotal'] = TarifCourse.PRIX_MINIMUM;

	this._table.modRow(row);
    }

    return true;
};

function ResultApprocheTaxi(taxi, tarifCourse) {
    this._taxi = taxi;
    this._tarifCourse = tarifCourse;
    this._adresse = tarifCourse._itineraire._adresses[0]; // Le taxi doit se rendre à adresse

    this._distance = 0; // Kms
    this._dureeSecs = 0; // Secondes
    this._duree = 0; // hh:mm:ss
    this._prix = 0; // 
};

ResultApprocheTaxi.prototype.calcul = function() {
    this._gdirections = new GDirections();
    GEvent.addListener(this._gdirections, "error", Itineraire.handleGDirectionsErrors);
    var s = this;
    GEvent.addListener(this._gdirections, "load", function(dir) { s.onItineraireFound(dir); });

    var waypoints = new Array();
    waypoints[0] = this._taxi.lat()+","+this._taxi.lng();
    waypoints[1] = this._adresse.lat()+","+this._adresse.lng();
    this._gdirections.loadFromWaypoints(waypoints);
};

ResultApprocheTaxi.prototype.taxi = function() { return this._taxi; };
ResultApprocheTaxi.prototype.distanceKm = function() { return this._distance; };
ResultApprocheTaxi.prototype.dureeHtml = function() { return this._duree; };
ResultApprocheTaxi.prototype.dureeSecs = function() { return this._dureeSecs; };
ResultApprocheTaxi.prototype.prix = function() { return this._prix; };

ResultApprocheTaxi.prototype.onItineraireFound = function(dir) { 
    var distance = dir.getDistance();
    this._distance = distance['meters']/1000;

    var duree = dir.getDuration();
    this._dureeSecs = duree['seconds'];
    this._duree = duree['html'];

    this.setPrix();

    GEvent.trigger(this, "loaded");
};

ResultApprocheTaxi.prototype.setPrix = function() { 
    var prix = this.getPrix();
    if (prix==null) return;
    
    this._prix = Math.round(prix);    
};

ResultApprocheTaxi.prototype.getPrix = function() { 
    // PRIX : requête au serveur :
    // Adresse de départ : GDirections ne retourne pas le département et la commune de départ
    // on suppose alors que le taxi est proche du lieu de départ, et par conséquent le département
    // et la commune sont les même que celles d'arrivé
    // Adresse d'arrivée : (est l'adresse de départ de la course)
    //   département
    //   commune
    //   lat
    //   lng
    // jour (jo | dim | jf)
    // heure
    // distance
    // durée
    // type de course : approche

    var url = "./admin/index.php";
    var parameters = "obj=JsonTaxisPublic&action=getPrix";

    parameters += "&lat1="+this._taxi.lat();
    parameters += "&lng1="+this._taxi.lng();    

    var adresse = this._adresse;
    parameters += "&d2="+adresse.departement();
    parameters += "&c2="+adresse.commune();
    parameters += "&lat2="+adresse.lat();
    parameters += "&lng2="+adresse.lng();    

    parameters += "&j="+this._tarifCourse._jour;
    parameters += "&h="+this._tarifCourse._heure;
    parameters += "&tc="+this._typeCourse;

    parameters += "&d="+this._distance;
    parameters += "&t="+this._duree;
    parameters += "&type=approche";

    res = Ajax.makeRequestSynchroneJson(url, parameters);
    if (res==null) return null;

    return res['prix'];
};


