// Global variables



var mapdiv = document.getElementById("map");
var map;
var poly;
var polyLines = new Array();
var count = 0;
var points = new Array();
var markers = new Array();
var streetCoords = new Array();
var icon_url ="http://labs.google.com/ridefinder/images/";
var tooltip;
var lineColor = "#6666af";
var normalColor = "#FF0000";
var normalTextColor = "#000000";
var gpsColor = "#000000";
var gpsColors = ["#FF0000","#00FF00","#0000FF","#555555"];
var hiliteColor = "#0000FF";
var fillColor = "#335599";
var editColor = "#FF00FF";
var hilite;
var lineWeight = 3;
var lineOpacity = .5;
var fillOpacity = .2;
var report= document.getElementById("status");
var previousHiliteId = -1;
var backupCoords = null;
var dateString = "";
var KMLCache = new Array();
var avgPoint = new Array();
var GPSFiles = new Array();
var infoShowing = false;

var hilitePolyStyleOptions = {color: hiliteColor , opacity: .8};
var normalPolyStyleOptions = {color: normalColor, opacity: lineOpacity};
var editPolyStyleOptions = {color: editColor, opacity: lineOpacity};

var editPoly = null;

var editId = -1;
var lastMapType = "roadmap";

var showMap = true;

var totalMiles = 0.0;
var totalKilometers = 0.0;

 function getUrlVars() {
	var vars = {};
	var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
		vars[key] = value;
	});
	return vars;
}


function prettyFilename(f) {
	
	noSuffix = f.substring(0,f.length-4);
	return noSuffix.replace(/_/g, " ");


}

function getVariable(q,s) {
    s = (s) ? s : window.location.search;
    var re = new RegExp('&amp;'+q+'=([^&amp;]*)','i');
    return (s=s.replace(/^\?/,'&amp;').match(re)) ?s=s[1] :s='';
}


function getHashParam() {
	s = location.href;
	idx = s.search("#");
	if (idx == -1) return null;
	return(s.substr(idx+1,s.length));
}



function downloadUrl(url,callback) {
 var request = window.ActiveXObject ?
     new ActiveXObject('Microsoft.XMLHTTP') :
     new XMLHttpRequest;

 request.onreadystatechange = function() {
   if (request.readyState == 4) {
     callback(request.responseText, request.status);
     request.onreadystatechange = -1;
   }
 };

 request.open('GET', url, true);
 request.send(null);
}






function loadGPS() {
	
	var url='http://'+domain+'/kml.php';
		
	downloadUrl(url, function(data,status) {
	
		if (status != 200) return;
		if (data == "") return;
		var fileRows = data.split("\n");
		files = "";
		lookup = new Array();
	 	for (var j = 0; j < fileRows.length; j++) {

			if (fileRows[j] == "") continue;
			f = fileRows[j];
			files += "<input type=checkBox id=check_"+j+" onChange=\"toggleVisible('" + f + "',"+j+")\"><a href=\"#"+ f.substr(0,f.length-4) +"\" onClick=\"loadKML('" + f + "'," + j +")\">"+prettyFilename(f)+"</a><br>";
			lookup[f] = j;
			GPSFiles[j] = f;
			numGPS = j+1;
		}
				
		document.getElementById("gpsPanel").innerHTML = files;

		//toggleInfo();
		vars = getUrlVars();
		kml = getHashParam();
		kmlfile = kml + ".kml";
		if (kml != null && lookup[kmlfile] != null) {
			loadKML(kmlfile,lookup[kmlfile]);
		}
	});	   		
}


//TRIM FUNCTIONS FROM http://www.somacon.com/p355.php
function trim(stringToTrim) {
	return stringToTrim.replace(/^\s+|\s+$/g,"");
}
function ltrim(stringToTrim) {
	return stringToTrim.replace(/^\s+/,"");
}
function rtrim(stringToTrim) {
	return stringToTrim.replace(/\s+$/,"");
}


function toggleVisible(filename,row) {
	
	var checked = (document.getElementById("check_" + row).checked == true);

	if (KMLCache[filename] == null) {
		if (checked) {
			loadKML(filename,-1);
		}
		return;
	}
	if (checked) {
		KMLCache[filename].setMap(map);
  		map.panTo(avgPoint[filename]);
	} else {
		KMLCache[filename].setMap(null);
	}
}


function loadKML(filename,r) {

	if (r != -1) {
	  		for (var j = 0; j < numGPS; j++) {
  				if (j != r) {
  					document.getElementById("check_" + j).checked = false;
  					toggleVisible(GPSFiles[j],j);
  				} else {
  				  document.getElementById("check_" + j).checked = true;
  				}
  			}
		}	

	if (KMLCache[filename] != null) {
		KMLCache[filename].setMap(map);
		map.panTo(avgPoint[filename]);
		return;
	}

	var url='http://'+domain+'/kml/' + filename;
	downloadUrl(url, function(data,status) {
	
		if (status != 200) return;
		if (data == "") return;
		var KMLRows = data.split("\n");
		var row;
		
		var points = [];
		var grabbing = false;
		var numPoints = 0;
		
		var avgLat = 0;
		var avgLon = 0;
		var shade = 0;
	 	for (var j = 0; j < KMLRows.length; j++) {

			row = trim(KMLRows[j]);
			
			if (row == "</coordinates>") {
				grabbing = false;
			
			}
			
			if (grabbing) {
				coords = row.split(",");
				points[numPoints] = new google.maps.LatLng(coords[1], coords[0]);
				avgLat += parseFloat(coords[1]);
				avgLon += parseFloat(coords[0]);
				numPoints++;
			}
		if (row == "<coordinates>") {
			grabbing = true; 
			shade++;
			}
			
		}
		avgLat = avgLat / numPoints;
		avgLon = avgLon / numPoints;
		
 		var newPoly;
   
 	 	var streetPath = new google.maps.Polyline({
    		path: points,
   			strokeColor: gpsColor,
    		strokeOpacity: 1,
    		strokeWeight: 4
  		});
  		KMLCache[filename] = streetPath;
  		streetPath.setMap(map);
  		 
  		avgPoint[filename] = new google.maps.LatLng(avgLat, avgLon)
  		map.panTo(avgPoint[filename]);
  		
	});	   




}


function loadStreets() {
	
	var before = getVariable("before");
	var url='http://'+domain+'/data.php';
		
	if (before != null) {
		url = url + "?before=" + before;
	}
	
	downloadUrl(url, function(data,status) {
	
		if (status != 200) return;
		if (data == "") return;
		var streetRows = data.split("\n");
		dateString = streetRows[0];

	 	for (var j = 1; j < streetRows.length; j++) {

			if (streetRows[j]=="") continue;
			var streetFields = streetRows[j].split("|");
			var coords = JSON.parse(streetFields[2]);
			totalKilometers += getTotalLength(coords);
			var streetId = streetFields[0];
			var streetName = streetFields[1];
			drawStreet(streetId, streetName, coords, 0);
			
			if (numRecent != 0 && j > (streetRows.length-numRecent)) {
				drawStreet(streetId, streetName, coords, 1);
			}
		}
	
		writeInfoPanel();
		
	});	   		
}



function rad(x) {
	return x*Math.PI/180.0;
}

function distHaversine(lat1, lon1, lat2, lon2) {
  var R = 6371.4; // earth's mean radius in km 
  var dLat  = rad(lat2 - lat1);
  var dLong = rad(lon2 - lon1);

  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(rad(lat1)) * Math.cos(rad(lat2)) * Math.sin(dLong/2) * Math.sin(dLong/2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  var d = R * c;

  return d;
}


function calculateDistance(lat1, lon1, lat2, lon2) {

		//var miledistance = glatlng1.distanceFrom(glatlng2, 3959);
	var kmdistance = distHaversine(lat1, lon1, lat2, lon2);
	
	return kmdistance;
 
}

function getTotalLength(coords) {

total = 0.0;



for (i = 0; i < coords.length; i++) {
	currentLat = coords[i].y;
	currentLon = coords[i].x;
	
	if (i != 0) {
		total = total + calculateDistance(currentLat, currentLon, previousLat, previousLon);
	}
	
	previousLat = currentLat;
	previousLon = currentLon;

}

	return total;

}

function constructStreets(text) {



	
	
}


function toggleInfo() {
	
	infoShowing = !infoShowing;
	
	if (infoShowing) {
		document.getElementById("infoPanel").style.height = "";
		document.getElementById("triangle").src = "triangle_down.gif";
	} else {
		document.getElementById("infoPanel").style.height = "1em";
		document.getElementById("triangle").src = "triangle_right.gif";
	}
}


function writeInfoPanel() {


	totalMiles = totalKilometers / 1.609344;
	infoString = "<a href=\"#\" id=coverage onClick=\"toggleInfo()\"><img src=triangle_right.gif id=triangle>Coverage: " 
	+ totalKilometers.toFixed(0) + " km </a><br><input type=checkbox onclick=hideMap() checked id=showMapCheck>Show Google Data<br> First data: " + startDateString +
	"<br>Last data: " + dateString + "<div id=gps></div>";
	document.getElementById("statsPanel").innerHTML = infoString;

	document.getElementById("infoPanel").style.height = "1em";
	document.getElementById("infoPanel").style.display = "block";

}



function addStreetListing(id, street) {
	
	streets = document.getElementById("streets");
	streets.innerHTML += "<div id=street" + id + " onClick=\"editStreet(" + id + ")\" onMouseOver=\"hiliteStreet(" + id + ")\">" + street + "</div>";

}






function clearHilite(id) {
	
	document.getElementById("status").value = id;
	
	if (id != -1) {
		polyLines[id].setStrokeStyle(normalPolyStyleOptions);
	  document.getElementById("street"+id).style.color = "";
	  document.getElementById("street"+id).style.fontWeight = "";	  
	}
	
}


function editStreet(id, discard ) {
	
	if (editPoly != null) {
		editPoly.disableEditing();
		clearHilite(editPoly.streetId);
		if (discard) {
			map.removeOverlay(polyLines[editPoly.streetId]);
			editPoly = null;
		}
	}
	
	if (id==null) return;

	editPoly =  polyLines[id];
	backupCoords = streetCoords[editPoly.streetId];
	editPoly.setStrokeStyle(editPolyStyleOptions);
	document.getElementById("street"+id).style.color = editColor;
	document.getElementById("street"+id).style.fontWeight = "Bold";	
	document.getElementById("streetName").value = editPoly.streetName;
	editPoly.enableEditing();
	editId = id;

}


function hiliteStreet(id) {

	if (editPoly != null && editPoly.streetId == id) return;
	if (editPoly == null || editPoly.streetId != previousHiliteId) {
		clearHilite(previousHiliteId);
	}
	
	polyLines[id].setStrokeStyle(hilitePolyStyleOptions);
  document.getElementById("street"+id).style.color = hiliteColor;
  document.getElementById("street"+id).style.fontWeight = "Bold";	  
  
  previousHiliteId = id;
  
}


function clearStreet() {


 points.length = 0;
 
 
 for (i = 0; i < markers.length; i++) {
 	map.removeOverlay(markers[i]);
 }
 
 
 markers.length = 0;
 count = 0;
 if(poly) { map.removeOverlay(poly); }
 poly = null;
 
}




function drawStreet(id, name, coords, hilite){
 
 var points = [];
 var newPoly;
  
 for (var c = 0; c < coords.length; c++) {
 	points[c] = new google.maps.LatLng(coords[c].y, coords[c].x);
 
 }
   
   var theColor = normalColor;
   if (hilite == 1) theColor = hiliteColor;
   
   
  var streetPath = new google.maps.Polyline({
    path: points,
    strokeColor: theColor,
    strokeOpacity: lineOpacity,
    strokeWeight: lineWeight
  });

  streetPath.setMap(map);
}


	var coordinateMapType;
	

function buildMap() {

	var latlng = new google.maps.LatLng(startLat, startLon);

	function CoordMapType() {}

CoordMapType.prototype.tileSize = new google.maps.Size(256,256);
CoordMapType.prototype.maxZoom = 19;

	CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
 	 var div = ownerDocument.createElement('DIV');
 	 //div.innerHTML = coord;
 	 div.style.width = this.tileSize.width + 'px';
   	 div.style.height = this.tileSize.height + 'px';
 	 div.style.fontSize = '10';
 	 div.style.borderStyle = 'none';
 	 div.style.backgroundColor = '#FFFFFF';
 	 return div;
	};

	CoordMapType.prototype.name = "None";
	 coordinateMapType = new CoordMapType();

    var myOptions = {
      zoom: 13,
      center: latlng,
      mapTypeControlOptions: {
      mapTypeIds: new Array(google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.TERRAIN)
    },
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    
    
 	map = new google.maps.Map(document.getElementById("map"), myOptions);


  map.mapTypes.set('coordinate',coordinateMapType);

 // map.setMapTypeId('coordinate');


 








google.maps.event.trigger(map, "zoom_changed");


google.maps.event.addListener(map, "maptypeid_changed", function () {

		if (map.getMapTypeId()=="satellite") {
		 	map.mapTypes[map.getMapTypeId()].minZoom = 1;
    	map.mapTypes[map.getMapTypeId()].maxZoom = 20;
		} else if (map.getMapTypeId()=="terrain") {
		 	map.mapTypes[map.getMapTypeId()].minZoom = 4;
    	map.mapTypes[map.getMapTypeId()].maxZoom = 15;
		} else {
			map.mapTypes[map.getMapTypeId()].minZoom = 4;
    	map.mapTypes[map.getMapTypeId()].maxZoom = 17;
		}
   
		
		if (map.getMapTypeId() != "coordinate") {
			lastMapType = map.getMapTypeId();
			document.getElementById("showMapCheck").checked = true;
   	}
   google.maps.event.trigger(map, "zoom_changed");

});
 
 loadStreets();
 loadGPS();

}




function toggleMode() {

 if(markers.length > 1) drawOverlay();
}



function hideMap() {
		
		showMap = document.getElementById("showMapCheck").checked;
	  if (!showMap)  {
			map.setMapTypeId('coordinate')
		} else {
			map.setMapTypeId(lastMapType)
		}
}





function drawOverlay(){

 // Check radio button
// var lineMode = document.forms["f"].elements["mode"][0].checked;
var lineMode = true;

 if(poly) { map.removeOverlay(poly); }
 points.length = 0;

 for(i = 0; i < markers.length; i++) {
  points.push(markers[i].getLatLng());
 }
 if(lineMode) {
   // Polyline mode
   poly = new GPolyline(points, lineColor, lineWeight, lineOpacity);
   var length = poly.getLength()/1000;
   var unit = " km";
   //report.innerHTML = "Total line length:<br> " + length.toFixed(3) + unit;
  }
  else {
   // Polygon mode
   points.push(markers[0].getLatLng());
   poly = new GPolygon(points, lineColor, lineWeight, lineOpacity, fillColor, fillOpacity);
   var area = poly.getArea()/(1000*1000);
   var unit = " km&sup2;";
  // report.innerHTML = "Area of polygon:<br> " + area.toFixed(3) + unit;
  }
  map.addOverlay(poly);
}


function clearMap() {

 // Clear current map and reset arrays
 map.clearOverlays();
 points.length = 0;
 markers.length = 0;
 count = 0;
}
