function Adresse(adresse, lat, lng, region, departement, commune) {
    this._id = Adresse._num++;
    if (!Adresse.Instances) Adresse.Instances = {};
    Adresse.Instances[this._id] = this;

    this._adresse = adresse;
    this._lat = lat;
    this._lng = lng;
    this._region = region;
    this._departement = departement;
    this._commune = commune;

    this._point = new GLatLng(lat, lng);
};
Adresse._num = 0;

Adresse.prototype.id = function() { return this._id; };
Adresse.prototype.adresse = function() { return this._adresse; };
Adresse.prototype.lat = function() { return this._lat; };
Adresse.prototype.lng = function() { return this._lng; };
Adresse.prototype.region = function() { return this._region; };
Adresse.prototype.departement = function() { return this._departement; };
Adresse.prototype.commune = function() { return this._commune; };
Adresse.prototype.point = function() { return this._point; };

Adresse.find = function(adresse, callback) {
    if (!Adresse._geocoder) Adresse._geocoder = new GClientGeocoder();
    if (!Adresse._geocoderErrors) {
	Adresse._geocoderErrors = {};
	Adresse._geocoderErrors[G_GEO_SUCCESS]            = "Success";
	Adresse._geocoderErrors[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
	Adresse._geocoderErrors[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
	Adresse._geocoderErrors[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
	Adresse._geocoderErrors[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
	Adresse._geocoderErrors[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
	Adresse._geocoderErrors[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
    };
	
    Adresse._geocoder.getLocations(adresse, function(result) {
	    Adresse.handlerClientGeocoder(result, callback);
	});
};

Adresse.handlerClientGeocoder = function(result, callback) {
    // ERREUR
    if (result.Status.code!=G_GEO_SUCCESS) {
	var reason = "Code " + result.Status.code;

	if (Adresse._geocoderErrors[result.Status.code]) reason = Adresse._geocoderErrors[result.Status.code];
	alert("Impossible de trouver cette adresse :\n" + reason);
	return;
    }

    // PLUSIEURS RESULTATS
    if (result.Placemark.length>1) { 	
	Adresse.openChoiceAdresses(result, callback);	
	return;
    }    

    // UN SEUL RESULTAT
    var placemark = result.Placemark[0];
    var lat = placemark.Point.coordinates[1];
    var lng = placemark.Point.coordinates[0];

    var adresse = placemark.address;
    var region = "";
    if (placemark.AddressDetails &&
	placemark.AddressDetails.Country &&
	placemark.AddressDetails.Country.AdministrativeArea)
	region = placemark.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
    
    var departement = "";
    var commune = "";
    if (region!="") {
	var p = placemark.AddressDetails.Country.AdministrativeArea;
	if (p.SubAdministrativeArea) {
	    departement = p.SubAdministrativeArea.SubAdministrativeAreaName;
	    if (p.SubAdministrativeArea.Locality) commune = p.SubAdministrativeArea.Locality.LocalityName;
	}
    }
    
    var a = new Adresse(adresse, lat, lng, region, departement, commune);
    callback(a);
};

Adresse.openChoiceAdresses = function(result, callback) {
    var window = new ModalWindow("Sélection d'adresse", 700, 500);

    var div = document.createElement('div');
    var h2 = document.createElement('h2');
    div.appendChild(h2);
    h2.innerHTML = 'Plusieurs lieux ont été trouvés. Double cliquez sur un lieu pour le sélectionner.</h2>';
    div.appendChild(document.createElement('br'));

    var tableNode = document.createElement('table');
    tableNode.className = "adresses";
    div.appendChild(tableNode);
    
    window.setContentNode(div);

    var table = new Table(tableNode);
    table.setAlternateRowColors();

    HEvent.addListener(table, "rowDblClicked", function(id, evt) {
	    var row = table._trs[id]._row;

	    var lat = row['lat'];
	    var lng = row['lng'];
	    var adresse = row['adresse'];
	    var region = row['region'];
	    var departement = row['departement'];
	    var commune = row['commune'];

	    var a = new Adresse(adresse, lat, lng, region, departement, commune);
	    
	    window.close();
	    callback(a);
	    
	});

    th = new TH('adresse', 'string', 'Adresse');
    table.addTH(th);

    th = new TH('region', 'string', 'Région');
    table.addTH(th);

    th = new TH('departement', 'string', 'Département');
    table.addTH(th);

    th = new TH('commune', 'string', 'Commune');
    table.addTH(th);

    table.createHeader();
	
    for (var i=0;i<result.Placemark.length;i++) {
	var placemark = result.Placemark[i];
	
	var lat = placemark.Point.coordinates[1];
	var lng = placemark.Point.coordinates[0];
	
	var adresse = placemark.address;
	var region = "";
	if (placemark.AddressDetails &&
	    placemark.AddressDetails.Country &&
	    placemark.AddressDetails.Country.AdministrativeArea)
	    region = placemark.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
	
	var departement = "";
	var commune = "";
	if (region!="") {
	    var p = placemark.AddressDetails.Country.AdministrativeArea;
	    if (p.SubAdministrativeArea) {
		departement = p.SubAdministrativeArea.SubAdministrativeAreaName;
		if (p.SubAdministrativeArea.Locality) commune = p.SubAdministrativeArea.Locality.LocalityName;
	    }
	}
	if (commune=='') continue;

	var row = {};
	row['adresse'] = adresse;
	row['region'] = region;
	row['departement'] = departement;
	row['commune'] = commune;	
	row['lat'] = lat;
	row['lng'] = lng;
	
	table.addRow(i, row);
    }

    window.exec();
};

Adresse.prototype.windowMap = function() {
    var div = document.createElement('div');
    div.style.padding = "1em";

    var node = document.createElement('p');
    node.innerHTML = "<strong>Adresse :</strong> "+this._adresse;
    div.appendChild(node);
    
    node = document.createElement('p');
    node.innerHTML = "<strong>Région :</strong> "+this._region;
    div.appendChild(node);

    node = document.createElement('p');
    node.innerHTML = "<strong>Département :</strong> "+this._departement;
    div.appendChild(node);

    node = document.createElement('p');
    node.innerHTML = "<strong>Commune :</strong> "+this._commune;
    div.appendChild(node);

    // Bouton d'ajout au carnet d'adresses
    var s = this;

    node = document.createElement('p');
    node.style.textAlign = "right";
    div.appendChild(node);

    var a = document.createElement('a');
    a.href = "#";
    
    a.onclick = function() {
	HEvent.trigger(s, "addToCarnetAdresse");
	return false;
    };
    a.innerHTML = "Ajouter au carnet d'adresse";
    node.appendChild(a);
    
    // Bouton de suppression du marker
    var a = document.createElement('a');
    a.href = "#";
    
    a.onclick = function() {
	HEvent.trigger(s, "removeMarker");
	return false;
    };
    a.innerHTML = "Supprimer la punaise de la carte";
    div.appendChild(a);

    return new WindowMapAdresse(div);
}


function WindowMapAdresse(div) {
    this.superClass = WindowMap;
    this.superClass("");
    delete this.superclass;

    this._div = div;
}
WindowMapAdresse.prototype = new WindowMap();

/**
 * Est appelé lorsqu'on clique sur le pushpin de la carte
 * Doit retourner un node, qui est celui qui sera intégré au calque de GMap2
 */
WindowMapAdresse.prototype.open = function() { return this._div; }

