var GoogleMap = Class.create()
GoogleMap.prototype = 
{
  initialize: function(ClientID, Toolbar, RouteListClientId, LocationListClientId, 
		RouteXml, HoldingDiv)
  {
    this.ClientID = ClientID;
		
		this.Toolbar = Toolbar;
		
		this.RouteListClientId = RouteListClientId;
		
		this.LocationListClientId = LocationListClientId;
		
    this.HoldingDiv = $(HoldingDiv);

    this.XmlData = RouteXml;
		
		this.RouteSelect = $('RouteSelect');
		this.LineWidthSelect = $('LineWidthSelect');
		this.ApplyLineWidthToAllChkBox = $('ApplyLineWidthToAllChkBox');
    
    this.Map = null;
    this.GeoCoder = null;
		
		this.GainesvilleCenter = new GLatLng(29.652071, -82.339444);
    
    this.InitializeMap(this.HoldingDiv);
    
		this.Route = new Array(75);
		
		this.Line = new Array(75);
		
		this.CurrentRouteId = null;
		this.LineWidth = this.LineWidthSelect.options[this.LineWidthSelect.selectedIndex].value;
		
		this.ApplyWidthToAll = this.ApplyLineWidthToAllChkBox.checked;
		
		$Browser.WheelScrolledUp = function() {alert('up')};
		
		this.InitializeCheckBoxLists();
		
		this.IconList = new ArrayList();
		this.BuildIcons();
		
		this.BusStopIcon = this.InitializeBusStopIcon();
		
  },
  
  InitializeMap: function(HoldingDiv)
  {
    if (GBrowserIsCompatible()) 
    {
      this.Map = new GMap2(this.HoldingDiv);
      this.GeoCoder = new GClientGeocoder();
			this.GainesvilleBounds = new GLatLngBounds(new GLatLng('29.741128366092113','-82.51007080078125'),
				new GLatLng('29.520890519025357','-82.2052001953125')); 
			
      GEvent.addListener(this.Map, "click", function(marker, point) {
				this.MapOnClick(marker, point);
      }.bind(this));
			
			
      
      this.Map.addControl(new GLargeMapControl());
      
      this.ShowMap();
    }
  },
	
	InitializeCheckBoxLists: function()
	{
		var routeNodes = this.XmlData.selectNodes('//Route');
		
		var node;
		for(var i = 0; node = routeNodes[i]; i++)
		{
			if(!node)
				continue;
				
			var checkBox = $(this.RouteListClientId + '_' + i);
			
			if(checkBox == null)
				continue;
			
			var self = this;
			checkBox.onclick = function()
			{
				var td = this.parentNode;
				var routeToDraw = td.childNodes[1].innerHTML;
				self.CurrentRouteId = routeToDraw;
				if(this.checked == true)
					self.DrawLine(routeToDraw, td.childNodes[1]);
				else
					self.EraseLine(routeToDraw, td.childNodes[1])
			};
		}
		
		var icons = this.XmlData.selectNodes('//MapIcon');
		for(var i = 0; node = icons[i]; i++)
		{
			if(!node)
				continue;
				
			var checkBox = $(this.LocationListClientId + '_' + i);
			
			if(checkBox == null)
				continue;
				
			checkBox.checked = true;
				
			var self = this;
			checkBox.onclick = function()
			{
				var td = this.parentNode;
				var iconToDraw = td.childNodes[1].innerHTML;
				if(this.checked == true)
					self.BuildIcons(iconToDraw);
				else
					self.HideIcons(iconToDraw);
			};
		}
	},
	
	InitializeBusStopIcon: function()
	{
		icon = new GIcon();
		var busStopIconXml = this.XmlData.selectSingleNode('/MapInfo/BusStopIcon');
		
		icon.image = busStopIconXml.getAttribute('ImageUrl');
		icon.shadow = busStopIconXml.getAttribute('ShadowUrl');
		icon.iconSize = new GSize(busStopIconXml.getAttribute('IconSizeX'), busStopIconXml.getAttribute('IconSizeY'));
		icon.shadowSize = new GSize(busStopIconXml.getAttribute('ShadowSizeX'), busStopIconXml.getAttribute('ShadowSizeY'));
		icon.iconAnchor = new GPoint(busStopIconXml.getAttribute('IconAnchorX'), busStopIconXml.getAttribute('IconAnchorY'));
		icon.infoWindowAnchor = new GPoint(busStopIconXml.getAttribute('InfoWindowAnchorX'), busStopIconXml.getAttribute('InfoWindowAnchorY'));
		
		return icon;
	},
	
	BuildIcons: function(IconType)
	{
		var icons;
		if(!IconType)
			icons = this.XmlData.selectNodes('//MapIcon');
		else
			icons = this.XmlData.selectNodes('//MapIcon[@IconType="' + IconType + '"]');
		
		$A(icons).each(function(icon)
		{
			var mapIcon = new GIcon();
			mapIcon.image = icon.getAttribute('ImageUrl');
			mapIcon.shadow = icon.getAttribute('ShadowUrl');
			mapIcon.iconSize = new GSize(icon.getAttribute('IconSizeX'), icon.getAttribute('IconSizeY'));
			mapIcon.shadowSize = new GSize(icon.getAttribute('ShadowSizeX'), icon.getAttribute('ShadowSizeY'));
			mapIcon.iconAnchor = new GPoint(icon.getAttribute('IconAnchorX'), icon.getAttribute('IconAnchorY'));
			mapIcon.infoWindowAnchor = new GPoint(icon.getAttribute('InfoWindowAnchorX'), icon.getAttribute('InfoWindowAnchorY'));
			
			var foundIconType = false;
			if(this.IconList.Count() > 0)
			{
				$A(this.IconList.aList).each(function(listObj)
				{
					if(listObj.IconType == icon.getAttribute('IconType'))
					{
						foundIconType = true;
						this.Map.addOverlay(listObj.Marker);
					}
				}.bind(this));
			}
			
			if(!foundIconType)
			{
				$A(icon.selectNodes('.//MapIconLocation')).each(function(location)
				{
					var point = new GLatLng(location.getAttribute('Latitude'), location.getAttribute('Longitude'));
					var marker = new GMarker(point, mapIcon);
					marker._IconType = icon.getAttribute('IconType');
					marker._Text = location.getAttribute('Text') + '<br />' + location.getAttribute('Description');
					this.IconList.Add({IconType:icon.getAttribute('IconType'), Marker:marker});
					this.Map.addOverlay(marker);
				}.bind(this));
			}
		}.bind(this));
	},
	
	HideIcons: function(IconType)
	{
		var icons;
		if(!IconType)
			icons = this.XmlData.selectNodes('//MapIcon');
		else
			icons = this.XmlData.selectNodes('//MapIcon[@IconType="' + IconType + '"]');

		$A(icons).each(function(icon)
		{
			$A(this.IconList.aList).each(function(listObj)
			{
				if(listObj.IconType == icon.getAttribute('IconType'))
					this.Map.removeOverlay(listObj.Marker);
			}.bind(this));
		}.bind(this));
	},
	
	MapOnClick: function(marker, point)
	{
		var event = $Browser.GetEvent();
		this.HideAllMenus();
		if (marker)
		{
			//this.Map.closeInfoWindow();
			if(marker._Text)
				marker.openInfoWindowHtml(marker._Text);
		} 
		else if(event && event.ctrlKey )
		{
			marker = new GMarker(point)
			this.Map.addOverlay(marker);
			
			marker._Text = 'Lat.: ' + point.y + '; Long.: ' + point.x;
			marker.openInfoWindowHtml(marker._Text);
 			if(this.Route[this.CurrentRouteId])
			{
				/* this.Route[this.CurrentRouteId].AddPoint(point.y, point.x);
				this.Map.removeOverlay(this.Line[this.CurrentRouteId]);
				this.Line[this.CurrentRouteId] = this.Route[this.CurrentRouteId].GetPolyLine(this.LineWidth)
				this.Map.addOverlay(this.Line[this.CurrentRouteId]); */
			}
			else
			{
				//this.Route[this.CurrentRouteId] = new Route(this.XmlData, this.CurrentRouteId);
			}
		}
	},
	
	HandleDownload: function(data, responseCode)
  {
		if(responseCode == "200")
			this.XmlData = new XmlDocument(data);
		else
			alert('Error');
  },
	
	RouteChanged: function(SelectBox)
	{
		this.CurrentRouteId = SelectBox.options[SelectBox.selectedIndex].value;
	},
	
	LineWidthChanged: function(SelectBox)
	{
		this.LineWidth = SelectBox.options[SelectBox.selectedIndex].value;
		
		if(this.ApplyWidthToAll)
		{
			$A(this.Route).each(function(route)
			{
				if(route)
				{
					this.Map.removeOverlay(this.Line[route.RouteId]);
					this.Line[route.RouteId] = route.GetPolyLine(this.LineWidth);
					this.Map.addOverlay(this.Line[route.RouteId]);
				}
			}.bind(this));
		}
	},
	
	ToggleApplyLineWidthToAll: function()
	{
		this.ApplyWidthToAll = !this.ApplyWidthToAll;
	},
  
  ShowMap: function()
  {
    this.Map.setCenter(this.GainesvilleCenter, 13);
  },
  
  DrawLine: function(RouteId, chkBoxTextElement)
  {
		if(!RouteId)
			RouteId = this.CurrentRouteId;
			
		if(!this.Route[RouteId])
			this.Route[RouteId] = new Route(this.XmlData, RouteId, this.BusStopIcon);
		
		chkBoxTextElement.style.color = this.Route[RouteId].LineColor;
		
		if(this.Line[RouteId])
			this.Map.removeOverlay(this.Line[RouteId]);
		this.Line[RouteId] = this.Route[RouteId].GetPolyLine(this.LineWidth)
		
		//draw busstops
		this.Route[RouteId].DrawBusStops(this.Map);
    
		this.Map.addOverlay(this.Line[RouteId]);
  },
	
	EraseLine: function(RouteId, chkBoxTextElement)
	{
		if(!RouteId)
			RouteId = this.Line[this.CurrentRouteId]
			
		chkBoxTextElement.style.color = "#000000";
			
		this.Map.removeOverlay(this.Line[RouteId]);
		this.Route[RouteId].HideBusStops(this.Map);
	},
	
	GetXml: function()
	{
		debugger;
	},
  
  ShowAddress: function(address)
  {
    this.GeoCoder.getLatLng(address, function(point) 
		{
      if (!point) {
        alert(address + " not found. \nMake sure you enter \"Gainesville, FL\" and you zipcode.");
      } else {
        this.Map.setCenter(point, 13);
        var marker = new GMarker(point);
        this.Map.addOverlay(marker);
        marker.openInfoWindowHtml(address);
      }
    }.bind(this)
  );
  },
	
	ShowAddressFinder:function(buttonInfo)
	{
		
		buttonInfo.TextElement.innerHTML = "Hide Address";
		buttonInfo.OnClickFunc = this.ClientID + ".HideAddressFinder"
	
		this.HideAllMenus();
	
		Effect.SlideDown($('InputAddressDiv'), {duration:.5});
	},
	
	HideAddressFinder:function(buttonInfo)
	{
		buttonInfo.TextElement.innerHTML = "Address";
		buttonInfo.OnClickFunc = this.ClientID + ".ShowAddressFinder"
	
		Effect.SlideUp($('InputAddressDiv'), {duration:.5});
	},
	
	ShowRoutes: function(buttonInfo)
	{
		buttonInfo.TextElement.innerHTML = "Hide Routes";
		buttonInfo.OnClickFunc = this.ClientID + ".HideRoutes"

		this.HideAllMenus();
		
		Effect.SlideDown($('RoutesListDiv'), {duration:.5});
	},
	
	HideRoutes: function(buttonInfo)
	{
		buttonInfo.TextElement.innerHTML = "Routes";
		buttonInfo.OnClickFunc = this.ClientID + ".ShowRoutes";

		Effect.SlideUp($('RoutesListDiv'), {duration:.5});
	},
	
	ShowLocations:function(buttonInfo)
	{
		buttonInfo.TextElement.innerHTML = 'Hide Locations';
		buttonInfo.OnClickFunc = this.ClientID + ".HideLocations";
		
		this.HideAllMenus();
		
		Effect.SlideDown($('LocationsDiv'), {duration:.5});
	},
	
	HideLocations:function(buttonInfo)
	{
		buttonInfo.TextElement.innerHTML = 'Locations';
		buttonInfo.OnClickFunc = this.ClientID + ".ShowLocations";
		
		Effect.SlideUp($('LocationsDiv'), {duration:.5});
	},
	
	ShowOptions: function(buttonInfo)
	{
		buttonInfo.TextElement.innerHTML = 'Hide Options';
		buttonInfo.OnClickFunc = this.ClientID + ".HideOptions";
		
		this.HideAllMenus();
		
		Effect.SlideDown($('OptionsDiv'), {duration:.5});
	},
	
	HideOptions: function(buttonInfo)
	{
		buttonInfo.TextElement.innerHTML = 'Options';
		buttonInfo.OnClickFunc = this.ClientID + ".ShowOptions";
		
		Effect.SlideUp($('OptionsDiv'), {duration:.5});
	},
	
	HideAllMenus: function()
	{
		if($('OptionsDiv').style.display != 'none')
			this.Toolbar.GetButtonByCommandName('Options').Click();
		if($('InputAddressDiv').style.display != 'none')
			this.Toolbar.GetButtonByCommandName('Address').Click();
		if($('LocationsDiv').style.display != 'none')
			this.Toolbar.GetButtonByCommandName('Locations').Click();
		if($('RoutesListDiv').style.display != 'none')
			this.Toolbar.GetButtonByCommandName('Route').Click();
	}
}

var Route = Class.create();
Route.prototype = 
{
  initialize: function(XmlData, RouteId, BusStopIcon)
  {    
    this.RouteId = RouteId;
		
		this.XmlData = new XmlDocument(XmlData.selectSingleNode('//Route[@RouteId=' + this.RouteId + ']').xml);
		
		this.BusStopIcon = BusStopIcon;
		
		this.Points = null;
		
		var routeNode = this.XmlData.selectSingleNode('/Route');
		
		this.LineColor = routeNode.getAttribute('Color');

    var markers = routeNode.selectNodes('./Markers/Marker');

    this.Points = new Array(markers.length);

    this.BuildPoints(markers);
  },
  
	BuildPoints: function(markers)
	{
		for (var i = 0; i < markers.length; i++) {
      var point = new GLatLng(parseFloat(markers[i].getAttribute("Latitude")),
                              parseFloat(markers[i].getAttribute("Longitude")));
      this.Points[i] = point;
    }
	},
	
	AddPoint: function(lat, lng)
	{
		var tempDoc = new XmlDocument('<Marker />')
		var node = tempDoc.selectSingleNode('/Marker');
		node.setAttribute('Latitude', lat);
		node.setAttribute('Longitude', lng);
		this.XmlData.selectSingleNode('//Route[@RouteId=' + this.RouteId + ']/Markers').appendChild(node);
		
		this.BuildPoints(this.XmlData.selectSingleNode('//Route[@RouteId=' + this.RouteId + ']').selectNodes('./Markers/Marker'));
	},
	
	GetPolyLine: function(width)
	{
		return new GPolyline(this.Points, this.LineColor, width);
	},
	
	DrawBusStops: function(map)
	{
		var busStops = this.XmlData.selectNodes('//BusStop');
		this.BusStops = new Array(busStops.length);
		$A(busStops).each(function(stop)
		{
			
			var point = new GLatLng(stop.getAttribute('Latitude'), stop.getAttribute('Longitude'));
			var marker = new GMarker(point, this.BusStopIcon)
			map.addOverlay(marker);
			marker._Text = stop.getAttribute('Name');
			//marker.openInfoWindowHtml(stop.getAttribute('name'));
		
			this.BusStops.push(marker);
		}.bind(this));
	},
	
	HideBusStops: function(map)
	{
		$A(this.BusStops).each(function(stop)
		{
			map.removeOverlay(stop);
		}.bind(this));
	}
}
