
// Extracts pays, région, département, ville, code postal and adresse
// into an array from an AddressDetails object as returned by the 
// google geocoding api.
function extractDataFromAddressDetail(addrDetails) {
	var ret = new Array("", "", "", "", "", "");
	var country = addrDetails.Country;
	if (isset(country)) {
		ret[0] = country.CountryName;
		var adminArea = country.AdministrativeArea;
		if (isset(adminArea)) {
			ret[1] = adminArea.AdministrativeAreaName;
			var subAdminArea = adminArea.SubAdministrativeArea;
			if (isset(subAdminArea)) {
				ret[2] = subAdminArea.SubAdministrativeAreaName;
				var locality = subAdminArea.Locality;
				if (isset(locality))  {
					ret[3] = locality.LocalityName;
					var postalCode = locality.PostalCode;
					if (isset(postalCode)) {
						ret[4] = postalCode.PostalCodeNumber;
					}
					var thoroughfare = locality.Thoroughfare;
					if (isset(thoroughfare)) {
						ret[5] = thoroughfare.ThoroughfareName;
					}
				}
			}
		}
	}
	return ret;
}

// Sets appropriate data on the the given form from the given
// AddressDetails
function updateForm(theForm, depAddrDetails, arrAddrDetails, updateDepart, updateArrivee){
	if (updateDepart) {
		var depData = extractDataFromAddressDetail(depAddrDetails);
	
		theForm.depAdminArea.value = depData[1];
		theForm.depSubAdminArea.value = depData[2];
		theForm.depLocality.value = depData[3];
		theForm.depPostalCode.value = depData[4];
		theForm.depThoroughfare.value = depData[5];
	}

	if (updateArrivee) {
		var arrData = extractDataFromAddressDetail(arrAddrDetails);
		theForm.arrAdminArea.value = arrData[1];
		theForm.arrSubAdminArea.value = arrData[2];
		theForm.arrLocality.value = arrData[3];
		theForm.arrPostalCode.value = arrData[4];
		theForm.arrThoroughfare.value = arrData[5];
	}
}

var gDirTries = 0;
// Searches covoitureurs from the given form for the given key
function searchCovoitureur(theForm, lrvKey, updateDepart, updateArrivee){
	// reset covoitureurs list
	if (document.getElementById('covoitureurs') != undefined) {
		document.getElementById('covoitureurs').innerHTML = '';
	}
	
	if (document.getElementById('nbCov') != undefined) {
		document.getElementById('nbCov').innerHTML = '';
	}
	
	paginationfrom=0;
	var depok=false;
	var arrok=false;
	map.clearOverlays();
	bounds = new GLatLngBounds();
	document.getElementById('depPaysNok').style.display = "none" ; 
	document.getElementById('arrPaysNok').style.display = "none" ; 
	document.getElementById('depnok').style.display = "none" ; 
	document.getElementById('arrnok').style.display = "none" ; 
	document.getElementById('pointsnok').style.display = "none" ; 
	var pointDepartStr;
	var pointArriveeStr;
	
	var inputDepart = theForm.inputDepart.value;
	inputDepart = replaceVille(replaceRue(inputDepart));
	var paysDepart = theForm.paysDepart.value;
	var adressecompletedep = inputDepart + ", " + paysDepart;
	
	if (GBrowserIsCompatible()) {
		var geocoder = new GClientGeocoder();
		geocoder.getLocations(adressecompletedep, function (responseDep) {onGeocodedDepart(true, responseDep, theForm, adressecompletedep, updateDepart, updateArrivee, lrvKey)});
	} else {
		alert("Votre navigateur ne supporte pas la cartographie. Utilisez plutot Firefox, IE, Safari, Opera 8.02 ou Netscape 7.1");
	}
}

function getFirstPlacemarkWithCountryOrFirst(placemarks) {
	for(placemarkI=0; placemarkI<placemarks.length; placemarkI++) {
		var placemark = placemarks[placemarkI]; 
		if (placemark.AddressDetails && placemark.AddressDetails.Country) {
			return placemark;
		}
	}
	return placemarks[0];
}

function onGeocodedDepart(tryReverse, responseDep, theForm, adressecompletedep,updateDepart, updateArrivee, lrvKey) {
	var statusCode = responseDep.Status.code;
	if (statusCode == '200') {
		var placemarkDep = getFirstPlacemarkWithCountryOrFirst(responseDep.Placemark);
		// check if same country...
		var addressDetailsDep = placemarkDep.AddressDetails;
		var coordDep = placemarkDep.Point.coordinates;
		// /!\ in response from gmap corrdinates are in lng / lat
		pointDepartStr = coordDep[1]+","+coordDep[0];
	    var pointdepartgeo = new GLatLng(coordDep[1], coordDep[0]);
		
		if (tryReverse && !addressDetailsDep.Country) {
			//No country provided try to reverse first
			var geocoder = new GClientGeocoder();
			geocoder.getLocations(pointdepartgeo, function (responseDep) {onGeocodedDepart(false, responseDep, theForm, adressecompletedep, updateDepart, updateArrivee, lrvKey)});			
		} else {
			if (sameCountry(addressDetailsDep, "paysDepart")) {
				
				var inputArrivee = theForm.inputArrivee.value;
				inputArrivee = replaceVille(replaceRue(inputArrivee));
				var paysArrivee = theForm.paysArrivee.value;
				var adressecompletearr = inputArrivee + ", " + paysArrivee;
	
				// let's take care of destination point now
				var geocoder = new GClientGeocoder();
				geocoder.getLocations(adressecompletearr, function (responseArr) {onGeocodedArrivee(true, responseArr, theForm, adressecompletearr, pointdepartgeo, placemarkDep, updateDepart, updateArrivee, lrvKey)});
			} else {
				document.getElementById('depPaysNok').style.display = "" ; 
			}
		}
	} else {
		document.getElementById('depnok').style.display = "" ; 
	}
}

function onGeocodedArrivee(tryReverse, responseArr, theForm, adressecompletearr, pointdepartgeo, placemarkDep, updateDepart, updateArrivee, lrvKey) {
	var statusCode = responseArr.Status.code;
	if (statusCode == '200') {
		var placemarkArr = getFirstPlacemarkWithCountryOrFirst(responseArr.Placemark);
		var addressDetailsArr = placemarkArr.AddressDetails;
		var coordArr = placemarkArr.Point.coordinates;
		// /!\ in response from gmap corrdinates are in lng / lat
		pointArriveeStr = coordArr[1]+","+coordArr[0];
	    var pointarriveegeo = new GLatLng(coordArr[1], coordArr[0]);

	    if (tryReverse && !addressDetailsArr.Country) {
			//No country provided try to reverse first
			var geocoder = new GClientGeocoder();
			geocoder.getLocations(pointarriveegeo, function (responseArr) {onGeocodedArrivee(false, responseArr, theForm, adressecompletearr, pointdepartgeo, placemarkDep, updateDepart, updateArrivee, lrvKey)});			
		}else {
		    if (sameCountry(addressDetailsArr, "paysArrivee")) {
				// ok, we can proceed
				if(theForm.latitudeArrivee.value!=""&&theForm.longitudeArrivee.value!="") {
					var latA = theForm.latitudeArrivee.value;
					var lngA = theForm.longitudeArrivee.value;
					pointArriveeStr= latA + "," + lngA;
					pointarriveegeo = new GLatLng(latA, lngA);
				}
				gdir = new GDirections(map);
			    var searchCovoitureurOnGDirectionsLoad = function() {
			    	gDirTries = 0;
					if(pointdepartgeo!=pointarriveegeo) {
						// Opening of the 'please wait' modal panel
						if (window.modalPanel)
							window.modalPanel.load();
						// Let's set all parameters on the form for the case when users
						// click on inscription or mon compte buttons
						updateForm(theForm,  placemarkDep.AddressDetails, placemarkArr.AddressDetails, updateDepart, updateArrivee);
						
						var postgisItineraireLine = 
								LaRoueVerte.GMap.Utils.getPostgisLineStringFromPolyline(gdir.getPolyline(), gdir.getDistance().meters);
						
						// then call the WS
				     	callCovWS(lrvKey, pointDepartStr, pointArriveeStr,postgisItineraireLine, gdir.getDistance().meters);
						bounds.extend(pointdepartgeo);
						bounds.extend(pointarriveegeo);
					} else {
				     	document.getElementById('pointsnok').style.display = "" ; 
					}
					
					//Call back this standard handler on window
					window.onGDirectionsLoad();
			    };
			    gdir.loadFromWaypoints([(pointdepartgeo),(pointarriveegeo)],{preserveViewport: true});
			    GEvent.addListener(gdir, "load", searchCovoitureurOnGDirectionsLoad);
			    GEvent.addListener(gdir, "error", function() {
			    	handleSearchCovoitureursGdirError(adressecompletedep, adressecompletearr, theForm, lrvKey, updateDepart, updateArrivee, lrvKey);
			    });
			} else {
				document.getElementById('arrPaysNok').style.display = "" ; 
			}
		}
	} else {
		document.getElementById('arrnok').style.display = "" ; 
	}

	
}

function handleSearchCovoitureursGdirError(adresseCompDep, adresseCompArr, theForm, lrvKey, updateDepart, updateArrivee) {
	var gDirStatusCode = gdir.getStatus().code; 
	if (gDirStatusCode == G_GEO_SERVER_ERROR && gDirTries < 3) {
		gDirTries++;
		searchCovoitureur(theForm, lrvKey, updateDepart, updateArrivee);
	} else {
		if (serverLog) {
			var errorMsg = gdir.getStatus().code;
			try {
				errorMsg = 'Requested directions for: from=[' + adresseCompDep
						+ '], to=[' + adresseCompArr + '], geocoded=[' + gdir.D.name
						+ '], geocode status code: ['
						+ gdir.getStatus().code + ']';
			} catch (err) {
				errorMsg += ', InternalCode [001]';
			}
			serverLog('gdir', 'error', errorMsg);
		}
		handleErrors(false);
	}
}

function sameCountry(addressDetails, paysInputId) {
	if (addressDetails) {
		var country = addressDetails.Country;
		if (country) {
			var countryNameCode = country.CountryNameCode;
			if (countryNameCode) {
				var selectedPays = jQuery('#' + paysInputId + ' option:selected');
				var selectedCountryCode = selectedPays.attr('countryCode').toLowerCase();
				countryNameCode = countryNameCode.toLowerCase();
				if (countryNameCode == selectedCountryCode) {
					return true;
				}
			}
		}
	}
	return false;
} 

