
var localSearch = new GlocalSearch();

var map;
var bounds;
var autopan;
var routePoints=new Array(0);
var colour="#cc0000";
var total_distance=0;
var togglemarkers=1;
var lineWidth=5;
var lineColor='#ff0066';
var lines=[];
var degreesPerRadian=180.0/Math.PI;
var radiansPerDegree=Math.PI/180.0
var earthRadiusMeters=6367460.0;
var metersPerDegree=2.0*Math.PI*earthRadiusMeters/360.0;
var EARTH_RADIUS=6367000;

var MILES=
{
	label:"miles",
	f:function(distance)
	{
		return distance/1609.344;
	}
}
var KMS=
{
	label:"km",
	f:function(distance)
	{
		return distance/1000;
	}
}

var NMILES={
label:"nautical miles",
f:function(distance){
return ((distance/1609.344)*(1/1.150779));
}
}

var unit_handler=MILES;

function Gload()
{
	map = new GMap2(document.getElementById("map"),{draggableCursor: 'crosshair', draggingCursor: 'pointer'});
	map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());
	map.setCenter(new GLatLng(0,0),1);
	map.addControl(new GScaleControl(256));
	bounds = new GLatLngBounds();
	autopan=document.getElementById("autopan").checked;
	GEvent.addListener(map,"click",function(overlay,point)
	{
		if(point)
		{
			routePoints.push(point);
			redraw();
			if (autopan==true)
			{
				map.panTo(point);
			}
			updateDisplay();
		}
	});
}



//toggle markers on or off on the map
function togglemarkersbtn()
{
	//If they are on
	if (togglemarkers==1)
	{
		togglemarkers=0;
		redraw();
	}
	else
	//If thety are off
	{
		togglemarkers=1;
		redraw();
	}
}

function autopantoggle(state)
{
	autopan=state;
}

function redraw()
{
	map.clearOverlays();
	total_distance=0;
	
	bounds = null;
    bounds = new GLatLngBounds(); 
	
	for(var j=0;j<routePoints.length;++j)
	{
		bounds.extend(routePoints[j]);
		if (togglemarkers==1)
		{
			map.addOverlay(createMarker(routePoints[j], j));
		}
		if (j>0)
		{
			var lat1=routePoints[j].lat();
			var long1=routePoints[j].lng();
			var lat2=routePoints[j-1].lat();
			var long2=routePoints[j-1].lng();
			total_distance+=((LatLon.distHaversine(lat1,long1,lat2,long2).toPrecision(4))*1000);
AddPolylines(lines,GreatCirclePoints(routePoints[routePoints.length-j],routePoints[routePoints.length-1-j]),lineColor,lineWidth);
		}
	}
}

function createMarker(point, number) 
{
	var marker=new GMarker(point,{draggable:true});
	
	GEvent.addListener(marker,"click",function()
	{
		routePoints.push(point);
		redraw();
		updateDisplay();
	});
	
	GEvent.addListener(marker,"dragend",function()
	{
		routePoints[number]=marker.getLatLng();
		redraw();
		updateDisplay();
	});	
	return marker;
}

function usePointFromPostcode(postcode, callbackFunction) 
{
	localSearch.setSearchCompleteCallback(null, 
	function() 
	{
		if (localSearch.results[0])
		{		
			var resultLat = localSearch.results[0].lat;
			var resultLng = localSearch.results[0].lng;
			var point = new GLatLng(resultLat,resultLng);
			callbackFunction(point);
		}
	});	
	localSearch.execute(postcode);
}

function placeMarkerAtPoint(point)
{
	setCenterToPoint(point);
}

function setCenterToPoint(point)
{
	map.setCenter(point, 10);
}

function clearLastLeg()
{
	if(routePoints.length<2)
	return;
	bounds = new GLatLngBounds();
	routePoints.pop();
	redraw();
	updateDisplay();
}

function clearMap()
{
	total_distance=0.00;
	bounds = new GLatLngBounds();
	routePoints=[];
	map.clearOverlays();
	updateDisplay();
}

function statert()
{
	alert(document.getElementById("rjour").checked);
}

function updateDisplay()
{
	var dist=unit_handler.f(total_distance);
	document.getElementById("distance").value=dist.toFixed(3);
}

function toggleUnits(arg)
{
	if(arg=="MILES")
	unit_handler=MILES;
	if(arg=="KMS")
	unit_handler=KMS;
	if(arg=="NMILES")
	unit_handler=NMILES;
	
	updateDisplay();
}

function calculateDistance(points)
{
	if(points.length<2)
	return 0;
	var dist=0.0;
	for(var i=0;i<points.length-1;i++)
	{
		dist+=distance_between_points(points[i],points[i+1]);
	}
	return dist;
}

Math.deg2rad=function(x)
{
	return x*(Math.PI/180.0);
}


function distance_between_points(p1,p2)
{
	var a=Math.deg2rad(90-p1.y);
	var b=Math.deg2rad(90-p2.y);
	var theta=Math.deg2rad(p2.x-p1.x);
	var c=Math.acos(Math.cos(a)*Math.cos(b)+Math.sin(a)*Math.sin(b)*Math.cos(theta));
	return c*EARTH_RADIUS;
}

function toggleReturn()
{
	if((document.getElementById("rjour").checked)==true)
	{
		total_distance*=2;
	}
	if((document.getElementById("rjour").checked)==false)
	{
		total_distance/=2;
	}
	updateDisplay();
}

function zoomtofitall(map)
{
	map.setZoom(map.getBoundsZoomLevel(bounds)-1);
	var clat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) /2;
	var clng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) /2;
	map.setCenter(new GLatLng(clat,clng));
}

function ZoomOut()
{
	 zoomtofitall(map)
}





function x_half_distance_between_points(p1,p2){
var a=p2.y+p1.y;
return a/2;
}
function y_half_distance_between_points(p1,p2){
var a=p2.x+p1.x;
return a/2;
}
function disHalf(){
var hwc=GreatCirclePoints(routePoints[routePoints.length-2],routePoints[routePoints.length-1]).length;
var midpc=Math.ceil(hwc/2);
var midpf=Math.floor(hwc/2);
var pointsc=[];
var pointsf=[];
points=GreatCirclePoints(routePoints[routePoints.length-2],routePoints[routePoints.length-1]);
var xh=x_half_distance_between_points(points[midpc],points[midpf]);
var yh=y_half_distance_between_points(points[midpc],points[midpf]);
var hwp=new GPoint(yh,xh);
var marker3=new GMarker(hwp);
map.addOverlay(marker3);
}
function AddPolylines(lines,ps,lineColor,lineWidth)
{
var line=new GPolyline(ps,lineColor,lineWidth);
lines.push(line);
map.addOverlay(line);
}
function GreatCirclePoints(p1,p2)
{
var maxDistanceMeters=200000.0;
var ps=[];
if(p1.distanceFrom(p2)<=maxDistanceMeters)
{
ps.push(p1);
ps.push(p2);
}
else
{
var theta1=p1.lng()*radiansPerDegree;
var phi1=(90.0-p1.lat())*radiansPerDegree;
var x1=earthRadiusMeters*Math.cos(theta1)*Math.sin(phi1);
var y1=earthRadiusMeters*Math.sin(theta1)*Math.sin(phi1);
var z1=earthRadiusMeters*Math.cos(phi1);
var theta2=p2.lng()*radiansPerDegree;
var phi2=(90.0-p2.lat())*radiansPerDegree;
var x2=earthRadiusMeters*Math.cos(theta2)*Math.sin(phi2);
var y2=earthRadiusMeters*Math.sin(theta2)*Math.sin(phi2);
var z2=earthRadiusMeters*Math.cos(phi2);
var x3=(x1+x2)/2.0;
var y3=(y1+y2)/2.0;
var z3=(z1+z2)/2.0;
var r3=Math.sqrt(x3*x3+y3*y3+z3*z3);
var theta3=Math.atan2(y3,x3);
var phi3=Math.acos(z3/r3);
var p3=new GLatLng(90.0-phi3*degreesPerRadian,theta3*degreesPerRadian);
var s1=GreatCirclePoints(p1,p3);
var s2=GreatCirclePoints(p3,p2);
for(var i=0;i<s1.length;++i)
ps.push(s1[i]);
for(var i=1;i<s2.length;++i)
ps.push(s2[i]);
}
return ps;
}
LatLon.distHaversine=function(lat1,lon1,lat2,lon2){
var R=6371;
var dLat=(lat2-lat1).toRad();
var dLon=(lon2-lon1).toRad();
lat1=lat1.toRad(),lat2=lat2.toRad();
var a=Math.sin(dLat/2)*Math.sin(dLat/2)+
Math.cos(lat1)*Math.cos(lat2)*
Math.sin(dLon/2)*Math.sin(dLon/2);
var c=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
var d=R*c;
return d;
}
LatLon.distCosineLaw=function(lat1,lon1,lat2,lon2){
var R=6371;
var d=Math.acos(Math.sin(lat1.toRad())*Math.sin(lat2.toRad())+
Math.cos(lat1.toRad())*Math.cos(lat2.toRad())*Math.cos((lon2-lon1).toRad()))*R;
return d;
}
LatLon.bearing=function(lat1,lon1,lat2,lon2){
lat1=lat1.toRad();lat2=lat2.toRad();
var dLon=(lon2-lon1).toRad();
var y=Math.sin(dLon)*Math.cos(lat2);
var x=Math.cos(lat1)*Math.sin(lat2)-
Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
return Math.atan2(y,x).toBrng();
}
LatLon.midPoint=function(lat1,lon1,lat2,lon2){
lat1=lat1.toRad();
lat2=lat2.toRad();
var dLon=(lon2-lon1).toRad();
var Bx=Math.cos(lat2)*Math.cos(dLon);
var By=Math.cos(lat2)*Math.sin(dLon);
lat3=Math.atan2(Math.sin(lat1)+Math.sin(lat2),
Math.sqrt((Math.cos(lat1)+Bx)*(Math.cos(lat1)+Bx)+By*By));
lon3=lon1.toRad()+Math.atan2(By,Math.cos(lat1)+Bx);
if(isNaN(lat3)||isNaN(lon3))return null;
return new LatLon(lat3.toDeg(),lon3.toDeg());
}
LatLon.prototype.destPoint=function(brng,d){
var R=6371;
var lat1=this.lat.toRad(),lon1=this.lon.toRad();
brng=brng.toRad();
var lat2=Math.asin(Math.sin(lat1)*Math.cos(d/R)+
Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng));
var lon2=lon1+Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1),
Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
if(isNaN(lat2)||isNaN(lon2))return null;
return new LatLon(lat2.toDeg(),lon2.toDeg());
}
LatLon.prototype.finalBrng=function(brng,d){
var p1=this,p2=p1.destPoint(brng,d);
var rev=LatLon.bearing(p2.lat,p2.lon,p1.lat,p1.lon);
var rev=(rev+180)%360;
return rev;
}
LatLon.distRhumb=function(lat1,lon1,lat2,lon2){
var R=6371;
var dLat=(lat2-lat1).toRad(),dLon=Math.abs(lon2-lon1).toRad();
var dPhi=Math.log(Math.tan(lat2.toRad()/2+Math.PI/4)/Math.tan(lat1.toRad()/2+Math.PI/4));
var q=dLat/dPhi;
if(!isFinite(q))q=Math.cos(lat1.toRad());
if(dLon>Math.PI)dLon=2*Math.PI-dLon;
var d=Math.sqrt(dLat*dLat+q*q*dLon*dLon);
return d*R;
}
LatLon.brngRhumb=function(lat1,lon1,lat2,lon2){
var dLon=(lon2-lon1).toRad();
var dPhi=Math.log(Math.tan(lat2.toRad()/2+Math.PI/4)/Math.tan(lat1.toRad()/2+Math.PI/4));
if(Math.abs(dLon)>Math.PI)dLon=dLon>0?-(2*Math.PI-dLon):(2*Math.PI+dLon);
return Math.atan2(dLon,dPhi).toBrng();
}
LatLon.prototype.destPointRhumb=function(brng,dist){
var R=6371;
var d=parseFloat(dist)/R;
var lat1=this.lat.toRad(),lon1=this.lon.toRad();
brng=brng.toRad();
lat2=lat1+d*Math.cos(brng);
var dPhi=Math.log(Math.tan(lat2/2+Math.PI/4)/Math.tan(lat1/2+Math.PI/4));
var q=(lat2-lat1)/dPhi;
if(!isFinite(q))q=Math.cos(lat1);
var dLon=d*Math.sin(brng)/q;
if(Math.abs(lat2)>Math.PI/2)lat2=lat2>0?Math.PI-lat2:-Math.PI-lat2;
lon2=(lon1+dLon+Math.PI)%(2*Math.PI)-Math.PI;
if(isNaN(lat2)||isNaN(lon2))return null;
return new LatLon(lat2.toDeg(),lon2.toDeg());
}
function LatLon(lat,lon){
this.lat=lat;
this.lon=lon;
}
LatLon.prototype.toString=function(){
return this.lat.toLat()+', '+this.lon.toLon();
}
String.prototype.parseDeg=function(){
if(!isNaN(this))return Number(this);
var degLL=this.replace(/^-/,'').replace(/[NSEW]/i,'');
var dms=degLL.split(/[^0-9.,]+/);
for(var i in dms)if(dms[i]=='')dms.splice(i,1);
switch(dms.length){
case 3:
var deg=dms[0]/1+dms[1]/60+dms[2]/3600;break;
case 2:
var deg=dms[0]/1+dms[1]/60;break;
case 1:
if(/[NS]/i.test(this))degLL='0'+degLL;
var deg=dms[0].slice(0,3)/1+dms[0].slice(3,5)/60+dms[0].slice(5)/3600;break;
default:return NaN;
}
if(/^-/.test(this)||/[WS]/i.test(this))deg=-deg;
return deg;
}
Number.prototype.toRad=function(){
return this*Math.PI/180;
}
Number.prototype.toDeg=function(){
return this*180/Math.PI;
}
Number.prototype.toBrng=function(){
return(this.toDeg()+360)%360;
}
Number.prototype.toDMS=function(){
var d=Math.abs(this);
d+=1/7200;
var deg=Math.floor(d);
var min=Math.floor((d-deg)*60);
var sec=Math.floor((d-deg-min/60)*3600);
if(deg<100)deg='0'+deg;if(deg<10)deg='0'+deg;
if(min<10)min='0'+min;
if(sec<10)sec='0'+sec;
return deg+'\u00B0'+min+'\u2032'+sec+'\u2033';
}
Number.prototype.toLat=function(){
return this.toDMS().slice(1)+(this<0?'S':'N');
}
Number.prototype.toLon=function(){
return this.toDMS()+(this>0?'E':'W');
}
Number.prototype.toPrecision=function(fig){
if(this==0)return 0;
var scale=Math.ceil(Math.log(this)*Math.LOG10E);
var mult=Math.pow(10,fig-scale);
return Math.round(this*mult)/mult;
}

