// Original script Copyright 2007-2008 Nico Goeminne (nicogoeminne@gmail.com)
// Modified by Xperience Webdevelopment (www.xperience-webdevelopment.nl)

function GReverseGeocoder(map) {
	this.map=map;
	this.gdirections = new GDirections();
	this.geocoder = new GClientGeocoder();
	this.lastpoint=null;
	this.closestonroad=null;
	this.experimental=false;
	this.ad="";
	this.step=10;
	this.start=1;
	this.gdirectionsrefine = new GDirections();
	GEvent.bind(this.gdirections, "error", this, this.handleError);
	GEvent.bind(this.gdirections, "load", this, this.processDirection);
	GEvent.bind(this.gdirectionsrefine, "error", this, this.handleError);
	GEvent.bind(this.gdirectionsrefine, "load", this, this.processDirectionRefine);
	
	this.point=point;
	this.recnr_update=recnr_update;
	this.tracename=tracename;
	this.imei=imei;
	this.speed=speed;
	this.datestring=datestring;
	this.timestring=timestring;
	this.label=label;
	this.mobile=mobile;
	this.autorefresh=autorefresh;
}

GReverseGeocoder.prototype.reverseGeocode = function(point, recnr_update, tracename,imei,speed,datestring,timestring,label,mobile,autorefresh,foutcode) {
	this.point=point;
	this.recnr_update=recnr_update;
	this.tracename=tracename;
	this.imei=imei;
	this.speed=speed;
	this.datestring=datestring;
	this.timestring=timestring;
	this.label=label;
	this.mobile=mobile;
	this.autorefresh=autorefresh;
	
	this.lastpoint = point;
	this.closestonroad = null;
	this.gdirections.clear();
	this.gdirections.loadFromWaypoints([point.toUrlValue(6),point.toUrlValue(6)],{getSteps: true, locale: "GB", getPolyline:true});
}

GReverseGeocoder.prototype.getStatus = function() {
	return this.gdirections.getStatus();
}

GReverseGeocoder.prototype.handleError = function() {
	var foutcode = this.gdirections.getStatus().code;
	GEvent.trigger(this, "error",this.point,this.recnr_update, this.tracename,this.imei,this.speed,this.datestring,this.timestring,this.label,this.mobile,this.autorefresh,foutcode);
}

GReverseGeocoder.prototype.processDirection = function() {
	var source = this;
	
	var point=this.point;
	var recnr_update=this.recnr_update;
	var tracename=this.tracename;
	var imei=this.imei;
	var speed=this.speed;
	var datestring=this.datestring;
	var timestring=this.timestring;
	var label=this.label;
	var mobile=this.mobile;
	var autorefresh=this.autorefresh;
	
	if ( this.gdirections.getPolyline() != null){
		this.closestonroad=this.gdirections.getPolyline().getVertex(0);;
	}
	
	var nrroutes = this.gdirections.getNumRoutes();
	if (nrroutes != 0) {
		var route = this.gdirections.getRoute(0);
		var nrsteps = route.getNumSteps();
		if (nrsteps != 0) {
			var step = route.getStep(0);
			var street = step.getDescriptionHtml();
			street = this.getStreet(street);
			var sw = new GLatLng(Number(this.lastpoint.lat()) - 0.01, Number(this.lastpoint.lng()) - 0.01);
			var ne = new GLatLng(Number(this.lastpoint.lat()) + 0.01, Number(this.lastpoint.lng()) + 0.01);
			var bounds = new GLatLngBounds(sw, ne);
			this.geocoder.setViewport(bounds);
			this.geocoder.getLocations(street,
				function(response) {
					var placemark = source.getBestMatchingPlacemark(response);
					if (placemark != null) {
						if(source.experimental) {
							source.ad = placemark.address;
							source.step=10;
							source.start=1;
							source.houseNumberSearch();
						}
						else {
							GEvent.trigger(source, "load", placemark,recnr_update, tracename,imei,speed,datestring,timestring,label,mobile,autorefresh);
						}
					}
					else{
						alert('error..........');
						source.handleError();
					}
				}
			);
		}
	}
}

GReverseGeocoder.prototype.getBestMatchingPlacemark = function(response){
	if (!response || response.Status.code != 200) return null;
	var j = -1;
	var mindist = 1000000;
	for (var i = 0; i < response.Placemark.length; i++){
		var place = response.Placemark[i];
		var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
		var temp = this.lastpoint.distanceFrom(point);
		if (temp < mindist) {
			j = i;
			mindist = temp;
		}
	}
	if(j < 0 ) return null;
	response.Placemark[j].RequestPoint = {
		"coordinates":[this.lastpoint.lng(),this.lastpoint.lat()]
	}
	response.Placemark[j].PointOnRoad = {
		"coordinates":[this.closestonroad.lng(),this.closestonroad.lat()]
	}
	response.Placemark[j].Distance=mindist;
	response.Placemark[j].DistanceOnRoad=this.closestonroad.distanceFrom(new GLatLng(response.Placemark[j].Point.coordinates[1], response.Placemark[j].Point.coordinates[0]));
	return response.Placemark[j];
}

GReverseGeocoder.prototype.getStreet = function(street){
	var str = street.split("</b>")[1];
	str =  str.substring(str.indexOf("<b>")+3);
	if (str.indexOf("/<wbr/>") > 0) {
		strs = str.split("/<wbr/>");
		if (strs[0].charAt(1) >= "0" && strs[0].charAt(1) <= "9") {
			str = strs[1];
		}
		else {
			str = strs[0];
		}
	}
	return str;
}

GReverseGeocoder.prototype.getPlacemarkProperty = function (placemark,propertyname){
	for (var property in placemark) {
		if((property == propertyname)) {
			return String(placemark[property]);
			} else if (typeof(placemark[property]) == 'object') {
			var r = this.getPlacemarkProperty(placemark[property], propertyname);
			if (r != null) return r;
		}
	}
	return null;
}

