// JScript File
//Copyright 2003-2010 by Ars Datum, Inc. All rights reserved. 

//google map key
//Write out the tilemap script key
//cctraffic.net key
var scriptKey = "ABQIAAAA0LAIb8E-QNBap9pDl5s4rhQPpIUZsI2zaBjJmKEF6BEeckdk9xTOlm0XD08buDJic_BhmluiBBjTyQ";
//mrtlab.com key
//var scriptKey = "ABQIAAAA0LAIb8E-QNBap9pDl5s4rhTayhINZAj3B_GXwyB6qkAbX50SXRRdqMfbuuvZ2Nvv3XqrQd8KEbyFuw";
document.write("<script src='http://maps.google.com/maps?file=api&v=2&key=" + scriptKey + "' type='text/javascript'></script>");


//global variables for map (default settings)
var map = null;
var mapKey = {};                //associative array for any map settings: key/value delimited, key: type, profile_id, profile_type
var reload = true;
var markers = {};
var BoundaryLat = '';           //min,max latitude of boundary area
var BoundaryLng = '';           //min,max longitude of boundary area
var popup = true;				//boolean to determine if we should allow markers to show infoWindow
var CenterLat = '';
var CenterLng = '';
var ZoomLevel = 4;
var MinZoomLevel = 7;

var flowBoundaries = null;
var flowLayer = null;
var CitySWPoint = null;
var CityNEPoint = null;

//toggle variable to show/hide options on traffic map for stations
var DisplayFlow = 1;
var DisplayIncident = 1;
var DisplayConstruction = 1;
var DisplayCamera = 0;
var DisplaySponsor = 1;

/* ************ Google Push-Pins 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;
}

//goto a specific location at this zoom level
function GotoLocation(latitude, longitude, zoomLevel) {
    if (zoomLevel == null)
        zoomLevel = ZoomLevel;

    if (latitude.toString() > '' && longitude.toString() > '') {
        map.closeInfoWindow();
        map.setCenter(new GLatLng(latitude, longitude), zoomLevel);
    }
}

//save the current map location (center lat/lng)
function SaveMapState(e) {
	var oldLat, oldLng, oldZoom, newLat, newLng, newZoom;
	//var blnReload = false;

	//get old lat/lng
	oldLat = CenterLat;
	oldLng = CenterLng;
	oldZoom = ZoomLevel;

	//get new lat/lng
	centerPoint = map.getCenter();
	newLat = centerPoint.lat();
	newLng = centerPoint.lng();
	newZoom = map.getZoom();
	
	if (oldZoom != newZoom) {
	    map.closeInfoWindow();
	    reload = true;	    
	}

	//save the lat/long
	CenterLat = newLat;
	CenterLng = newLng;
	ZoomLevel = newZoom;

	//save the boundary info
	SaveMapBoundary();
	
	//actions to take after moved
	if (reload == true)
	    MapActions();
}

//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;
}

//actions to take after the map is moved
function MapActions() {
    var blnZoomFarOut = false;
	if (ZoomLevel <= MinZoomLevel)
	    blnZoomFarOut = true;
	
	if (mapKey.type == "sponsor") {
	    //actions for sponsor map
	    if (blnZoomFarOut == true) {
	        //hide any old sponsor points
	        SponsorLocations(0);
	        
	        //show market level sponsor's icon
	        CitySponsors(1);
	    } else {
	        //show individual sponsor's points within boundary area
	        
	        //first hide the market level icons
	        CitySponsors(0);
	        
	        //get the location's within this boundary area
	        SponsorLocations(1);
	    }
	} else if (mapKey.type == "camera") {
	    //actions for camera map
	    if (blnZoomFarOut == true) {
	        //hide any old sponsor points
	        CameraLocations(0);
	        
	        //show market level sponsor's icon
	        CityCameras(1);
	    } else {
	        //show individual sponsor's points within boundary area
	        
	        //first hide the market level icons
	        CityCameras(0);
	        
	        //get the location's within this boundary area
	        CameraLocations(1);
	    }
	} else if (mapKey.type == "traffic") {
	    //actions for traffic map
	    
	    //check which market we are in
	    UpdateCityInfo();
	}
}

//class to hold markers
function Marker() {
	this.ID = '';
	this.Type = '';
	this.Icon = '';
	this.IconHover = '';
	this.Width = 0;
	this.Height = 0;
	this.Lat = '';
	this.Lng = '';
	this.Title = '';
	this.Description = '';
	this.Color = 'highlightColor';       //severity color for traffic data
	this.GMarker = null;			//store the whole market object
	
	//specific info for sponsors (optional)
	this.SponsorID = 0;
	this.ParentID = 0;
	
	//sponsor location point id or camera id
	this.PointID = 0;
}

//function to create base icon
function CreateBaseIcon(width, height) {
	var anchorOffset = parseInt(width / 2);
	var anchorOffsetY = parseInt(height / 2);
	var shadowIcon = new GIcon();
	//shadowIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
	//shadowIcon.shadowSize = new GSize(width, height);
	shadowIcon.transparent = websiteURL + "images/general/transparent.png";
	shadowIcon.iconSize = new GSize(width, height);
	shadowIcon.iconAnchor = new GPoint(anchorOffset, anchorOffsetY);
	shadowIcon.infoWindowAnchor = new GPoint(anchorOffset, 2);
	shadowIcon.infoShadowAnchor = new GPoint(anchorOffset - 1, 25);

	return shadowIcon;
}

//function will create a Google Marker
function CreateMarker(mMarker, mWidth) {
	//get the width/height of the image
	var width = mMarker.Width;
	var height = mMarker.Height;
	
	if (mWidth == null)
	    mWidth = 300;

	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 = 30;
			height = 30;
		}
		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="' + mWidth + '">';
		content += '<tr><td class="' + mMarker.Color + 'Border ' + mMarker.Color + '"><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();
		});
	}

	//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 deletes all items from this collection
function DeleteCollection(markerType) {
	for (var item in markers) {
		var oMarker = markers[item];
		if (oMarker.Type == markerType) {
			delete markers[item];
		}
	}
}

//display the collection on the map
function ShowCollection(markerType) {
    if (mapKey.type == "traffic") {
        var showLoc = false;
        if ((markerType == "flow" || markerType == "flowHighlight") && DisplayFlow == 1)
            showLoc = true;
        else if (markerType == "incident" && DisplayIncident == 1)
            showLoc = true;
        else if (markerType == "construction" && DisplayConstruction == 1)
            showLoc = true;
        else if (markerType == "camera" && DisplayCamera == 1)
            showLoc = true;
        else if (markerType == "sponsor" && DisplaySponsor == 1)
            showLoc = true;

	    for (var item in markers) {
		    var oMarker = markers[item];
		    if (oMarker.Type == markerType && showLoc == true) {
			    map.addOverlay(oMarker.GMarker);
		    }
	    }
    } else {
	    for (var item in markers) {
		    var oMarker = markers[item];
		    if (oMarker.Type == markerType) {
			    map.addOverlay(oMarker.GMarker);
		    }
	    }
	}
}

//hide the collection on the map
function HideCollection(markerType) {
	for (var item in markers) {
		var oMarker = markers[item];
		if (oMarker.Type == markerType) {
			map.removeOverlay(oMarker.GMarker);
		}
	}
}

//build and show the collection and add them to the markers array
function BuildCollection(markerType, colURL, infoWinWidth) {
    if (markerType > '' && colURL > '') {
        $.get(colURL, {}, function(xml) {
	        //reinitialize this collection
	        HideCollection(markerType);
	        DeleteCollection(markerType);
	        
	        if (infoWinWidth == null)
	            infoWinWidth = 300;
    	    
    	    //builds the collection
	        $('location', xml).each(function(i) {
		        xType = markerType;
		        xColor = '';
		        xID = $(this).attr("id");
		        xLat = $(this).attr("latitude");
		        xLng = $(this).attr("longitude");
		        xTitle = $(this).find("title").text();
		        xDescription = $(this).find("description").text();
		        xIconName = $(this).find("icon").attr("src");
		        xIconHover = $(this).find("icon").attr("hover");
		        xIconWidth = $(this).find("icon").attr("width");
		        xIconHeight = $(this).find("icon").attr("height");
		        
		        if (xType == 'flow' || xType == 'incident' || xType == 'construction' || xType == 'mapsponsor') {
		            xEvent = $(this).find("event_name").text();
		            xIconName = $(this).find("icon").attr("name");
		            xColor = $(this).find("severity").text();
		            if (xIconName > '')
		                xIconName = websiteURL + 'images/traffic/' + xIconName;
		            if (xEvent > '')
		                xTitle = xEvent;
		        }
		        
		        //optional data
		        xSponsorID = $(this).attr("SponsorID");
		        if (xSponsorID > '')
		            xSponsorID = parseInt(xSponsorID);
		        else
		            xSponsorID = 0;

		        xParentID = $(this).attr("ParentID");
		        if (xParentID > '')
		            xParentID = parseInt(xParentID);
		        else
		            xParentID = 0;

		        xPointID = $(this).attr("PointID");         //sponsor point id or camera id
		        if (xPointID > '')
		            xPointID = parseInt(xPointID);
		        else
		            xPointID = 0;

		        if (xLat > '' && xLng > '') {
			        //build the marker class
			        var oMarker = new Marker;
			        oMarker.ID = xID;
			        oMarker.Type = xType;
			        oMarker.Icon = xIconName;
			        oMarker.IconHover = xIconHover;
			        oMarker.Width = parseInt(xIconWidth);
			        oMarker.Height = parseInt(xIconHeight);
			        oMarker.Lat = xLat;
			        oMarker.Lng = xLng;
			        oMarker.Title = xTitle;
			        oMarker.Description = xDescription;
			        
			        if (xColor > '')
			            oMarker.Color = xColor;
			        
			        //optional data
			        oMarker.SponsorID = xSponsorID;
			        oMarker.ParentID = xParentID;
			        oMarker.PointID = xPointID;

			        //create the google marker
			        var oGMarker = CreateMarker(oMarker, infoWinWidth);
			        oMarker.GMarker = oGMarker;

			        //add it to the array of markers
			        markers[oMarker.ID] = oMarker;
		        }
	        });
	        
	        //show it
	        ShowCollection(markerType);
	    });
	}
}

//create a class to hold location info
function Location() {
    //geocode info
    this.address = '';
    this.address2 = '';         //TEMP storage: for storing suite number, apartment number, etc...
    this.city = '';
    this.state = '';
    this.zipcode = '';
    this.county = '';
    this.phone = '';
    this.latitude = '';
    this.longitude = '';

    this.error = false;
    this.IsValid = false;
}

//geocode address and execute the function handler when sucessful
function Geocode(address, address2, city, state, zipcode, fnHandler) {
    var oLocation = new Location;
    oLocation.address = address;
    oLocation.address2 = address2;
    oLocation.city = city;
    oLocation.state = state;
    oLocation.zipcode = zipcode;
    
    if (fnHandler == null)
        fnHandler = '';
    
	var geocoder = new GClientGeocoder();
	var FullAddress = '';
	if (oLocation.address > '' && oLocation.city > '' && oLocation.state > '' && oLocation.zipcode > '') {
	    FullAddress = oLocation.address + ', ' + oLocation.city + ', ' + oLocation.state + ' ' + oLocation.zipcode;
	} else if (oLocation.address > '' && oLocation.city > '' && oLocation.state > '') {
	    FullAddress = oLocation.address + ', ' + oLocation.city + ', ' + oLocation.state;
	} else if (oLocation.address > '' && oLocation.zipcode > '') {
	    FullAddress = oLocation.address + ', ' + oLocation.zipcode;
	}

    if (FullAddress > '') {
	    geocoder.getLocations(FullAddress, function(point) {
	        var oKML = point.Placemark;
	        
	        if (!oKML) {
	            oLocation.error = true;

                //execute fnHandler
                if (fnHandler > '')
                    eval(fnHandler);
	        } else {
	            //get specific point info
	            oLocation.IsValid = true;
	            
	            var oPoint = point.Placemark[0];
                oLocation.state = oPoint.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
                oLocation.latitude = oPoint.Point.coordinates[1];
                oLocation.longitude = oPoint.Point.coordinates[0];

                var gAddress = '';
                var gCity = '';
                var gCounty = '';
                var gZip = '';
                if (oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea) {
                    if (oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName != null)
                        gAddress = oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
                    if (oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName != null)
                        gCity = oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
                    if (oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName != null)
                        gCounty = oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName;
                    if (oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber != null)
                        gZip = oPoint.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber;
                } else if (oPoint.AddressDetails.Country.AdministrativeArea.Locality) {
                    if (oPoint.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare.ThoroughfareName != null)
                        gAddress = oPoint.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
                    if (oPoint.AddressDetails.Country.AdministrativeArea.Locality.LocalityName != null)
                        gCity = oPoint.AddressDetails.Country.AdministrativeArea.Locality.LocalityName;
                    if (oPoint.AddressDetails.Country.AdministrativeArea.Locality.PostalCode.PostalCodeNumber != null)
                        gZip = oPoint.AddressDetails.Country.AdministrativeArea.Locality.PostalCode.PostalCodeNumber;
                } else if (oPoint.AddressDetails.Country.AdministrativeArea.Thoroughfare) {
                    if (oPoint.AddressDetails.Country.AdministrativeArea.Thoroughfare.ThoroughfareName != null)
                        gAddress = oPoint.AddressDetails.Country.AdministrativeArea.Thoroughfare.ThoroughfareName;
                    if (oPoint.AddressDetails.Country.CountryName != null)
                        gCounty = oPoint.AddressDetails.Country.CountryName;
                    if (oPoint.AddressDetails.Country.AdministrativeArea.PostalCode.PostalCodeNumber != null)
                        gZip = oPoint.AddressDetails.Country.AdministrativeArea.PostalCode.PostalCodeNumber;
                }
                
                //overwrite google info if exists
                if (gAddress > '')
                    oLocation.address = gAddress;
                if (gCity > '')
                    oLocation.city = gCity;
                if (gCounty > '')
                    oLocation.county = gCounty;
                if (gZip > '')
                    oLocation.zipcode = gZip;
                    
                //execute fnHandler
                if (fnHandler > '')
                    eval(fnHandler);
	        }
	    });
	}
}



/* ************ Map Search Functions **************** */

//reset the find text box in the header
function ResetMapSearch(oInput, theSetting) {
    if (theSetting == 0 && (oInput.value == '')) {
        oInput.style.color = "gray";
        oInput.value = 'Type City or Zip';
    } else if (theSetting == 1 && oInput.value == 'Type City or Zip') {
        oInput.style.color = "#444444";
        oInput.value = '';
    } else if (theSetting == 1) {
        oInput.style.color = "#444444"; 
    } else if (theSetting == 0) {
        oInput.style.color = "gray"; 
    }
}

//catch when a user hits the enter key
function CheckMapSearchKeyPress(oInput, e) {
    keyCode = e.keyCode;
    if (keyCode == 13) {
        //enter was hit, run find function
        DoMapSearch(oInput);
    }
}

//executes Google's Geocoder command
function DoMapSearch(oInput) {
	var lookup = oInput.value;

	if (lookup != 'Type City or Zip' && lookup != '') {
		var geocoder = new GClientGeocoder();

		geocoder.getLatLng(lookup, function(point) {
			 if (!point) {
				  alert(lookup + ' not found!');
			 } else {
                  oInput.style.color = "gray";
                  oInput.blur();
				  map.setCenter(point, 11);
				  
				  if (mapKey.type == "traffic") {
				      //save the user's last city search lat/lng
				      SetCookie("lat_lng", point.lat() + ',' + point.lng(), 30);
				      SetCookie("zoom", map.getZoom(), 30);
				  }
			 }
		});
	}
}

/* ------------------- 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=/";
}

//geocode this address, return the lat/lng

/* ************ Map Sponsor Functions **************** */

//return all active sponsor id in the currently viewable list
function GetSponsorID(active) {
    var returnID = '';
    
    if (active == -1) {
        $(".sponsorViewItem").each(function () {if (returnID > '') returnID += ','; returnID += $(this).attr("value");});
    } else {
        $(".sponsorViewItem[active=" + active + "]").each(function () {if (returnID > '') returnID += ','; returnID += $(this).attr("value");});
    }
    
    return returnID;
}

//setup click function when a sponsor is click, this need to be resetup everytime the list is updated
function EnableSponsorToggle(className) {
    $("." + className).click(function () {
        var active = false;
        var sponsorID = $(this).attr("value");
        
        if (parseInt($(this).attr("active")) == 1) {
            //currently active, so deactivate it
            active = false;
            $(this).attr("active", 0);
            $(this).addClass("inactive");
        } else {
            //currently inactive, so activate it
            active = true;
            $(this).attr("active", 1);
            $(this).removeClass("inactive");
        }
        
        //show/hide these sponsors on the map
        MapActions();
    });
}

//event handler for sponsor highlights
function EnableItemEventHandler(itemClassName) {
    //allow these items to have hover action
    Hover(itemClassName);
    
    //enable the proper action for clicking on remove link
    EnableRemoveItem(itemClassName);
}

//remove the highlighted sponsor item from both the list and map
function EnableRemoveItem(itemClassName) {
    //swap out images for hover over/out
    $("." + itemClassName + " > .admin").find("a").find("img").hover(
        function () {
            //action when hover over
            $(this).attr("src", "/images/general/delete-hover.gif");
        },
        function () {
            //action when hover out
            $(this).attr("src", "/images/general/delete.gif");
        }
    );

    //enable clickable
    $("." + itemClassName + " > .admin").find("a").click(function () {
        //var pointID = $(this).parent().parent().attr("value");
       
        //remove this item from the list
        $(this).parent().parent().remove();
    });
}

//show market level locations: when map is zoom out too much these locations will appear
function CitySponsors(show) {
    if (show == 1) {
        //show these sponsor's locations
        var ids = GetSponsorID(1);
        if (ids == "0")
            ids = "";           //show all
        else if (ids == "")
            ids = "-1";         //show none
            
        BuildCollection("CitySponsor", "/sponsor/xml/CitySponsors.aspx?id="+ids, 250);
    } else {
        //hide these sponsors
        HideCollection("CitySponsor");
    }
}

//show/hide location points within the boundary area
function SponsorLocations(show) {
    if (show == 1) {
        //show the location points for these sponsors
        var ids = GetSponsorID(1);
        if (ids == "0")
            ids = "";           //show all
        else if (ids == "")
            ids = "-1";         //show none
            
        //extra parameters
        var extraParam = '';
        if (mapKey.profile_id != undefined)
            extraParam += '&profile_id='+mapKey.profile_id;
            
        BuildCollection("sponsor", "/sponsor/xml/Locations.aspx?id="+ids+"&lat="+BoundaryLat+"&lng="+BoundaryLng+extraParam, 300);
    } else {
        //hide the location points
        HideCollection("sponsor");
    }
}


/* ************ Map Camera Functions **************** */

//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 + '?rnd=' + randomNum;
		else
			oImage.src = imageSrc + '&rnd=' + randomNum;
	}
}

//setup click function when a sponsor is click, this need to be resetup everytime the list is updated
function EnableCameraToggle(className) {
    $("." + className).click(function () {
        var active = false;
        var blnZoomFarOut = false;
	    if (ZoomLevel <= MinZoomLevel)
	        blnZoomFarOut = true;

        if (parseInt($(this).attr("active")) == 1) {
            //currently active, so deactivate it
            active = false;
            $(this).attr("active", 0);
            $(this).addClass("inactive");
        } else {
            //currently inactive, so activate it
            active = true;
            $(this).attr("active", 1);
            $(this).removeClass("inactive");
        }
        
        //show/hide these sponsors on the map
        if (active == true) {
            //show
	        if (blnZoomFarOut == true) {
	            //hide any old sponsor points
	            CameraLocations(0);
    	        
	            //show market level sponsor's icon
	            CityCameras(1);
	        } else {
	            //show individual sponsor's points within boundary area
    	        
	            //first hide the market level icons
	            CityCameras(0);
    	        
	            //get the location's within this boundary area
	            CameraLocations(1);
	        }
        } else {
            //hide
            CityCameras(0);
            CameraLocations(0);
        }
    });
}

//show market level locations: when map is zoom out too much these locations will appear
function CityCameras(show) {
    if (show == 1) {
        //show these camera's locations
        BuildCollection("CityCamera", "/camera/xml/CityCameras.aspx", 250);
    } else {
        //hide these cameras
        HideCollection("CityCamera");
    }
}

//show/hide location points within the boundary area
function CameraLocations(show) {
    if (show == 1) {
        //show the location points for these cameras
            
        //extra parameters
        var extraParam = '';
        if (mapKey.profile_id != undefined)
            extraParam += '&profile_id='+mapKey.profile_id;
            
        BuildCollection("camera", "/camera/xml/Locations.aspx?lat="+BoundaryLat+"&lng="+BoundaryLng+extraParam, 240);
    } else {
        //hide the location points
        HideCollection("camera");
    }
}


/* ************ Flow Functions For End User **************** */

//reverse geocode lat/lng to get City settings
function UpdateCityInfo() {
    var blnUpdate = true;
	var CityID = parseInt(mapKey.CityID);
	var newCityID = 0;
	var xCityID, xCamera, xSponsor, xFlow, xNWLatLng, xSELatLng;
	
    var url = '/feeds/map/CitySettings.aspx?key='+mapKey.AccountKey+'&lat='+CenterLat+'&lng='+CenterLng;
    $.get(url, {}, function(xml) {
	    //builds the collection
        $('city', xml).each(function(i) {            
	        xCityID = parseInt($(this).attr("ID"));
	        if (i == 0) {
	            newCityID = xCityID;	         
		        xFlow = $(this).attr("FlowActive");
		        xCamera = $(this).find("camera").attr("Active");
		        xSponsor = $(this).find("sponsor").attr("Active");
		        xNWLatLng = $(this).find("north_west").text();
		        xSELatLng = $(this).find("south_east").text();
	        }
	        
	        if (xCityID == CityID) {
	            blnUpdate = false;
	        }
        });
        
	    //another way to check if we need to display a flow
	    if (flowLayer == null)
		    blnUpdate = true;
		    
        if (blnUpdate == true && newCityID > 0) {
            //update new city data
		    if (xFlow == "true")
			    xFlow = 1;
		    else
			    xFlow = 0;
		    if (xCamera == "true")
			    xCamera = 1;
		    else
			    xCamera = 0;
		    if (xSponsor == "true")
			    xSponsor = 1;
		    else
			    xSponsor = 0;
			    
       		//save the new settings
       		mapKey.CityID = newCityID;
       		mapKey.Flow = xFlow;
       		mapKey.Camera = xCamera;
       		mapKey.Sponsor = xSponsor;

		    if (xNWLatLng > '' && xSELatLng > '') {
			    var arrNWLatLng = xNWLatLng.split(",");
			    var arrSELatLng = xSELatLng.split(",");

			    CitySWPoint = new GLatLng(arrSELatLng[0], arrNWLatLng[1]);
			    CityNEPoint = new GLatLng(arrNWLatLng[0], arrSELatLng[1]);
		    } else {
			    //must have boundary area, else can't display flow
			    if (flowLayer)
				    map.removeOverlay(flowLayer);

			    mapKey.Flow = 0;
			    flowBoundaries = null;
			    flowLayer = null;
		    }
    		    
		    if (mapKey.Flow == "1") {	
			    flowBoundaries = new GLatLngBounds(CitySWPoint, CityNEPoint);
		    }
		    
    
		    //show options if they exists
		    var oCameraOption = document.getElementById('chkCamera');
		    if (oCameraOption) {
			    if (mapKey.Camera == "1") {
				    oCameraOption.className = 'show';
				    oCameraOption.parentNode.style.visibility = 'visible';
			    } else {
				    oCameraOption.className = 'hide';
				    oCameraOption.parentNode.style.visibility = 'hidden';
			    }

		    }
		    var oSponsorOption = document.getElementById('chkSponsor');
		    if (oSponsorOption) {
			    if (mapKey.Sponsor == "1") {
				    oSponsorOption.className = 'show';
				    oSponsorOption.parentNode.style.visibility = 'visible';
			    } else {
				    oSponsorOption.className = 'hide';
				    oSponsorOption.parentNode.style.visibility = 'hidden';
			    }
		    }	
        } 
                
        //load flow polylines and points
        LoadFlow(mapKey.CityID, ZoomLevel);
	    
	    //show traffic pushpins
	    BuildRemoteCollections();
    });
}

//function will display all the flow highlighted points
function BuildFlowHighlights(cityID) {
	//var oFlow = document.getElementById('chkFlow');
	var blnShowLocs = false;
    var showFlowLocs = false;
	var minZoomFlowLoc = parseInt(mapKey.MinZoomFlow);
	var maxZoomFlowLoc = parseInt(mapKey.MaxZoomFlow);
	if (ZoomLevel >= minZoomFlowLoc && ZoomLevel <= maxZoomFlowLoc)
		blnShowLocs = true;
    if (mapKey.FlowLocs == "1" && DisplayFlow == 1)
        showFlowLocs = true;
        
	if (reload == true) {
		HideCollection('flowHighlight');
		DeleteCollection('flowHighlight');        
        
		if (showFlowLocs == true && blnShowLocs == true && flowBoundaries) {
			var url = "/feeds/map/FlowLocations.aspx?id="+cityID+"&lat="+BoundaryLat+"&lng="+BoundaryLng;
            $.get(url, {}, function(xml) {
    	        //builds the collection
	            $('Location', xml).each(function(i) {
		            xType = "flowHighlight";
		            xID = $(this).attr("ID");
		            xLat = $(this).attr("Lat");
		            xLng = $(this).attr("Lng");
		            xColor = $(this).find("Severity").text();
		            xTitle = $(this).find("Title").text();
		            xDescription = $(this).find("Description").text();

			        //icon info
			        iconURL = websiteURL + 'images/general/';
		            xIconName = iconURL + 'dot-'+xColor+'.png';
                    xIconHover = '';
			        xIconWidth = '5';
			        xIconHeight = '5';
			        infoWinWidth = 300;

		            if (xLat > '' && xLng > '') {
			            //build the marker class
			            var oMarker = new Marker;
			            oMarker.ID = 'flowHighlight_' + xID;
			            oMarker.Type = xType;
			            oMarker.Icon = xIconName;
			            oMarker.IconHover = xIconHover;
			            oMarker.Width = parseInt(xIconWidth);
			            oMarker.Height = parseInt(xIconHeight);
			            oMarker.Lat = xLat;
			            oMarker.Lng = xLng;
			            oMarker.Title = xTitle;
			            oMarker.Description = xDescription;
			            oMarker.Color = xColor;
    			        
			            //create the google marker
			            var oGMarker = CreateMarker(oMarker, infoWinWidth);
			            oMarker.GMarker = oGMarker;

			            //add it to the array of markers
			            markers[oMarker.ID] = oMarker;
		            }
	            });
    	        
	            //show it
	            ShowCollection("flowHighlight");
	        });
		}
	}
}

//load a new flow layer
function LoadFlow(cityID, zoom) {
	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.onerror = function () { HideCollection('flowHighlight'); };
	oImage.src = imgFlowLayer;
}

//handler to be completed if flow layer exists
function LoadingFlow(cityID, zoom) {
	var imgFlowLayer = mapLayerServer + "layers/"+cityID+"/"+cityID+"_FlowCoverage_"+zoom+".png"
	
	if (flowBoundaries) {
		flowLayer = new GGroundOverlay(imgFlowLayer, flowBoundaries);
		map.addOverlay(flowLayer);		
		BuildFlowHighlights(cityID);
		
	    if (DisplayFlow == 0)
		    HideFlow();
	}
}

function ShowFlow() {
	//var oFlow = document.getElementById('chkFlow');
	if (flowLayer && DisplayFlow == 1) {
		flowLayer.show();
		ShowCollection('flowHighlight');
	} else if (flowLayer) {
		flowLayer.hide();
		HideCollection('flowHighlight');
	}
}

function HideFlow() {
	if (flowLayer)
		flowLayer.hide();

	//hide the highlighted points
	HideCollection('flowHighlight');
}

/* ------------------ Toogle Options ---------------------- */

//show a particular option on the map
function Show(theType) {
	//only show items if statisfy zoom min requirement
	if (ZoomLevel >= MinZoomLevel) {
		if (theType == "all") {
			if (DisplayFlow == 1)
				Show('flow');
			if (DisplayIncident == 1)
				Show('incident');
			if (DisplayConstruction == 1)
				Show('construction');
			if (DisplayCamera == 1)
				Show('camera');
			if (DisplaySponsor == 1)
				Show('sponsor');
		} else {
			//show the CCTraffic flow lines, only if actived
			var flowActive = false;
			if (mapKey.Flow == "1")
			    flowActive = true;
			if (theType == 'flow' && flowActive == true)
				ShowFlow();

			//show all items in this collection
			ShowCollection(theType);
		}
	}
}

//hide a particular option on the map
function Hide(theType) {
	if (theType == 'all') {
		//hide all collection
		Hide('flow');
		Hide('incident');
		Hide('construction');
		Hide('camera');
		Hide('sponsor');
	} else {
		//hiding a single collection
		//hide the CCTraffic flow lines, only if actived
		var flowActive = false;
		if (mapKey.Flow == "1")
		    flowActive = true;
		if (theType == 'flow' && flowActive == true) {
			HideFlow();
		}

		//hide all the items of this collection
		HideCollection(theType);
	}
}

//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
		var CityID = mapKey.CityID;
		var flowActive = false;
		if (mapKey.Flow == "1")
		    flowActive = true;

		if (reload == true) {
			if (flowActive == false) {
			    //build flow collection icons, since this market's flow lines don't exists yet
			    colURL = "/feeds/map/Traffic.aspx?id="+CityID+"&type=flow&max="+mapKey.MaxRecord+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng+"&sort=severity_priority%20asc";				
			    BuildCollection('flow', colURL);
			}

			//build incident collection
		    colURL = "/feeds/map/Traffic.aspx?id="+CityID+"&type=incident,event&max="+mapKey.MaxRecord+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng+"&sort=severity_priority%20asc";
		    BuildCollection('incident', colURL);

			//build construction collection
		    colURL = "/feeds/map/Traffic.aspx?id="+CityID+"&type=construction&max="+mapKey.MaxRecord+"&bLat="+BoundaryLat+"&bLng="+BoundaryLng;
		    BuildCollection('construction', colURL);

			//build camera collection, if exists
			if (mapKey.Camera == "1") {
				colURL = "/feeds/map/Cameras.aspx?key="+mapKey.AccountKey+"&city="+CityID+"&max=25&lat="+BoundaryLat+"&lng="+BoundaryLng;
				BuildCollection('camera', colURL, 250);
			}

			//build sponsor collection, if exists
			if (mapKey.Sponsor == "1") {
				colURL = "/feeds/map/Sponsors.aspx?key="+mapKey.AccountKey+"&city="+CityID+"&max=25&lat="+BoundaryLat+"&lng="+BoundaryLng;
				BuildCollection('sponsor', colURL);
			}
		}
	} else
		Hide("all");
}