//
// Various functions for creating a pedometer using Google Maps.
//
// You use this software at your own risk. It shouldn't be used to run
// nuclear power stations or fly aeroplanes.
//
// Written by Simon Buckle (simon@simonbuckle.com) 
//
// Copyright 2005
//

var Codec = {

	// The algorithm for route encoding can be found here:
	// http://www.thrall.net/~mking/maps/points.py
	// I translated it into Javascript.

	encodePoints : function (locations) {
		var points = [];
		var x0 = 0;
		var y0 = 0;

		locations = this.map(function (x) { return Math.round(x / 1.0E-5); }, locations);

		for (var i = 0; i < locations.length / 2; i++) {
			var y = locations[i << 1];
			var dy = y - y0;
			y0 = y;
			var f = (Math.abs(dy) << 1) - (dy < 0);
			while (1) {
				var e = f & 31;
				f >>= 5;
				if (f) 
					e |= 32;
				points.push(String.fromCharCode(e + 63));
				if (f == 0)
					break;
			}
			var x = locations[(i << 1) + 1]
			var dx = x - x0;
			x0 = x;
			f = (Math.abs(dx) << 1) - (dx < 0);
			while (1) {
				var e = f & 31;
				f >>= 5;
				if (f) 
					e |= 32;
				points.push(String.fromCharCode(e + 63));
				if (f == 0)
					break;
			}
		}
		return points.join("");
	},

	decodePoints : function (points) {
		if (!points) 
			return [];
	
		var locations = [];
    	var pb = 0;
		var Ka = 0;
		var Pa = 0;

		while (pb < points.length) {
			var oc = 0;
			var Fa = 0;
			while (1) {
				var ub = points.charCodeAt(pb) - 63;
				pb += 1;
				Fa |= (ub & 31) << oc;
				oc += 5;
				if (ub < 32) 
					break;
			}
			var i;
			if (Fa & 1) 
				i = ~(Fa >> 1);
			else
				i = Fa >> 1;
			Ka += i;
			locations.push(Ka * 1.0E-5);

			oc = 0;
			Fa = 0;
			while (1) {
				var ub = points.charCodeAt(pb) - 63;
				pb += 1;
				Fa |= (ub & 31) << oc;
				oc += 5;
				if (ub < 32) 
					break;
			}
			if (Fa & 1) 
				i = ~(Fa >> 1);
			else
				i = Fa >> 1;
			Pa += i;
			locations.push(Pa * 1.0E-5); 
		}
		return locations;
	},

	map : function (f, a) {
		var results = [];
		for(var i = 0; i < a.length; i++) {
			results[i] = f(a[i]);
		}
		return results;
	}
}


var map;
var routePoints = new Array(0);
var total_distance = 0.0;

var MILES = {
	label : "miles",
	f : function (distance) {
		return distance / 1609.344;
	}
}

var KMS = {
	label: "km",
	f : function (distance) {
			return distance / 1000;
	}
}

var unit_handler = KMS;

function onLoad(x,y,zl) {  
      map = new GMap2(document.getElementById("map"));
      var url = window.location.href.split("?");

      if (url[1]) {
	  	initialiseMapFromURL(window.location.href);
      } else {
	  	// Use the default
	  	map.setCenter(new GLatLng(x, y), zl);
      }

      map.addControl(new GLargeMapControl());
      map.addControl(new GMapTypeControl());
      
      GEvent.addListener(map, "click", function(overlay, point) {
	      if (point) {
		  map.clearOverlays();
		  routePoints.push(point);
		  map.addOverlay(new GPolyline(routePoints));
		  // Add a marker at the beginning and the end
		  map.addOverlay(new GMarker(routePoints[0]));
		  if ( routePoints.length > 1 ) {
		      map.addOverlay(new GMarker(routePoints[routePoints.length - 1]));
		      // Re-calculate the distance so far
		      var lastLeg = point.distanceFrom( routePoints[ routePoints.length - 2 ] );
		      total_distance += lastLeg;	
		      
		      updateDisplay();			
		  }
	      }
	  });
}

function initialiseMapFromURL(url) {
    var url = url.split("?");
    
    if (!url[1]) {
	return null;
    }
    
    var params = new Object();
    var queryStr = url[1].split("&");
    var pattern = /(\w+)=(.+)/;
    var result;
    
    for (var i = 0; i < queryStr.length; i++) {
	if ((result = pattern.exec(queryStr[i])) != null) {
	    var param = result[1];
	    params[param] = decodeURI(result[2]);
	}
    }

    var zoomLevel = parseInt(params.zl);
    // Determine if this permalink was generated using version 1.0
    // of the Google Maps API.
    if (params.v == null) {
	zoomLevel = 17 - zoomLevel;
    }  

    // This MUST be the first call after the map has been initialised
    map.setCenter(new GLatLng(params.y, params.x), zoomLevel);
    
    // Determine the current map type, e.g. map, satellite, hybrid
    var obj;
    if (params.type) {
	switch (params.type) {
	case "1":
	    map.setMapType(G_NORMAL_MAP);
	    break;
	case "2":
	    map.setMapType(G_SATELLITE_MAP);
	    break;
	case "3":
	    map.setMapType(G_HYBRID_MAP);
	    break;
	default:
	    map.setMapType(G_NORMAL_MAP);
	}
    } 
    
    if (params.path) {
	// Returns an array of lat/lon pairs [lat1,lon1,lat2,lon2 ...]
	var path = Codec.decodePoints(params.path);
	var point;
	total_distance = 0;
	for (var i = 0; i < path.length / 2; i++) {
	    point = new GLatLng( path[2*i], path[2*i +1] );
	    if (i > 0) {
		// Calculate the length of the route
		var prev = routePoints[i-1];
		total_distance += point.distanceFrom( prev );
	    }
	    routePoints.push( point );
	}
	map.addOverlay(new GPolyline(routePoints));
	// Add the start/end markers
	map.addOverlay(new GMarker(routePoints[0]));
	map.addOverlay(new GMarker(routePoints[routePoints.length - 1]));
    }
    
    updateDisplay();
}

function updateDisplay () {
    var dist = unit_handler.f(total_distance);
    document.getElementById("distance").value = dist.toFixed(2);
    
    //alert("amount: "+ dist.toFixed(2) + "testing");
    

   
  //////////////////// 
  //ugly hack start//
  //////////////////  
  var calc_dist = dist.toFixed(2);
  
	//alert(calc_dist+"testing");
	
	//calculate fuel costs
	document.getElementById("distance").value = calc_dist;
	
	
	
	var price = (calc_dist/document.getElementById("economy").value)*document.getElementById("price").value;
	var total_cost = (Math.round(price * Math.pow(10, 2)))/ Math.pow(10, 2);
	
	//alert(total_cost );
	
  if( isNaN(total_cost) ){
		alert("You have entered an invalid amount, please try again.");
	}
	else{
		document.getElementById("cost").value = total_cost;
	}
	
	//calculate travel times
	var raw_time = calc_dist/document.getElementById("speed").value;	
	var temp = new Array();
	var time = raw_time.toString();
	temp = time.split('.');
	var hours = (temp[0]*1+0);
	var minutes = '.'+temp[1];
	var minutes = Math.round( ((minutes)*.6)*100 );
	
	if(minutes==60){
		minutes = '0';
		hours = hours + 1;
	}else if(isNaN(minutes) || isNaN(hours) ){
		minutes = 'unknown';
		hours = 'unknown';
	}
	
	travel_time = hours+' hours, '+minutes+' minutes';
	document.getElementById("travel_time").value =  travel_time;
	
	
	
	    // Set the label
    var span = document.getElementById("units");
    span.firstChild.nodeValue = unit_handler.label;
 
   ////////////////// 
  //ugly hack end///
 //////////////////    
} 

function toggleUnits (arg) {
    if (arg == "MILES") 
	unit_handler = MILES;
    else if (arg == "KMS")
	unit_handler = KMS;
    else
	// Revert to the default
	unit_handler = KMS;
    // Refresh
    updateDisplay();
}

// Generates a unique URL for this route
function generatePermalink ( ) {
	
	
	//ugly hack for now - to tidy up later
	var economy = document.getElementById("economy").value;
	var price = document.getElementById("price").value;	
	var speed = document.getElementById("speed").value;
	var distance = document.getElementById("distance").value;
	var cost = document.getElementById("cost").value;
	var travel_time = document.getElementById("travel_time").value;
	var cur = document.getElementById("cur").value;
	
	
	for (i=0;i<document.forms[0].dist.length;i++)
	{
		if (document.forms[0].dist[i].checked)
		{
			var dist = document.forms[0].dist[i].value;
		}
	}
	
	var final = "&economy="+economy+"&price="+price+"&speed="+speed+"&distance="+distance+"&cost="+cost+"&travel_time="+travel_time+"&dist="+dist+"&cur="+cur;
	
    var params = [];
    // grab whatever the existing URL is
    var url = window.location.href.split("?")[0];
    
    var zl = map.getZoom();
    params.push("zl=" + zl);
    
    var center = map.getCenter();
    // Ideally we would call these parameters "lat" and "lng" but we have to maintain
    // backwards compatibility with previously generated permalinks.
    params.push("x=" + center.lng());
    params.push("y=" + center.lat());
    
    var location = [];
    var pt;
    
    for (var i = 0; i < routePoints.length; i++) {
	pt = routePoints[i];
	location.push(pt.y);
	location.push(pt.x);
    }
    
    params.push("path=" + Codec.encodePoints(location));
    
    var type = map.getCurrentMapType();
    // Determine the current map type, e.g. map, satellite, hybrid
    switch (type) {
    case G_NORMAL_MAP:
	t = 1;
	break;
    case G_SATELLITE_MAP:
	t = 2;
	break;
    case G_HYBRID_MAP:
	t = 3;
	break;
    default:
	t = 1;
    }
    
    params.push("type=" + t);
    params.push("v=2");
    
   // url += "?"; 
   // url += params.join("&");	
    
    url = "roadtrip.php?"+params.join("&")+final;
  
    return url;
}


// Clear the last leg
function clearLastLeg ( ) {
    if (routePoints.length < 2)
	return;
    var point = routePoints.pop();
    map.clearOverlays();
    
    // Re-draw
    map.addOverlay(new GPolyline(routePoints));
    
    // Add the start/end markers
    map.addOverlay(new GMarker(routePoints[0]));
    map.addOverlay(new GMarker(routePoints[routePoints.length - 1]));	
    
    // Re-calculate the total distance
    total_distance = total_distance - point.distanceFrom(routePoints[routePoints.length - 1]);

    updateDisplay();
}

// Clears the existing route
function clearRoute ( ) {
    routePoints = [];
    map.clearOverlays();
    total_distance = 0.00;
    // Refresh the distance field
    updateDisplay();
}

function generateURL ( ) {
    var url = generatePermalink();
    // Reload the document
    //alert(url);
    window.location = url;	
}

function generateTinyURL ( ) {
    document.getElementById("TinyURL").value = generatePermalink();
    document.tinyURLform.submit();
}

function popUp(node){
 window.open('popup.php?help='+node,'child','top=20,left=10,width=225,height=250,scrollbar=yes,resizable=yes');
}
 
function bookMark(){ 
	
	var website = "http://route-planner.org";
	var title = "Route Planner";
	
	window.status="Bookmark "+website;
	
	if (window.sidebar) {
		window.sidebar.addPanel(title, website,"");
	}
	else if(window.external) {
		window.external.AddFavorite(website, title);
	}
	else if(window.opera && window.print) {
		alert('Please click ctrl+D on your keyboard to bookmark this site');
		return true;
	}
	
	
}



