var GM3 = Class.create();
GM3.prototype = {

	initialize: function(map) {
		this.routeid;
		this.map = map;
		this.markers=new Array();
		this.marker_start = new google.maps.Marker();
		this.marker_end = new google.maps.Marker();

		this.points=new Array();
		this.poly = new google.maps.Polyline();

		this.point_user= new google.maps.LatLng();
		this.point_start= new google.maps.LatLng();
		this.point_end= new google.maps.LatLng();
		this.point_center= new google.maps.LatLng();
		
		this.bounds = new google.maps.LatLngBounds();
		this.lat_min= 999;
		this.lat_max= -999;
		this.lat_med= 0;
		this.lng_min= 999;
		this.lng_max= -999;
		this.lng_med= 0;
		
		this.totaldistance=0;
		this.stagedistance=0;

	},
	undoStep: function() {	//this function called when the "Undo Last" button clicked
		this.popPoint();
		this.drawRoute();
	},
	resetRoute: function() {	//called when the "Clear" button clicked
		for (var i=0;i<this.markers.length;i++) {
			this.markers[i].setMap(null);
		}
		this.markers.length=0;
		this.marker_start.setMap(null);
		this.marker_end.setMap(null);
		
		this.poly.setMap(null);

		this.points.length=0;

		this.totaldistance=0;
		this.stagedistance=0;
		$("routedistance").value=0;
		$("routedistancekm").value=0;
		$("routedata").value="";

		this.map.setCenter(this.point_start);
	},
	clearOverlays: function() {
		for (var i=0;i<this.markers.length;i++) {
			this.markers[i].setMap(null);
		}
		this.marker_start.setMap(null);
		this.marker_end.setMap(null);
		this.poly.setMap(null);
	},
	
	drawRoute: function() {
		this.clearOverlays();
		var route_endpoint_image = new google.maps.MarkerImage("fe_roundsymbol.png",new google.maps.Size(19, 19),new google.maps.Point(0,0),new google.maps.Point(9, 10));

		if (this.points.length==0) {
			this.point_start=this.point_user;
		} else if (this.points.length==1) {
			this.point_start=this.points[0];
			this.marker_start = new google.maps.Marker({position:this.point_start,map:this.map,icon:route_endpoint_image});
		} else {
			this.point_start=this.points[0];
			this.point_end=this.points[this.points.length-1];
			this.poly.setMap(null);
	
			this.poly = new google.maps.Polyline({zIndex:1,map:this.map,path:this.points,strokeColor:"#003399",strokeOpacity:0.6,strokeWeight:6});
			this.marker_start = new google.maps.Marker({position:this.point_start,map:this.map,icon:route_endpoint_image});
			this.marker_end = new google.maps.Marker({position:this.point_end,map:this.map,icon:route_endpoint_image});
		}
		
		for (i=0;i<this.markers.length;i++) {
			var mile_to_display = i+1;
			if (mile_to_display>60) {
				var mm_image = "/fe_roundsymbol.png";
			} else {
				var mm_image = "/images/icons/mm_"+mile_to_display+".png";
			}
			var marker_image = new google.maps.MarkerImage(mm_image,new google.maps.Size(19, 19),new google.maps.Point(0,0),new google.maps.Point(9, 10));
			
			this.markers[i] = new google.maps.Marker({position:this.markers[i].position,map:this.map,icon:marker_image});
		}
		document.getElementById("latitude").value=this.point_start.lat();
		document.getElementById("longitude").value=this.point_start.lng();
		document.getElementById("routedata").value=this.points.toString();
		$("routedistance").value=gm3.roundDistance(gm3.totaldistance);
		$("routedistancekm").value=gm3.roundDistance(gm3.totaldistance*1.609344);

	},
	pushPoint: function (point) {
		this.points.push(point);
		this.bounds.extend(point);
		this.point_start=this.points[0];
		this.point_end=point;
		var oldmilescovered=Math.floor(this.totaldistance);
		var olddistance=this.totaldistance;
		if (this.points.length>1) {
			this.stagedistance=this.distPointToPoint(this.points[this.points.length-1],this.points[this.points.length-2])
			this.totaldistance=this.totaldistance+this.stagedistance;
		} else {
			this.totaldistance=0;
		}
		if (point.lat() < this.lat_min) { this.lat_min=point.lat();	}
		if (point.lat() > this.lat_max) { this.lat_max=point.lat();	}
		if (point.lng() < this.lng_min) { this.lng_min=point.lng();	}
		if (point.lng() > this.lng_max) { this.lng_max=point.lng();	}
		this.lat_med=this.lat_min+(this.lat_max-this.lat_min)/2;
		this.lng_med=this.lng_min+(this.lng_max-this.lng_min)/2;
		this.point_center = new google.maps.LatLng(this.lat_med,this.lng_med);
		
		var newmilescovered=Math.floor(this.totaldistance);
		for (var x=oldmilescovered;x<newmilescovered;x++) {
			var markertoplace=x+1;
			var distanceRatio = (markertoplace - olddistance) / (this.totaldistance - olddistance);
			var point_new = this.points[this.points.length-1];
			var lat_new = point_new.lat();
			var lng_new = point_new.lng();
			var point_old = this.points[this.points.length-2];
			var lat_old = point_old.lat();
			var lng_old = point_old.lng();
			
			var lat_mm = 1*lat_old+1*(lat_new-lat_old)*distanceRatio;
			var lng_mm = 1*lng_old+1*(lng_new-lng_old)*distanceRatio;
			var latlng= new google.maps.LatLng(lat_mm,lng_mm);
			this.pushMarker(new google.maps.Marker({position:latlng}));
		}
		return true;
	},
	popPoint: function() {
		if (this.points.length==0) {
			this.resetRoute();
			this.point_end=this.point_user;
		} else if (this.points.length==1) {
			this.points.pop();
			for (var i=0;i<this.markers.length;i++) {
				this.popMarker();
			}
			this.point_end=this.point_user;
			this.map.setCenter(this.point_end);
			this.drawRoute();
		} else if (this.points.length==2) {
			this.points.pop();
			this.totaldistance=0;
			for (var i=0;i<this.markers.length;i++) {
				this.popMarker();
			}
			this.point_end=this.point_start;

			this.markers.length=0;
			this.marker_end.setMap(null);
			this.map.setCenter(this.point_end);
		} else {
			var olddistance=this.totaldistance;
			var lastpoint=this.points.pop();
			this.totaldistance=this.totaldistance-this.distPointToPoint(lastpoint,this.points[this.points.length-1]);
			for (i=Math.floor(olddistance);i>Math.floor(this.totaldistance);i--) {
				this.popMarker();
			}
			this.point_end=this.points[this.points.length-1];
			this.map.setCenter(this.point_end);
		}
	},
	pushMarker: function(point) {
		this.markers.push(point);
	},
	popMarker: function() {
		this.markers[this.markers.length - 1].setMap(null);
		this.markers.pop();
	},
	
	
	
	buildRouteFromFormData: function() {
		var pointdata=document.getElementById("routedata").value;
		pointdata = pointdata.replace(/\),\(/g,"X");
		pointdata = pointdata.replace(/\)/g,"");
		pointdata = pointdata.replace(/\(/g,"");
		var pointlist = pointdata.split(/X/g);
		for (i=0;i<pointlist.length;i++) {
			latandlong = pointlist[i].split(",");
			lat = latandlong[0];
			lng = latandlong[1];
			if (lat!=0 || lng!=0) {
				var latlng= new google.maps.LatLng(lat,lng);
				this.pushPoint(latlng);
			}
		}
		this.drawRoute();
	},
	runHome: function() {
		var returnLeg = this.points.slice();
		returnLeg.reverse();
		for (i=0;i<returnLeg.length;i++) {
			this.pushPoint(returnLeg[i]);
		}
		this.drawRoute();
		this.map.setCenter(this.point_end);
	},

	zoomToPostcode: function() {
		var postcode = document.getElementById("postcode").value;
		var request;
		if (window.XMLHttpRequest) {
			request = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		var result;
		request.open('GET', 'routes-ws-postcode-to-lat.php?postcode=' + postcode, true);
		request.onreadystatechange = function() {
			if (request.readyState == 4) {
				var coords = (request.responseText).split("X");
				if (coords[0]!=0 || coords[1]!=0) {
					var newLocation = new google.maps.LatLng(coords[0],coords[1]);
					this.map.setCenter(newLocation);
				} else {
					alert("Postcode not recognised");
				}
			}
		}
		request.send(null);
	},
	getPointSample: function(p,x) {
		var output_array = new Array();
		if (x>=p.length) {
			return p;
		} else {
			var points_to_ditch = p.length - x;
			var ditch = p.length / points_to_ditch;
			if (ditch>1.5) {
				ditch=Math.round(ditch);
				for (var i=0;i<p.length;i++) {
					if (!((i % ditch)==0)) {
						output_array.push(p[i]);
					}
				}
				if (output_array.length>x) {
					output_array = this.getPointSample(output_array,x);
				}
			} else {
				ditch=2;
				for (var i=0;i<p.length;i++) {
					if (!((i % ditch)==0)) {
						output_array.push(p[i]);
					}
				}
				output_array = this.getPointSample(output_array,x);
			}
		}
		return output_array;
	},
	distPointToPoint: function(point1,point2) {
		if (point1.lat()==point2.lat() && point1.lng()==point2.lng()) {
			return 0;
		}
		var radlat1 = Math.PI * point1.lat()/180
		var radlat2 = Math.PI * point2.lat()/180
		var radlon1 = Math.PI * point1.lng()/180
		var radlon2 = Math.PI * point2.lng()/180
		var theta = point1.lng()-point2.lng();
		var radtheta = Math.PI * theta/180
		var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
		dist = Math.acos(dist)
		dist = dist * 180/Math.PI
		dist = dist * 60 * 1.1515
		return dist
	},
	roundDistance: function(x) {
		return Math.round(x*100)/100;
	},
	storeElevationData: function(results,status) {
		if (status == google.maps.ElevationStatus.OK) {
			var output_string='';
			for (var i=0;i<results.length;i++) {
				output_string+=results[i].elevation;
				if (i<(results.length -1)) {
					output_string+=',';
				}
			}
			gm3.postAndForget('/routes-ws-store-elevation-data.php','rid='+ gm3.routeid +'&elevation='+output_string);
		}
	},
	postAndForget:function(url,params) {
		var request;
		if (window.XMLHttpRequest) {
		    request = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
		    request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		request.open("POST", url, true);
		request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		request.setRequestHeader("Content-length", params.length);
		request.setRequestHeader("Connection", "close");
		request.send(params);


		return true;
	}
};
