﻿Array.prototype.remove = function(from, to){
	var rest = this.slice((to || from) + 1 || this.length);
	this.length = from < 0 ? this.length + from : from;
	return this.push.apply(this, rest);
};

Array.prototype.intersection = function( setB ) {  
   var setA = this;  
  
   var setA_seen = {};  
   var setB_seen = {};  
   for ( var i = 0; i < setB.length; i++ ) {  
      setB_seen[ setB[i] ] = true;  
   }  
  
   var intersection = [];  
   for ( var i = 0; i < setA.length; i++ ) {  
      if ( !setA_seen[ setA[i] ] ) {  
         setA_seen[ setA[i] ] = true;  
         if ( setB_seen[ setA[i] ] ) {  
            intersection.push( setA[i] );  
         }  
      }  
   }  
   return intersection;  
};  

var map;
var mapIcon;
var mapIconHighlight;
var xmlHttp;
var cities;
var filters;
var currentCenter;
var currentZoom;
var operand = "and";

var naCenter = new GLatLng(37.0625, -95.677068);
var naZoom = 4;
var hawaiiCenter = new GLatLng(20.385825381874263, -157.8076171875);
var hawaiiZoom = 7;
var alaskaCenter = new GLatLng(63.58767529470318, -161.982421875);
var alaskaZoom = 4;

function ContinentSwitchControl() { }

ContinentSwitchControl.prototype = new GControl();

ContinentSwitchControl.prototype.initialize = function(currentMap) {
	var container = document.createElement("div");

	var northAmericaDiv = document.createElement("div");
	this.setButtonStyle_(northAmericaDiv);
	container.appendChild(northAmericaDiv);
	northAmericaDiv.appendChild(document.createTextNode("North America"));
	GEvent.addDomListener(northAmericaDiv, "click", function() {
		map.closeInfoWindow();
		map.setMapType(G_NORMAL_MAP);
		map.setCenter(naCenter, naZoom);
	});
	
	var hawaiiDiv = document.createElement("div"); 
	this.setButtonStyle_(hawaiiDiv);
	container.appendChild(hawaiiDiv);
	hawaiiDiv.appendChild(document.createTextNode("Hawaii"));
	GEvent.addDomListener(hawaiiDiv, "click", function() {
		map.closeInfoWindow();
		map.setMapType(G_NORMAL_MAP);
		map.setCenter(hawaiiCenter, hawaiiZoom);
	});
	
	/*
	var alaskaDiv = document.createElement("div"); 
	this.setButtonStyle_(alaskaDiv);
	container.appendChild(alaskaDiv);
	alaskaDiv.appendChild(document.createTextNode("Alaska"));
	GEvent.addDomListener(alaskaDiv, "click", function() {
		map.closeInfoWindow();
		//map.setMapType(G_NORMAL_MAP);
		map.setCenter(alaskaCenter, alaskaZoom);
	});
	*/
	
	currentMap.getContainer().appendChild(container);
	return container;
}

ContinentSwitchControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(7, 45));
}

ContinentSwitchControl.prototype.setButtonStyle_ = function(button) {
	button.style.textDecoration = "none";
	button.style.color = "#000";
	button.style.backgroundColor = "#fff";
	button.style.font = "12px Arial";
	button.style.border = "1px solid black";
	button.style.paddingTop = "1px";
	button.style.marginBottom = "2px";
	button.style.textAlign = "center";
	button.style.width = "88px"
	button.style.height = "16px";
	button.style.cursor = "pointer";
}


function DisplayCities()
{
	map.clearOverlays();
	if(map.getCurrentMapType() == G_HYBRID_MAP)
    {
        map.setMapType(G_NORMAL_MAP);
	    map.setCenter(naCenter, naZoom);
	}
	for (var i = 0; i < cities.length; i++)
	{
		var found = false;
		if(filters.length > 0)
		{
		    for (var j = 0; j < cities[i].getElementsByTagName('CityCharacteristic').length; j++)
		    {
		        for (var k = 0; k < filters.length; k++)
		        {
		            if(operand == "or")
		            {
	                    if (cities[i].getElementsByTagName('CityCharacteristic')[j].attributes.getNamedItem('Id').value == filters[k])
	                    {
		                    found = true;
	                        break;
	                    }
	                }
	                else
	                {
	                    // load this city's characteristics in an array
	                    var cityChar = new Array();
	                    for( var l = 0; l < cities[i].getElementsByTagName('CityCharacteristic').length; l++)
	                    {
	                        cityChar.push(cities[i].getElementsByTagName('CityCharacteristic')[l].attributes.getNamedItem('Id').value);
	                    }
	                    
	                    var intersectArray = cityChar.intersection(filters);
	                    if(filters.length == intersectArray.length)
	                    {
	                        found = true;
	                        break;
	                    }
	                }
		        }
		        
		        if (found)
    		    {
                    break;
		        }
		    }
		}
		else
		{
		    found = true;
		}
	
		if (found)
		{
			var latitude = parseFloat(cities[i].getElementsByTagName('Latitude')[0].firstChild.nodeValue);
			var longitude = parseFloat(cities[i].getElementsByTagName('Longitude')[0].firstChild.nodeValue);						
			var cityId = cities[i].getElementsByTagName('Id')[0].firstChild.nodeValue;
			var cityName = cities[i].getElementsByTagName('Name')[0].firstChild.nodeValue;
			var stateName = cities[i].getElementsByTagName('State')[0].firstChild.nodeValue;
			
			CreateMarkers(new GLatLng(latitude, longitude), cityId, cityName + ', ' + stateName);
		}
	}
}

function CreateMarkers(point, id, cityTitle)
{
	var normalMarker = new GMarker(point, { icon:mapIcon });
	var highlightMarker = new GMarker(point, { icon:mapIconHighlight, title:cityTitle });		
	highlightMarker.bindInfoWindowHtml(CreateInfoWindowHtml(id));   
	
	var city = GetCityById(id);
	var zoomLevel = parseFloat(city.getElementsByTagName('ZoomLevel')[0].firstChild.nodeValue);
	var zoomLat = parseFloat(city.getElementsByTagName('ZoomLatitude')[0].firstChild.nodeValue);
	var zoomLong = parseFloat(city.getElementsByTagName('ZoomLongitude')[0].firstChild.nodeValue);
	
	GEvent.addListener(normalMarker, "mouseover", function(){
		normalMarker.hide();
		highlightMarker.show();
	});
	
	GEvent.addListener(highlightMarker, "mouseout", function(){
		normalMarker.show();
		highlightMarker.hide();
	});
	
	GEvent.addListener(highlightMarker, "click", function(){
	
	    if(map.getCurrentMapType() == G_NORMAL_MAP)
	    {
		    currentCenter = map.getCenter();
		    currentZoom = map.getZoom();
		}
		map.setMapType(G_HYBRID_MAP);
		map.setCenter(new GLatLng(zoomLat, zoomLong), zoomLevel);
	});
	
	map.addOverlay(normalMarker);
	map.addOverlay(highlightMarker);
	
	highlightMarker.hide();
}

function CreateInfoWindowHtml(id)
{
	var html = '';
	var city = GetCityById(id);
	if (city != null)
	{
		var cityName = city.getElementsByTagName('Name')[0].firstChild.nodeValue;
		var stateName = city.getElementsByTagName('State')[0].firstChild.nodeValue;
		var xmlPath = xmlHttp.responseXML.getElementsByTagName('XmlPath')[0].firstChild.nodeValue;
	
		html = '<div style="width:450px;"><h1 style="margin: 0; padding: 0; font-size: 18px; font-family: \'Trebuchet MS\', Arial, Sans-Serif;width:300px;float:left;">' + cityName + ', ' + stateName + '</h1><a id="backToMapLink" style="float:right;color:#6261d8;margin-right:25px;margin-top:-7px;" href="javascript:void(0);" onclick="BackToMap();">Back to Larger Map</a>'
		+ '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="450" height="349" id="mapFlash" align="middle">'
		+ '<param name="allowScriptAccess" value="sameDomain" />'
		+ '<param name="allowFullScreen" value="false" />'
		+ '<param name="movie" value="flash/SmartGrowthFlash.swf?cityId=' + id + '&xmlPath=' + xmlPath + '" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /><embed src="flash/SmartGrowthFlash.swf?cityId=' + id + '&xmlPath=' + xmlPath + '" quality="high" bgcolor="#ffffff" width="450" height="349" name="mapFlash" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />'
		+ '</object></div>';
	}          
	return html;
}

function BackToMap() {
    map.getInfoWindow().hide();
	map.setMapType(G_NORMAL_MAP);
	map.setCenter(currentCenter, currentZoom);
};

function GetCityById(id)
{
	for (var i = 0; i < cities.length; i++)
	{
		if (cities[i].getElementsByTagName('Id')[0].firstChild.nodeValue == id)
			return cities[i];
	}
	return null;
}

function Filter(checkbox)
{
    if (checkbox.checked)
	    filters.push(checkbox.name);
    else
    {
	    for (var i = 0; i < filters.length; i++)
	    {
		    if (filters[i] == checkbox.name)
		    {
			    filters.remove(i);
			    break;
		    }
	    }
    }
	DisplayCities();
}

function ClearFiltersAndCities()
{
	var filterContainer = document.getElementById('mapFilters').childNodes;
	for (var i = 0; i < filterContainer.length; i++)
	{
		var filterCheckboxes = filterContainer[i].childNodes;
		for (var j = 0; j < filterCheckboxes.length; j++)
		{
			if (filterCheckboxes[j].nodeName == 'DIV')
			{
				for (var k = 0; k < filterCheckboxes[j].childNodes.length; k++)
				{
				    if (filterCheckboxes[j].childNodes[k].checked)
					    filterCheckboxes[j].childNodes[k].checked = false
				}
			}
			else if(filterCheckboxes[j].checked) 
			    filterCheckboxes[j].checked = false;
		}
	}
	
	LoadFilters();
	DisplayCities();
}

function toggleSearchOptions(radioButton)
{
    operand = radioButton.value;
    LoadFilters();
    DisplayCities();
}

function LoadFilters()
{
	filters = new Array();
	
	var filterContainer = document.getElementById('mapFilters').childNodes;
	for (var i = 0; i < filterContainer.length; i++)
	{
		var filterCheckboxes = filterContainer[i].childNodes;
		for (var j = 0; j < filterCheckboxes.length; j++)
		{
			if (filterCheckboxes[j].nodeName == 'DIV')
			{
				for (var k = 0; k < filterCheckboxes[j].childNodes.length; k++)
				{
					if (filterCheckboxes[j].childNodes[k].checked)
						filters.push(filterCheckboxes[j].childNodes[k].name);
				}
			}
			else if (filterCheckboxes[j].checked)
				filters.push(filterCheckboxes[j].name);
		}
	}
}

function LoadXml(url)
{
	if (window.XMLHttpRequest)
		xmlHttp = new XMLHttpRequest();
	else if (window.ActiveXObject)
		xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
		
	if (xmlHttp != null)
	{
		xmlHttp.onreadystatechange = OnXmlLoaded;
		xmlHttp.open('GET', url, true);
		xmlHttp.send(null);
	}
}

function OnXmlLoaded()
{
	if (xmlHttp.readyState == 4)
	{
		if (xmlHttp.status == 200)
		{
			cities = xmlHttp.responseXML.getElementsByTagName('Cities')[0].getElementsByTagName('City');
			LoadFilters();
			DisplayCities();
		}
		else
			alert('Error Loading Map Data: ' + xmlHttp.statusText);
	}
}

function Load()
{
	if (GBrowserIsCompatible())
	{
		map = new GMap2(document.getElementById('map'));
		map.setCenter(naCenter, naZoom);
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		map.addControl(new ContinentSwitchControl());
		
		mapIcon = new GIcon();
		mapIcon.image = '_images/map_icon.png';
		mapIcon.shadow = '_images/map_shadow.png';
		mapIcon.iconSize = new GSize(36, 39);
		mapIcon.shadowSize = new GSize(46, 39);
		mapIcon.iconAnchor = new GPoint(8, 36);
		mapIcon.infoWindowAnchor = new GPoint(16, 2);
		
		mapIconHighlight = new GIcon();
		mapIconHighlight.image = '_images/map_icon_highlight.png';
		mapIconHighlight.shadow = '_images/map_shadow.png';
		mapIconHighlight.iconSize = new GSize(36, 39);
		mapIconHighlight.shadowSize = new GSize(46, 39);
		mapIconHighlight.iconAnchor = new GPoint(8, 36);
		mapIconHighlight.infoWindowAnchor = new GPoint(16, 2);

		LoadXml('xml/SmartGrowth.xml');
	}
}

/*
function WriteCoords()
{
	var center = map.getCenter();
	var zoom = map.getZoom();

	if (center && zoom)
	{
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		var s = fso.CreateTextFile("C:\\temp\\coord.txt", true);
		s.WriteLine('<ZoomLevel>' + zoom + '</ZoomLevel>');
		s.WriteLine('<ZoomLatitude>' + center.lat() + '</ZoomLatitude>');
		s.WriteLine('<ZoomLongitude>' + center.lng() + '</ZoomLongitude>');
		s.Close();
	}
}
*/
