// JavaScript Document

//************ Global variables ************//

// Google objects
var gMap;
var gMapBounds;
var trafficOptions;
var trafficInfo;

// files
//var srcDoNotEnterSign = "../_images/TAG/DoNotEnter10x10.png";

// Non Google objects
var rcIcon;
var rcIcon2;
var crStartIcon;
var crFinishIcon;
var alertIcon;
var poiIcon;
var parkingIcon;
var event_id;    
var name;
var description;
var gpInFocus;
var roadClosure = new Array();
var detourRoute = new Array();

//------------------------------------------//

//************ Initializing Function ************//

function initializeGMap() {
// get height of viewable area within browser
//	var mapDivHeight = getMapCanvasHeight() - 150;  //leave space for footer
//	document.getElementById("map_canvas").style.height=mapDivHeight+"px"; // change height of map accordingly

	// get height of viewable area within browser
	//resizeMap();

	if (GBrowserIsCompatible()) {

		// initialize map
		gMap = new GMap2(document.getElementById("map_canvas"));	
		//gMap.setCenter(new GLatLng(34.07348, -118.24017), 15);
		gMap.setCenter(new GLatLng(marathonCenterLat, marathonCenterLng), 14);
		//gMap.setCenter(new GLatLng(34.01664, -118.50120), 14);	
		gMap.setUIToDefault();


		// initialize marker icons
		rcIcon = new GIcon();
		rcIcon.shadow = "_images/TAG/DoNotEnter10x10.png";
		rcIcon.iconSize = new GSize(10, 10);
		rcIcon.shadowSize = new GSize(10, 10);
		rcIcon.iconAnchor = new GPoint(5, 1);
		rcIcon.infoWindowAnchor = new GPoint(5, 9);
		
		crStartIcon = new GIcon();
		crStartIcon.shadow = "_images/TAG/LAMarathonStart.png";
		crStartIcon.iconSize = new GSize(77, 10);
		crStartIcon.shadowSize = new GSize(77, 10);
		crStartIcon.iconAnchor = new GPoint(38, 1);
		crStartIcon.infoWindowAnchor = new GPoint(38,9);
		
		crFinishIcon = new GIcon();
		crFinishIcon.shadow = "_images/TAG/LAMarathonEnd.png";
		crFinishIcon.iconSize = new GSize(77, 10);
		crFinishIcon.shadowSize = new GSize(77, 10);
		crFinishIcon.iconAnchor = new GPoint(38, 1);
		crFinishIcon.infoWindowAnchor = new GPoint(38,9);		

		alertIcon = new GIcon();
		alertIcon.shadow = "_images/TAG/alert_icon.png";
		alertIcon.iconSize = new GSize(13, 13);
		alertIcon.shadowSize = new GSize(13, 13);
		alertIcon.iconAnchor = new GPoint(7, 1);
		alertIcon.infoWindowAnchor = new GPoint(7,12);		

		poiIcon = new GIcon();
		poiIcon.shadow = "_images/TAG/poi_icon.png";
		poiIcon.iconSize = new GSize(13, 13);
		poiIcon.shadowSize = new GSize(13, 13);
		poiIcon.iconAnchor = new GPoint(7, 1);
		poiIcon.infoWindowAnchor = new GPoint(7,12);
		
		parkingIcon = new GIcon();
		parkingIcon.shadow = "_images/TAG/pkg_icon.png";
		parkingIcon.iconSize = new GSize(15, 15);
		parkingIcon.shadowSize = new GSize(15, 15);
		parkingIcon.iconAnchor = new GPoint(8, 1);
		parkingIcon.infoWindowAnchor = new GPoint(8,14);

		// load Google traffic layer
		//trafficOptions = {incidents:true};
		//trafficInfo = new GTrafficOverlay(trafficOptions);
		//gMap.addOverlay(trafficInfo);
		
		//load roadclosures and routes from the db
		name = "LA Marathon";
		event_id = 2;
		LoadRoadClosures();
		LoadRoutes();
		
		//load course route start & end
		loadCourseStartEnd();
		
		//load map legend
		gMap.addControl(new MapLegend());

//		var listenerMapResize = GEvent.addListener(gMap, "zoomend", function(oldLevel, newLevel) {
//			resizeMap();
//		});
	}
}



function getMapCanvasHeight() {

	//get height of viewable area within browser
	var mapCanvasHeight;

	// all except Explorer
	if(self.innerHeight) // all except Explorer
	{
		mapCanvasHeight = self.innerHeight;
	}

	// Explorer 6 Strict Mode
	else if (document.documentElement && document.documentElement.clientHeight)
	{
		mapCanvasHeight = document.documentElement.clientHeight;
	}

	// ohter Explorers
	else
	{
		mapCanvasHeight = document.body.clientHeight;
	}
	return mapCanvasHeight;
}


function panToStartFinishLine(type){
	if(type)
	{
		gMap.panTo(new GLatLng(34.07348, -118.24017));

		gmStartLine.openInfoWindowHtml("<div class=\"infoWinContainer\"><div class=\"infoWinTitleDiv\"><span class=\"txtInfoWinTitle\">Start Line and Expo</span></div><div class=\"txtInfoWinDesc\">Dodger Stadium<br><br>Expo at the Start Line: Friday, March 19th, through Saturday, March 20th.<br>Start Line on Race Day, March 21st.</div><div class=\"txtInfoWinSource\">Source:&nbsp;<a id=\"txtInfoWinSource\">LA Marathon, LLC</a></div><div class=\"txtInfoWinCommuteramaFooter\">Powered by Commuterama.com</div></div>");
	}
	
	else
	{
		gMap.panTo(new GLatLng(34.014033, -118.498016));
		
		gmFinishLine.openInfoWindowHtml("<div class=\"infoWinContainer\"><div class=\"infoWinTitleDiv\"><span class=\"txtInfoWinTitle\">Finish Line</span></div><div class=\"txtInfoWinDesc\">Ocean Av and Santa Monica Bl in the City of Santa Monica</div><div class=\"txtInfoWinSource\">Source:&nbsp;<a id=\"txtInfoWinSource\">LA Marathon, LLC</a></div><div class=\"txtInfoWinCommuteramaFooter\">Powered by Commuterama.com</div></div>");
	}
}


function loadCourseStartEnd(){
	gmStartLine = new GMarker(new GLatLng(34.07348, -118.24017), {icon:crStartIcon});
	gmFinishLine = new GMarker(new GLatLng(34.018138, -118.502744), {icon:crFinishIcon});

	
	var focusStartLine = function() {
		gmStartLine.openInfoWindowHtml("<div class=\"infoWinContainer\"><div class=\"infoWinTitleDiv\"><span class=\"txtInfoWinTitle\">Start Line and Expo</span></div><div class=\"txtInfoWinDesc\">Dodger Stadium<br><br>Expo at the Start Line: Friday, March 19th, through Saturday, March 20th.<br>Start Line on Race Day, March 21st.</div><div class=\"txtInfoWinSource\">Source:&nbsp;<a id=\"txtInfoWinSource\">LA Marathon, LLC</a></div><div class=\"txtInfoWinCommuteramaFooter\">Powered by Commuterama.com</div></div>");
	}

	var focusFinishLine = function() {
		gmFinishLine.openInfoWindowHtml("<div class=\"infoWinContainer\"><div class=\"infoWinTitleDiv\"><span class=\"txtInfoWinTitle\">Finish Line</span></div><div class=\"txtInfoWinDesc\">Ocean Av and Santa Monica Bl in the City of Santa Monica</div><div class=\"txtInfoWinSource\">Source:&nbsp;<a id=\"txtInfoWinSource\">LA Marathon, LLC</a></div><div class=\"txtInfoWinCommuteramaFooter\">Powered by Commuterama.com</div></div>");
	}
	
	GEvent.addListener(gmStartLine, 'click', focusStartLine);
	GEvent.addListener(gmFinishLine, 'click', focusFinishLine);

	gMap.addOverlay(gmStartLine);
	gMap.addOverlay(gmFinishLine);
}

function MapLegend() {}
MapLegend.prototype = new GControl(true);
MapLegend.prototype.initialize = function(map) {
  var maplegend = this;
  maplegend.panel = document.createElement("div");
  maplegend.panel.style.border = "1px solid gray";
  maplegend.panel.style.paddingLeft = "5px";
  maplegend.panel.style.paddingRight = "5px";
  maplegend.panel.style.background = "beige";
  var html = '<div><b>2011 LA Marathon</b></div><img src="_images/TAG/courseRoute_icon.png"/> Course Route</div><div><img src="_images/TAG/detourRoute_icon.png"/> Detour Routes</div><div><img src="_images/TAG/DoNotEnter10x10.png"/>&nbsp Road Closures</div><div><img src="_images/TAG/alert_icon.png"/> Alerts</div><div><img src="_images/TAG/poi_icon.png"/> Points of Interest</div><div><img src="_images/TAG/pkg_icon.png"/> Parking Lots</div>';
  maplegend.panel.innerHTML = html;
  map.getContainer().appendChild(maplegend.panel);
  return maplegend.panel;
}
MapLegend.prototype.getDefaultPosition = function() {
  return new GControlPosition(
      G_ANCHOR_BOTTOM_RIGHT, new GSize(10, 50));
}

//function resizeMap() {
//	var mapDivHeight = getMapCanvasHeight() - 200;  //leave space for footer
//	document.getElementById("map_canvas").style.height=mapDivHeight+"px"; // change height of map accordingly	
//	
//	//resizeLeftMenu();
//}

//function resizeLeftMenu() {
//	//GLog.write("mapDivHeight = " + getMapCanvasHeight());
//	var mapDivHeight = getMapCanvasHeight() - 240;  //leave space for footer
//	//GLog.write("mapDivHeight = " + mapDivHeight);
//	document.getElementById("Accordion1").style.maxHeight = mapDivHeight+"px"; // change height of left menu accordingly
//	document.getElementById("GeneralEventInfoPanelContent").style.height = (mapDivHeight-200)+"px";
//}

//--------------------
//Event functions
//--------------------
// **********************************************
// Road Closure
// **********************************************

function getRoadClosureIndex() {
	//GLog.write ("inside getRoadClosureIndex()");
	var arrayIndex = null;
	var gllInfoWindowLat = gMap.getInfoWindow().getPoint().lat();
	var gllInfoWindowLng = gMap.getInfoWindow().getPoint().lng();

	//GLog.write("gllInfoWindow = " + gllInfoWindowLat + " " + gllInfoWindowLng);
	var numOfRC = roadClosure.length;
	//GLog.write("numOfRC = " + numOfRC);

	for (var a  = 0; a < numOfRC; a=a+1)
	{
		if (gllInfoWindowLat == roadClosure[a].getLatLng().lat())
		{
			if (gllInfoWindowLng == roadClosure[a].getLatLng().lng())
			{
				arrayIndex = a;
			}
		}
	}
	//GLog.write("arrayIndex = " + arrayIndex);
	//GLog.write("end getRoadClosureIndex()");
	return arrayIndex;
}

function panToRC  (rcIndex) {
	gMap.panTo(roadClosure[rcIndex].getLatLng());

	roadClosure[rcIndex].openInfoWindow("<div class=\"infoWinContainer\"><div class=\"infoWinTitleDiv\"><span class=\"txtInfoWinTitle\">"+ roadClosure[rcIndex].title +"</span></div><div class=\"txtInfoWinDesc\">"+roadClosure[rcIndex].desc +"</div><div class=\"txtInfoWinSource\">Source: <a id=\"txtInfoWinSource\">"+roadClosure[rcIndex].source+"</a></div><div class=\"txtInfoWinCommuteramaFooter\">Powered by Commuterama.com</div></div>");

}

function initializeRC(roadClosure,index) {
	var focusRoadClosure = function() {
	roadClosure.openInfoWindowHtml("<div class=\"infoWinContainer\"><div class=\"infoWinTitleDiv\"><span class=\"txtInfoWinTitle\">"+ roadClosure.title +"</span></div><div class=\"txtInfoWinDesc\">"+roadClosure.desc +"</div><div class=\"txtInfoWinSource\">Source: <a id=\"txtInfoWinSource\">"+roadClosure.source+"</a></div><div class=\"txtInfoWinCommuteramaFooter\">Powered by Commuterama.com</div></div>");
	return false;

	}

	GEvent.addListener(roadClosure, 'click', focusRoadClosure);
	gMap.addOverlay(roadClosure);
	return roadClosure;
}



function LoadRoadClosures () {
	var rcdata = loadRoadClosuresFromDatabase();
	var rccount = rcdata.length;

	for (var i = 0; i < rccount; i=i+1)
	{
		roadClosure[i] = new GMarker(new GLatLng(rcdata[i].lat,rcdata[i].lng), getGMarkeroptions(rcdata[i].type_id));
		roadClosure[i].title = rcdata[i].name;
		roadClosure[i].desc = rcdata[i].description;
		roadClosure[i].db_index = rcdata[i].id;
		roadClosure[i].type_id = rcdata[i].type_id;
		roadClosure[i].source = rcdata[i].source;
		roadClosure[i].area_id = rcdata[i].area_id;
		roadClosure[i].saveStat = 1;
		initializeRC(roadClosure[i],i);
	}
}

function getGMarkeroptions(type_id) {	
	//Chooses marker attributes based on type_id
	switch(type_id)
	{
	case '1': case 1:
  		//road closures
		return {icon:rcIcon,
				draggable:false
				};
  		break;
	case '2': case 2:
		//alerts
  		return {icon:alertIcon,
				draggable:false
				};
  		break;	
	case '3': case 3:
		//points of interest
  		return {icon:poiIcon,
				draggable:false
				};
  		break;	
	case '4': case 4:
		//parking lots
  		return {icon:parkingIcon,
				draggable:false
				};
  		break;	
	default:
  		return {icon:rcIcon,
				draggable:false
				};
  		break;
	}
}

// **********************************************
// Detour Route (DR)
// **********************************************

function LoadRoutes () {
	var routedata = loadRoutesFromDatabase();
	var routecount = routedata.length;

	for (var i = 0; i < routecount; i++)
	{
		detourRoute[i] = new GPolyline.fromEncoded({
  			points: routedata[i].latlngs,
  			levels: routedata[i].levels,
  			zoomFactor: 2, 
  			numLevels: 18
			});
		detourRoute[i].setStrokeStyle(getGPolyStyleoptions(routedata[i].type_id));
		//initialize all attributes of the route
		detourRoute[i].title = routedata[i].name;
		detourRoute[i].desc = routedata[i].description;
		detourRoute[i].db_index = routedata[i].id;
		detourRoute[i].type_id = routedata[i].type_id;
		detourRoute[i].source = routedata[i].source;
		detourRoute[i].area_id = routedata[i].area_id;
		detourRoute[i].midPt = getMidPtOfDR(getVertexArray(detourRoute[i]));

		var gplDR_new = initializeDR(detourRoute[i],i);
		//GLog.write("removing temp poly..." + i);
		detourRoute[i] = gplDR_new;
		//GLog.write("adding new poly...");
		gMap.addOverlay(gplDR_new);	
	}
}

function getDetourRouteIndex(isMidPt) {
	//GLog.write("start getDetourRouteIndex(), isMidPt = " + isMidPt);
	var arrayIndex = null;
	var gllInfoWindowLat = gMap.getInfoWindow().getPoint().lat();
	var gllInfoWindowLng = gMap.getInfoWindow().getPoint().lng();
	//GLog.write("gllInfoWindow = " + gllInfoWindowLat + " " + gllInfoWindowLng);
	var numOfDR = detourRoute.length;
	//GLog.write("numOfDR = " + numOfDR);

	if(isMidPt)
	{
		//GLog.write("Is MidPt");
		for (var a  = 0; a < numOfDR; a=a+1)
		{
			//GLog.write("midPtLat = " + detourRoute[a].midPt.lat());
			if (gllInfoWindowLat == detourRoute[a].midPt.lat())
			{
				//GLog.write("midPtLng = " + detourRoute[a].midPt.lng());
				if (gllInfoWindowLng == detourRoute[a].midPt.lng())
				{
					arrayIndex = a;
				}
			}
		}
	}
	else
	{
		arrayIndex = numOfDR - 1;
	}
	return arrayIndex;		
}

function panToDR (drIndex) {		
	gMap.openInfoWindowHtml(detourRoute[drIndex].midPt,"<div class=\"infoWinContainer\"><div class=\"infoWinTitleDiv\"><span class=\"txtInfoWinTitle\">"+ detourRoute[drIndex].title +"</span></div><div class=\"txtInfoWinDesc\">"+detourRoute[drIndex].desc +"</div><div class=\"txtInfoWinSource\">Source: <a id=\"txtInfoWinSource\">"+detourRoute[drIndex].source+"</a></div><div class=\"txtInfoWinCommuteramaFooter\">Powered by Commuterama.com</div></div>");
}

function getVertexArray(route) {
	var vertexarray = new Array();
	var vertexcount = route.getVertexCount();
		for (var b = 0; b < vertexcount; b++)
		{
			vertexarray[b] = route.getVertex(b);
		}
	return vertexarray;
}

function getMidPtOfDR (vertex) {

	//GLog.write("start getDRPolyCenter()");

	// returns a GLatLng object
	var vertexCount = vertex.length;
	var justBeforeMidPt;
	var justAfterMidPt;
	var midPtLat;
	var midPtLng;

	//try to find two vertices closest to the midpoint
	var isOdd = vertexCount%2;

	if (isOdd)
	{
		vertexCount = vertexCount - 1;
	}
	if (vertexCount == 2) //if a straight line
	{
		justBeforeMidPt = vertex[0];
		justAfterMidPt = vertex[1];
	}
	else
	{
		justBeforeMidPt = vertex[(vertexCount/2) - 1];
		justAfterMidPt = vertex[vertexCount / 2];
	}
	//find approx midpoint between the two vertices
	midPtLat = (justBeforeMidPt.lat() + justAfterMidPt.lat())/2;
	midPtLng = (justBeforeMidPt.lng() + justAfterMidPt.lng())/2;
	var midPtLatLng = new GLatLng(midPtLat,midPtLng);
	return midPtLatLng;  		
}

function initializeDR (detour,index) {

	var focusDetourRoute = function(){			
	gMap.openInfoWindowHtml(detour.midPt,"<div class=\"infoWinContainer\"><div class=\"infoWinTitleDiv\"><span class=\"txtInfoWinTitle\">"+ detour.title +"</span></div><div class=\"txtInfoWinDesc\">"+detour.desc +"</div><div class=\"txtInfoWinSource\">Source: <a id=\"txtInfoWinSource\">"+detour.source+"</a></div><div class=\"txtInfoWinCommuteramaFooter\">Powered by Commuterama.com</div></div>");			
		return false;
	}
	var updateDRMidPt = function(){
		detour.midPt = getMidPtOfDR(getVertexArray(detour));
    }

	var mouseOverDR = function() {
		gpInFocus = detour;
	}

	var mouseOutDR = function() {
		gpInFocus = null;
	}
	GEvent.addListener(detour, 'click', focusDetourRoute);
	GEvent.addListener(detour, 'lineupdated', updateDRMidPt);
	GEvent.addListener(detour, 'mouseover', mouseOverDR);
	GEvent.addListener(detour, 'mouseout', mouseOutDR);
	return detour;
}

function askToDeleteVertex (gmOverlay) {
	if(typeof(gmOverlay.index) != "undefined")
	{
		if(name != null)
		{
			var gllVertexInFocus = gpInFocus.getVertex(gmOverlay.index);
		}
		else
		{
			//GLog.write("gpInFocus is null or undefined");
		}

	}
}

function getGPolyStyleoptions(type_id) {
	//Chooses route attributes based on type_id
	switch(type_id)
	{
	case '1': case 1:
		//detour routes
  		return {color:"#cc33cc",
				weight: 6,
  				opacity: 0.7
				};
  		break;
	case '2': case 2:
		//course routes
  		return {color:"#000099",
				weight: 10,
  				opacity: 0.9
				};
  		break;
	default:
  		return {color:"#cc33cc",
				weight: 8,
  				opacity: 0.7
				};
  		break;
	}
}

//**DATABASE FUNCTIONS **//

// **********************************************
// Road Closure
// **********************************************
function loadRoadClosuresFromDatabase () {
	var parameters = JSON.stringify({
				event_id:event_id});
	var result = parseResult(processJSON("roadclosure","view",parameters));
	return result;
}

// **********************************************
// Route (DR)
// **********************************************

//**Load Routes
function loadRoutesFromDatabase () {
	var parameters = JSON.stringify({
				event_id:event_id});
	
	var result = parseResult(processJSON("route","view",parameters));
	return result;
}

//**Venues
function loadVenuesFromDatabase() {
	var parameters = JSON.stringify({
				event_id:event_id});
	var result = parseResult(processJSON("venue","view",parameters));
	return result;
}

//**MISC FUNCTIONS**//
function parseResult(result)
{
	if(result != false)
	{
		return JSON.parse(result);
	}
	else
	{
		return false;
	}
}

//** AJAX FUNCTIONS **//
function processJSON(title,action,jsonstring)
{
	var xmlhttp=GetXmlHttpObject();
	if (xmlhttp==null)
	{
		alert ("Browser does not support HTTP Request");
  		return;
	}
	var url="EventData/EventDataProcessor2011.php";

	var parameters = "t="+title;
	parameters = parameters+"&a="+action;
	parameters = parameters+"&q="+jsonstring;
	
	xmlhttp.open("POST",url,false);
	//Send the proper header information along with the request
	xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	xmlhttp.setRequestHeader("Content-length", parameters.length);
	xmlhttp.setRequestHeader("Connection", "close");
	xmlhttp.send(parameters);	
	//GLog.write("response " + xmlhttp.responseText);
	return xmlhttp.responseText;
}

function GetXmlHttpObject()
{
	if (window.XMLHttpRequest)
	{
		// code for IE7+, Firefox, Chrome, Opera, Safari
	  	return new XMLHttpRequest();
	}
	if (window.ActiveXObject)
	{
		// code for IE6, IE5
		return new ActiveXObject("Microsoft.XMLHTTP");
	}
	return null;
}


