//Copyright 2003-2010 by Ars Datum, Inc. All rights reserved.

//MapQuest functions

/* ------------------- Global variables ------------------- */
var reload = true;
var cityPoi;
var markers = {};
var BoundaryLat = '';
var BoundaryLng = '';
var popup = true;				//boolean to determine if we should allow markers to show infoWindow
var showFlowLocs = false;	//boolean to show the flow highlighted points


/* ------------------- Classes ------------------- */

//class to hold markers
function Marker() {
	this.ID = '';
	this.Type = '';			//point, line, polygon, etc..
	this.Icon = '';
	this.IconHover = '';
	this.Width = 0;
	this.Height = 0;
	this.Lat = '';
	this.Lng = '';
	this.Title = '';
	this.Description = '';
	this.Severity = '';			//severity type
	this.GMarker = null;			//store the whole market object
}

/* ---------- Map movement/zooming functions -------------- */

//closes the info window if one is open
function CloseInfoWindow(e) {
	map.closeInfoWindow();
}

//disable the location based reloading of new icons whenever map finishes moving
function DisableReload() {
	reload = false;
}

//re-enable the location based loading
function EnableReload() {
	reload = true;
}

//checks to see fi user zoomed out too far, if so display stop sign icon to indicate there are traffic available if user zooms in more
function TooFarOut() {
	//hide all collection data
	Hide("all");

}

//determine the map's lat/lng boundaries
function SaveMapBoundary() {
	var bLat = '';
	var bLng = '';
	var boundary = map.getBounds();
	var pointSW = boundary.getSouthWest();
	var pointNE = boundary.getNorthEast();

	var swLat = pointSW.lat();
	var swLng = pointSW.lng();
	var neLat = pointNE.lat();
	var neLng = pointNE.lng();

	if (swLat < neLat)
		bLat = swLat + ',' + neLat;
	else
		bLat = neLat + ',' + swLat;

	if (swLng < neLng)
		bLng = swLng + ',' + neLng;
	else
		bLng = neLng + ',' + swLng;

	//save the values in the global variables
	BoundaryLat = bLat;
	BoundaryLng = bLng;
}

//whenever the map is moved or zoomed, we save the new center point and zoom level and reload the location based points
function SaveCenterLL(e) {
	var oldLat, oldLong, oldZoom, newLat, newLong, newZoom, blnReload;
	var blnReload = false;

	//get old lat/lng
	oldLat = centerLat;
	oldLong = centerLong;
	oldZoom = zoomLevel;

	//get new lat/lng
	centerPoint = map.getCenter();
	newLat = centerPoint.lat();
	newLong = centerPoint.lng();
	newZoom = map.getZoom();

	//save the lat/long
	centerLat = newLat;
	centerLong = newLong;
	zoomLevel = newZoom;

	//save the boundary info
	SaveMapBoundary();

	//if new zoom level load new layer
	if (oldZoom != newZoom)
		LoadFlow(CityID, newZoom);

	//check if we need to reload the icons
	if (oldLat != newLat || oldLong != newLong || oldZoom != newZoom)
		blnReload = true;

	if (zoomLevel < minZoomLevel) {
		TooFarOut();
	} else {
		//if lat/lng changed, rebuild collection
		if (blnReload == true) {
			//get rid of the city poi
			//map.removeOverlay(cityPoi);

			//show new state
			BuildRemoteCollections();

			//show the flow highlight points
			BuildFlowHighlights(CityID);
		}
	}
}

//load a new image for the camera, imageID=[id of the image object]
function ReloadImage(imageID) {
	var imageSrc = '';
	var oImage = document.getElementById(imageID);
	var randomNum = Math.random();
	if (oImage) {
		imageSrc = oImage.attributes['loc'].value;

		if (imageSrc.indexOf('?') < 0)
			oImage.src = imageSrc + '?x=' + randomNum;
		else
			oImage.src = imageSrc + '&x=' + randomNum;
	}
}

//load a specific map type
function ChangeMapType(oInput) {
	var mapType = oInput.attributes['value'].value;

	if (mapType == 'road')
		map.setMapType(G_NORMAL_MAP);
	else if (mapType == 'hybrid')
		map.setMapType(G_HYBRID_MAP);
	else if (mapType == 'satellite')
		map.setMapType(G_SATELLITE_MAP);
}

//***********************************************************************************
//Find Functions

//reset the find text box in the header
function ResetFind(theSetting) {
    var where = document.getElementById("txtSearch");
    if (theSetting == 0 && (where.value == ''))
        where.value = 'Type City or Zip';
    else if (theSetting == 1 && where.value == 'Type City or Zip')
        where.value = '';
}

//catch when a user hits the enter key
function CheckKeyPress(e) {
    keyCode = e.keyCode;
    if (keyCode == 13) {
        //enter was hit, run find function
        DoFind();
    }
}

//executes Google's Geocoder command
function DoFind() {
	var where = document.getElementById("txtSearch");
	var lookup = where.value;

	if (lookup != 'Type City or Zip' && lookup != '') {
		var geocoder = new GClientGeocoder();

		geocoder.getLatLng(lookup, function(point) {
			 if (!point) {
				  alert(lookup + ' not found!');
			 } else {
				  map.setCenter(point);

				  //save the user's last city search lat/lng
				  SetCookie("lat_lng", point.lat() + ',' + point.lng(), 30);
				  SetCookie("zoom", map.getZoom(), 30);
			 }
		});
	}
}

/* ------------------ Toogle Options ---------------------- */

//reloads all the remote collections
function RefreshRemoteCollections() {
	BuildRemoteCollections();
}

//toggle on/off each of the different options to display on the map
function Toggle(oThis) {
	 var theType = oThis.attributes['value'].value;
	 if (oThis) {
		  if (oThis.checked == true) {
				//show this
				Show(theType);
		  } else {
				//hide this
				Hide(theType);
		  }
	 }
}

//show a particular option on the map
function Show(theType) {
	var oFlow = document.getElementById('chkFlow');
	var oIncident = document.getElementById('chkIncident');
	var oConstruction = document.getElementById('chkConstruction');
	var oCamera = document.getElementById('chkCamera');
	var oSponsor = document.getElementById('chkSponsor');

	//only show items if statisfy zoom min requirement
	if (zoomLevel >= minZoomLevel) {
		if (theType == "all") {
			if (oFlow.checked == true)
				Show('flow');
			if (oIncident.checked == true)
				Show('incident');
			if (oConstruction.checked == true)
				Show('construction');
			if (oCamera) {
				if (oCamera.checked == true)
					Show('camera');
			}
			if (oSponsor) {
				if (oSponsor.checked == true)
					Show('sponsor');
			}

		} else {
			/*
			if (theType == 'flow') {
				if (traffic)
					traffic.show();
			}
			*/

			//show the CCTraffic flow lines, only if actived
			if (theType == 'flow' && flowActive == true)
				ShowFlow();

			//show all items in this collection
			ShowCollection(theType);
		}
	}
}

//hide a particular option on the map
function Hide(theType) {
	var oFlow = document.getElementById('chkFlow');
	var oIncident = document.getElementById('chkIncident');
	var oConstruction = document.getElementById('chkConstruction');
	var oCamera = document.getElementById('chkCamera');
	var oSponsor = document.getElementById('chkSponsor');

	if (theType == 'all') {
		//hide all collection
		//map.clearOverlays();
		Hide('flow');
		Hide('incident');
		Hide('construction');
		Hide('camera');
		Hide('sponsor');
	} else {
		//hiding a single collection
		/*
		if (theType == 'flow') {
			if (traffic)
				traffic.hide();
		}
		*/

		//hide the CCTraffic flow lines, only if actived
		if (theType == 'flow' && flowActive == true)
			HideFlow();

		//hide all the items of this collection
		HideCollection(theType);
	}
}


/* -------------------- Collections ---------------------- */

//build all the collections needed in the map, i.e. each of the toggle options (flow, incident, construction, camera, sponsor)
function BuildRemoteCollections() {
	if (zoomLevel >= minZoomLevel) {
		//only reload if the location based option is active
		if (reload == true) {
			if (flowActive == false) {
				//build flow collection icons, since this market's flow lines don't exists yet
				colURL = "georss/traffic.asp?id="+CityID+"&type=flow&max="+CityMaxRecord+"&lat="+centerLat+"&lng="+centerLong+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng+"&sort=severity_priority%20asc";
				BuildCollection('flow', colURL);
			}

			//build incident collection
			colURL = "georss/traffic.asp?id="+CityID+"&type=incident,event&max="+CityMaxRecord+"&lat="+centerLat+"&lng="+centerLong+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng+"&sort=severity_priority%20asc";
			BuildCollection('incident', colURL);

			//build construction collection
			colURL = "georss/traffic.asp?id="+CityID+"&type=construction&max="+CityMaxRecord+"&lat="+centerLat+"&lng="+centerLong+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng;
			BuildCollection('construction', colURL);

			//build camera collection, if exists
			if (cameraExists == true) {
				colURL = "georss/camera.asp?id="+CityID+"&type=CCT&max=25&lat="+centerLat+"&lng="+centerLong+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng;
				BuildCollection('camera', colURL);
			}

			//build sponsor collection, if exists
			if (sponsorExists == true) {
				colURL = "georss/sponsor.asp?id="+CityID+"&type=Fox&max=25&lat="+centerLat+"&lng="+centerLong+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng;
				BuildCollection('sponsor', colURL);
			}

			Show("all");
		}
	} else
		TooFarOut();
}

//function to create base icon
function CreateBaseIcon(width, height) {
	var anchorOffset = parseInt(width / 2);
	var shadowIcon = new GIcon();
	//shadowIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
	//shadowIcon.shadowSize = new GSize(37, height);
	shadowIcon.transparent = websiteServer + "images/general/transparent.png";
	shadowIcon.iconSize = new GSize(width, height);
	shadowIcon.iconAnchor = new GPoint(9, height);
	shadowIcon.infoWindowAnchor = new GPoint(anchorOffset, 2);
	shadowIcon.infoShadowAnchor = new GPoint(anchorOffset - 1, 25);

	return shadowIcon;
}

//function will create a Google Marker
function CreateMarker(mMarker) {
	//get the width/height of the image
	var width = mMarker.Width;
	var height = mMarker.Height;

	if (width == 0 || height == 0) {
		var oImage = document.createElement('img');
		oImage.src = mMarker.Icon;
		if (oImage.width > '') {
			width = oImage.width;
			height = oImage.height;
		} else {
			//error proof
			width = 34;
			height = 34;
		}
		oImage = null;
	}

	//first build the shadow for this market
	var baseIcon = CreateBaseIcon(width, height);
	var point = new GLatLng(mMarker.Lat, mMarker.Lng);
	var iconImage = new GIcon(baseIcon);
	iconImage.image = mMarker.Icon;

	var content = '<table border="0" cellspacing="2" cellpadding="2" width="300">';
		content += '<tr><td class="' + mMarker.Severity + 'Border ' + mMarker.Severity + '"><b>' + mMarker.Title + '</b></td>';
		content += '<tr><td>' + mMarker.Description + '</td>';
	content += '</table>';

	var markerOptions = {icon: iconImage, title: mMarker.Title};
	var thisMarker = new GMarker(point, markerOptions);

	//add event handler
	if (popup == true) {
		GEvent.addListener(thisMarker, "click", function() {
			//now open the infoWindow
			thisMarker.openInfoWindowHtml(content);
		});
		GEvent.addListener(thisMarker, "infowindowopen", function() {
			//make sure reloading of the icons is disabled
			DisableReload();
		});
		GEvent.addListener(thisMarker, "infowindowclose", function() {
			//make sure reloading of the icons is enabled
			EnableReload();
		});
	}

/*
	if (mMarker.Type == 'flowHighlight') {
		GEvent.addListener(thisMarker, "mouseover", function() {
			//now open the infoWindow
			thisMarker.openInfoWindowHtml(content);
		});
	}
*/

	//mouse hover effects
	if (mMarker.IconHover > '') {
		GEvent.addListener(thisMarker, "mouseover", function() {
			//make sure reloading of the icons is enabled
			thisMarker.setImage(mMarker.IconHover);
		});
		GEvent.addListener(thisMarker, "mouseout", function() {
			//make sure reloading of the icons is enabled
			thisMarker.setImage(mMarker.Icon);
		});
	}

	return thisMarker;
}

//function will display all the flow highlighted points
function BuildFlowHighlights(cityID) {
	var oFlow = document.getElementById('chkFlow');

	if (reload == true) {
		HideCollection('flowHighlight');
		DeleteCollection('flowHighlight');

		if (showFlowLocs == true && oFlow.checked == true && flowBoundaries) {
			//get the xml doc
			var oXML = new Object;
			var url = "georss/flowHighlight.asp?id="+cityID+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng;
			ajaxReturnRequest(url, oXML, 'xml');
			var xmlDoc = oXML.xml;
			var total = xmlDoc.getElementsByTagName('Location').length;

			//icon info
			var iconURL = websiteServer + 'images/general/';
			xIconWidth = '5';
			xIconHeight = '5';

			//add new markets
			for (i=0; i < total; i++) {
				xID = xmlDoc.getElementsByTagName('Location')[i].attributes.getNamedItem('ID').childNodes[0].data;
				xLat = xmlDoc.getElementsByTagName('Location')[i].attributes.getNamedItem('Lat').childNodes[0].data;
				xLng = xmlDoc.getElementsByTagName('Location')[i].attributes.getNamedItem('Lng').childNodes[0].data;
				xSeverity = xmlDoc.getElementsByTagName('Severity')[i].childNodes[0].data;
				xTitle = xmlDoc.getElementsByTagName('Title')[i].childNodes[0].data;
				xDescription = xmlDoc.getElementsByTagName('Description')[i].childNodes[0].data;

				if (xLat > '' && xLng > '') {
					//build the marker class
					var oMarker = new Marker;
					oMarker.ID = 'flowHighlight_' + xID;
					oMarker.Type = 'flowHighlight';
					xIconName = 'dot-'+xSeverity+'.png';
					//xIconHover = 'dot-'+xSeverity+'.png';
					oMarker.Icon = iconURL + xIconName;
					//oMarker.IconHover = iconURL + xIconHover;
					oMarker.Width = parseInt(xIconWidth);
					oMarker.Height = parseInt(xIconHeight);
					oMarker.Lat = xLat;
					oMarker.Lng = xLng;
					oMarker.Title = xTitle;
					oMarker.Description = xDescription;
					oMarker.Severity = xSeverity;

					//create the google marker
					var oGMarker = CreateMarker(oMarker);
					oMarker.GMarker = oGMarker;

					//add it to the array of markers
					markers[oMarker.ID] = oMarker;
				}
			}

			ShowCollection('flowHighlight');
		}
	}
}

//function to parse xml doc and build markers for a specific collection
function BuildCollection(colType, colURL) {
	if (colType > '' && colURL > '') {
		//get the xml doc
		var oXML = new Object;
		ajaxReturnRequest(colURL, oXML, 'xml');
		var xmlDoc = oXML.xml;
		var total = xmlDoc.getElementsByTagName('item').length;

		//determine where the images are located
		var iconURL = websiteServer + 'images/traffic/';
		if (colType == 'sponsor')
			iconURL = sponsorWebsiteServer + 'images/sponsor/';

		//reinitialize this collection
		HideCollection(colType);
		DeleteCollection(colType);

		//add new markers into this collection
		for (i=0; i < total; i++) {
			xID = xmlDoc.getElementsByTagName('id')[i].childNodes[0].data;
			xType = xmlDoc.getElementsByTagName('type')[i].childNodes[0].data;
			xIconName = xmlDoc.getElementsByTagName('icon_name')[i].childNodes[0].data;
			xLatLng = xmlDoc.getElementsByTagName('lat_lng')[i].childNodes[0].data;
			xDescription = xmlDoc.getElementsByTagName('description')[i].childNodes[0].data;
			xSeverity = '';
			xTitle = '';
			xIconHover = '';
			xIconWidth = '0';
			xIconHeight = '0';
			if (xmlDoc.getElementsByTagName('icon_width')[i]) {
				xIconWidth = xmlDoc.getElementsByTagName('icon_width')[i].childNodes[0].data;
			}
			if (xmlDoc.getElementsByTagName('icon_height')[i]) {
				xIconHeight = xmlDoc.getElementsByTagName('icon_height')[i].childNodes[0].data;
			}
			if (xmlDoc.getElementsByTagName('severity')[i]) {
				xSeverity = xmlDoc.getElementsByTagName('severity')[i].childNodes[0].data;
				xSeverity = xSeverity.toLowerCase();
			}
			if (xmlDoc.getElementsByTagName('event_name')[i])
				xTitle = xmlDoc.getElementsByTagName('event_name')[i].childNodes[0].data;
			else if (xmlDoc.getElementsByTagName('title_only')[i])
				xTitle = xmlDoc.getElementsByTagName('title_only')[i].childNodes[0].data;

			if (colType == 'flow' || colType == 'incident' || colType == 'construction') {
				//rename icons based on Fox icons: extreme, major, moderate, minor, freely, advisory, construction
				if (xType == 'event') {
					xIconName = 'event.png';
					xIconHover = 'event_over.png';
				} else if (xType == 'construction') {
					xIconName = 'construction.png';
					xIconHover = 'construction_over.png';
				} else {
					xIconName = xSeverity + '.png';
					xIconHover = xSeverity + '_over.png';
				}

				//fox's width/height for these images are 34x34
				xIconWidth = '34';
				xIconHeight = '34';
			} else if (colType == 'camera') {
				xIconName = 'camera.png';
				xIconHover = 'camera_over.png';

				//fox's width/height for this images are 28x33
				xIconWidth = '34';
				xIconHeight = '34';
			}

			xLat = '';
			xLng = '';
			if (xLatLng > '') {
				arrLatLng = xLatLng.split(" ");
				xLat = arrLatLng[0];
				xLng = arrLatLng[1];

				//build the marker class
				var oMarker = new Marker;
				oMarker.ID = colType + '_' + xID;
				oMarker.Type = colType;
				oMarker.Icon = iconURL + xIconName;
				oMarker.IconHover = iconURL + xIconHover;
				oMarker.Width = parseInt(xIconWidth);
				oMarker.Height = parseInt(xIconHeight);
				oMarker.Lat = xLat;
				oMarker.Lng = xLng;
				oMarker.Title = xTitle;
				oMarker.Description = xDescription;
				oMarker.Severity = xSeverity;

				//create the google marker
				var oGMarker = CreateMarker(oMarker);
				oMarker.GMarker = oGMarker;

				//add it to the array of markers
				markers[oMarker.ID] = oMarker;
			}
		}
	}
}

//function deletes all items from this collection
function DeleteCollection(colType) {
	for (var item in markers) {
		var oMarker = markers[item];
		if (oMarker.Type == colType) {
			delete markers[item];
		}
	}
}

//display the collection on the map
function ShowCollection(colType) {
	for (var item in markers) {
		var oMarker = markers[item];
		if (oMarker.Type == colType) {
			map.addOverlay(oMarker.GMarker);
		}
	}
}

//hide the collection on the map
function HideCollection(colType) {
	for (var item in markers) {
		var oMarker = markers[item];
		if (oMarker.Type == colType) {
			map.removeOverlay(oMarker.GMarker);
		}
	}
}

/* -------------------- Flow Overlays ---------------------- */

//load a new flow layer
function LoadFlow(cityID, zoom) {
	var oFlow = document.getElementById('chkFlow');
	var imgFlowLayer = mapLayerServer + "layers/"+cityID+"/"+cityID+"_FlowCoverage_"+zoom+".png"

	//remove old layers
	if (flowLayer)
		map.removeOverlay(flowLayer);

	//continue loading layer ONLY if it exists
	var oImage = document.createElement('img');
	oImage.onload = function () { LoadingFlow(cityID, zoom); };
	oImage.src = imgFlowLayer;
}

//handler to be completed if flow layer exists
function LoadingFlow(cityID, zoom) {
	var oFlow = document.getElementById('chkFlow');
	var imgFlowLayer = mapLayerServer + "layers/"+cityID+"/"+cityID+"_FlowCoverage_"+zoom+".png"

	//remove old layers
	//if (flowLayer)
	//	map.removeOverlay(flowLayer);

	if (flowBoundaries) {
		flowLayer = new GGroundOverlay(imgFlowLayer, flowBoundaries);
		map.addOverlay(flowLayer);

		if (oFlow.checked == false)
			HideFlow();
	}
}

function ShowFlow() {
	var oFlow = document.getElementById('chkFlow');
	if (flowLayer && oFlow.checked == true) {
		flowLayer.show();
		ShowCollection('flowHighlight');
	} else if (flowLayer) {
		flowLayer.hide();
		HideCollection('flowHighlight');
	}
}

function HideFlow() {
	if (flowLayer)
		flowLayer.hide();

	//hide the highlighted points
	HideCollection('flowHighlight');
}

/* ------------------- Cookies ------------------- */

function GetCookie( check_name ) {
	// first we'll split this cookie up into name/value pairs
	// note: document.cookie only returns name=value, not the other components
	var a_all_cookies = document.cookie.split( ';' );
	var a_temp_cookie = '';
	var cookie_name = '';
	var cookie_value = '';
	var b_cookie_found = false; // set boolean t/f default f

	for ( i = 0; i < a_all_cookies.length; i++ )
	{
		// now we'll split apart each name=value pair
		a_temp_cookie = a_all_cookies[i].split( '=' );


		// and trim left/right whitespace while we're at it
		cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');

		// if the extracted name matches passed check_name
		if ( cookie_name == check_name )
		{
			b_cookie_found = true;
			// we need to handle case where cookie has no value but exists (no = sign, that is):
			if ( a_temp_cookie.length > 1 )
			{
				cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
			}
			// note that in cases where cookie is initialized but no value, null is returned
			return cookie_value;
			break;
		}
		a_temp_cookie = null;
		cookie_name = '';
	}
	if ( !b_cookie_found )
	{
		return null;
	}
}

function SetCookie(name, value, expires)
{
	// set time, it's in milliseconds
	var today = new Date();
	today.setTime( today.getTime() );

	if ( expires )
	{
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );

	document.cookie = name + "=" +escape( value ) +
	( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + ";path=/";
}