/* Sets dimensions for the various content divs */
function setFindAgentMapDimensions()
{
	// Set map height
	contentHeight = getViewportHeight() - document.getElementById("footerArea").offsetHeight - document.getElementById("headerArea").offsetHeight - document.getElementById("findAgentHeader1").offsetHeight - document.getElementById("findAgentHeader2").offsetHeight;
	/*alert("ViewportHeight(): " + getViewportHeight() + "\n" +
		  "footerBar      : " + document.getElementById("footerArea").offsetHeight + "\n" +
		  "headerArea      : " + document.getElementById("headerArea").offsetHeight + "\n" +
		  "findAgentHeader1: " + document.getElementById("findAgentHeader1").offsetHeight + "\n" +
		  "findAgentHeader2: " + document.getElementById("findAgentHeader2").offsetHeight + "\n" +
		  "contentHeight   : " + contentHeight);*/

	// 2px to account for map border
	document.getElementById("mapDiv").style.height = contentHeight-2 + "px";
	document.getElementById("agencyInfoDiv").style.height = contentHeight + "px";
}

function toggleHeader()
{
	/*alert("toggle menu");*/
	headerDiv = document.getElementById("header");
	topmenuDiv = document.getElementById("topmenu");
	submenuDiv = document.getElementById("submenu");
	contentDiv = document.getElementById("content");

	headerDiv.style.display = (headerDiv.style.display != "none") ? "none" : "block";
	topmenuDiv.style.display = (topmenuDiv.style.display != "none") ? "none" : "block";
	submenuDiv.style.display = (submenuDiv.style.display != "none") ? "none" : "block";
	contentDiv.style.top = (contentDiv.style.top != "0px") ? "0px" : "160px";
}

function findByAddress(address, keyCode)
{
	if (keyCode == 13)
	{
			geocoder = new GClientGeocoder();
			geocoder.getLatLng(address, google_geocode_callback);
	}
}

function google_geocode_callback(latlng)
{
	if (!latlng)
	{
		//Address not found
		document.getElementById("geocodeStatusText").style.display="block";
	}
	else
		onMapClick(null, latlng);
}

	/** When user clicks the map, an asychronous call to findAgentAction.findAgents() fires off 
	  * See GMap2.click event for more documentation.  latlng is of type GLatLng */
	function onMapClick(overlay, latlng) 
	{
	if (latlng) 
	{
    	// Clear geocodeStatusText error, if showing
		document.getElementById("geocodeStatusText").style.display="none";
    	
  		// Point global variable "baseLocation" to returned GLatLng
		baseLocation = latlng;

		// Clear map & create new base location marker
  		map.clearOverlays();
			markerOptions = { icon:greenicon, draggable:false }; 
			baseMarker = new GMarker(latlng, markerOptions);
		GEvent.addListener(baseMarker, "dragend", onBaseLocationDrag);
			map.addOverlay(baseMarker);
			map.panTo(latlng);

			// Lookup agents based on point clicked
			Seam.Component.getInstance("findAgentAction").findAgents(latlng.lat(), latlng.lng(), findAgents_callback);
		}
	}
	
	/** Callback function used by findAgentAction.findAgent() 
	  * result is a List<AgentMetadata> */ 
	function findAgents_callback(result)
	{
		// Point global variable "nearbyAgents" to returned List<AgentMetadata>
		nearbyAgents = result;
		
		// Start loading directions asynchronously
		loadDirections();

		// Refresh list of agents below map "agencyInfo"
		// Makes asynchronous call to findAgentAction.getNearbyAgencyList()
		// When complete, callback method activateAgencyList() is called 
		document.getElementById("agencyForm").submit();
		
		// Find bounding box of returned agent locations
		minLat = baseLocation.lat();
		maxLat = baseLocation.lat();
		minLng = baseLocation.lng();
		maxLng = baseLocation.lng();
		
		for (i=0; i < result.length; i++)
		{
			lat = result[i].agency.latitude;
			lng = result[i].agency.longitude;
			
			glatlong = new GLatLng(lat, lng);

			markerOptions = { icon:redicon }; 
			
		agentMarkers[i] = new GMarker(glatlong, markerOptions);
		// Add onClick event to agent markers
		// When clicked, do the same thing as clicking on an agency in the table.
		switch(i)
		{
			case 0: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(0); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(0); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(0); });  break;
			case 1: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(1); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(1); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(1); });  break;
			case 2: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(2); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(2); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(2); });  break;
			case 3: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(3); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(3); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(3); });  break;
			case 4: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(4); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(4); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(4); });  break;
			case 5: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(5); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(5); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(5); });  break;
			case 6: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(6); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(6); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(6); });  break;
			case 7: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(7); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(7); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(7); });  break;
			case 8: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(8); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(8); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(8); });  break;
			case 9: GEvent.addListener(agentMarkers[i], "click", function() { onAgencyInfoClick(9); });  GEvent.addListener(agentMarkers[i], "mouseover", function() { onAgencyInfoMouseover(9); });  GEvent.addListener(agentMarkers[i], "mouseout", function() { onAgencyInfoMouseout(9); });  break;
		}
		
			map.addOverlay(agentMarkers[i]);
			
			minLat = Math.min(minLat, lat);
			minLng = Math.min(minLng, lng);
			maxLat = Math.max(maxLat, lat);
			maxLng = Math.max(maxLng, lng);
  	}

  	// set bounding box (sw corner, ne corner)
  	nearbyAgentsBounds = new GLatLngBounds(new GLatLng(minLat, minLng), new GLatLng(maxLat, maxLng));
  	
	/** Draw Polygon around bounding box.  Debug only.
  	poly = new GPolygon([new GLatLng(minLat, minLng), 
  											 new GLatLng(maxLat, minLng), 
  											 new GLatLng(maxLat, maxLng), 
  											 new GLatLng(minLat, maxLng), 
  											 new GLatLng(minLat, minLng)], "#FF0000", 5, 1);
  	map.addOverlay(poly);
  	*/
  	
	map.panTo(nearbyAgentsBounds.getCenter());
	map.setCenter(nearbyAgentsBounds.getCenter());
	map.setZoom(map.getBoundsZoomLevel(nearbyAgentsBounds));
	}

	/** Callback function for agencyform.oncomplete()
	  * Called after DOM has been updated with new data */
function activateAgencyList()
{
    if (saveSelection)
    {
        // rehighlight selectedAgent
        onAgencyInfoClick(selectedAgent);
    }
    else
    {
        // Reset selectedAgent to none selected (-1)
        selectedAgent = -1;
    }
    
    document.getElementById("agencyForm:agencyInfoStatusText").innerHTML = nearbyAgents.length + " Locations Found.";
    
    // This could all be optimized to reduce # of getElementById() calls.
	if (document.getElementById("agencyForm:agencyInfo")) document.getElementById("agencyForm:agencyInfo").style.display = "block";

	// Bind onclick functions to new DOM elements			
    if (document.getElementById("agencyForm:agencyInfo:0")) document.getElementById("agencyForm:agencyInfo:0").onclick = function() {onAgencyInfoClick(0);};
    if (document.getElementById("agencyForm:agencyInfo:1")) document.getElementById("agencyForm:agencyInfo:1").onclick = function() {onAgencyInfoClick(1);};
    if (document.getElementById("agencyForm:agencyInfo:2")) document.getElementById("agencyForm:agencyInfo:2").onclick = function() {onAgencyInfoClick(2);};
    if (document.getElementById("agencyForm:agencyInfo:3")) document.getElementById("agencyForm:agencyInfo:3").onclick = function() {onAgencyInfoClick(3);};
    if (document.getElementById("agencyForm:agencyInfo:4")) document.getElementById("agencyForm:agencyInfo:4").onclick = function() {onAgencyInfoClick(4);};
    if (document.getElementById("agencyForm:agencyInfo:5")) document.getElementById("agencyForm:agencyInfo:5").onclick = function() {onAgencyInfoClick(5);};
    if (document.getElementById("agencyForm:agencyInfo:6")) document.getElementById("agencyForm:agencyInfo:6").onclick = function() {onAgencyInfoClick(6);};
    if (document.getElementById("agencyForm:agencyInfo:7")) document.getElementById("agencyForm:agencyInfo:7").onclick = function() {onAgencyInfoClick(7);};
    if (document.getElementById("agencyForm:agencyInfo:8")) document.getElementById("agencyForm:agencyInfo:8").onclick = function() {onAgencyInfoClick(8);};
    if (document.getElementById("agencyForm:agencyInfo:9")) document.getElementById("agencyForm:agencyInfo:9").onclick = function() {onAgencyInfoClick(9);};

	// Bind onmouseover functions to new DOM elements			
    if (document.getElementById("agencyForm:agencyInfo:0")) document.getElementById("agencyForm:agencyInfo:0").onmouseover = function() {onAgencyInfoMouseover(0);};
    if (document.getElementById("agencyForm:agencyInfo:1")) document.getElementById("agencyForm:agencyInfo:1").onmouseover = function() {onAgencyInfoMouseover(1);};
    if (document.getElementById("agencyForm:agencyInfo:2")) document.getElementById("agencyForm:agencyInfo:2").onmouseover = function() {onAgencyInfoMouseover(2);};
    if (document.getElementById("agencyForm:agencyInfo:3")) document.getElementById("agencyForm:agencyInfo:3").onmouseover = function() {onAgencyInfoMouseover(3);};
    if (document.getElementById("agencyForm:agencyInfo:4")) document.getElementById("agencyForm:agencyInfo:4").onmouseover = function() {onAgencyInfoMouseover(4);};
    if (document.getElementById("agencyForm:agencyInfo:5")) document.getElementById("agencyForm:agencyInfo:5").onmouseover = function() {onAgencyInfoMouseover(5);};
    if (document.getElementById("agencyForm:agencyInfo:6")) document.getElementById("agencyForm:agencyInfo:6").onmouseover = function() {onAgencyInfoMouseover(6);};
    if (document.getElementById("agencyForm:agencyInfo:7")) document.getElementById("agencyForm:agencyInfo:7").onmouseover = function() {onAgencyInfoMouseover(7);};
    if (document.getElementById("agencyForm:agencyInfo:8")) document.getElementById("agencyForm:agencyInfo:8").onmouseover = function() {onAgencyInfoMouseover(8);};
    if (document.getElementById("agencyForm:agencyInfo:9")) document.getElementById("agencyForm:agencyInfo:9").onmouseover = function() {onAgencyInfoMouseover(9);};

	// Bind onmouseout functions to new DOM elements			
    if (document.getElementById("agencyForm:agencyInfo:0")) document.getElementById("agencyForm:agencyInfo:0").onmouseout = function() {onAgencyInfoMouseout(0);};
    if (document.getElementById("agencyForm:agencyInfo:1")) document.getElementById("agencyForm:agencyInfo:1").onmouseout = function() {onAgencyInfoMouseout(1);};
    if (document.getElementById("agencyForm:agencyInfo:2")) document.getElementById("agencyForm:agencyInfo:2").onmouseout = function() {onAgencyInfoMouseout(2);};
    if (document.getElementById("agencyForm:agencyInfo:3")) document.getElementById("agencyForm:agencyInfo:3").onmouseout = function() {onAgencyInfoMouseout(3);};
    if (document.getElementById("agencyForm:agencyInfo:4")) document.getElementById("agencyForm:agencyInfo:4").onmouseout = function() {onAgencyInfoMouseout(4);};
    if (document.getElementById("agencyForm:agencyInfo:5")) document.getElementById("agencyForm:agencyInfo:5").onmouseout = function() {onAgencyInfoMouseout(5);};
    if (document.getElementById("agencyForm:agencyInfo:6")) document.getElementById("agencyForm:agencyInfo:6").onmouseout = function() {onAgencyInfoMouseout(6);};
    if (document.getElementById("agencyForm:agencyInfo:7")) document.getElementById("agencyForm:agencyInfo:7").onmouseout = function() {onAgencyInfoMouseout(7);};
    if (document.getElementById("agencyForm:agencyInfo:8")) document.getElementById("agencyForm:agencyInfo:8").onmouseout = function() {onAgencyInfoMouseout(8);};
    if (document.getElementById("agencyForm:agencyInfo:9")) document.getElementById("agencyForm:agencyInfo:9").onmouseout = function() {onAgencyInfoMouseout(9);};
}

/** Called when an agencyInfo item is clicked 
  * Index of clicked agency is stored in selectedAgent variable */
function onAgencyInfoClick(index)
{
    // If user clicked on a DIFFERENT agnency, having already clicked on one,
    // Clear the properties of the previous selection first
    if ((selectedAgent != index) && (selectedAgent != -1))
    	onAgencyInfoMouseout(selectedAgent, true);

    // If the user clicked on the SAME agency, then "unselect" the agency
	if (selectedAgent == index)
	{
		onAgencyInfoMouseout(selectedAgent, true);
		selectedAgent=-1;
		map.panTo(nearbyAgentsBounds.getCenter());
		map.setCenter(nearbyAgentsBounds.getCenter());
		map.setZoom(map.getBoundsZoomLevel(nearbyAgentsBounds));
	}
	else
	{
        selectedAgent = index;
    	lat = nearbyAgents[index].agency.latitude;
    	lng = nearbyAgents[index].agency.longitude;
    	
    	toLocation = new GLatLng(lat, lng);

    	// get bounding box of selectedAgent's location & base location
      	bounds = new GLatLngBounds(new GLatLng(Math.min(toLocation.lat(), baseLocation.lat()),
      										   Math.min(toLocation.lng(), baseLocation.lng())), 
      							   new GLatLng(Math.max(toLocation.lat(), baseLocation.lat()), 
      										   Math.max(toLocation.lng(), baseLocation.lng())));
      	
    	// Zoom & center map to centerpoint of selectedAgent's location & base location
		map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
		// show directions
        if (directionsPoly[index]) directionsPoly[index].show();
	}
}

/** Called when a mouseover occurs on an agencyInfo item */
function onAgencyInfoMouseover(index)
{
    // Show direction overlay
	if (directionsPoly[index]) directionsPoly[index].show();

    // Swap marker image to highlighted
	 agentMarkers[index].setImage(yellowicon.image);
	// agentMarkers[index].setIcon(yellowicon);
	//map.setCenter(agentMarkers[index].getLatLng(), 14);
	
	document.getElementById("agencyForm:agencyInfo:"+index).style.backgroundColor = "#FEFDEC";
}

/** Called when a mouseout occurs on an agencyInfo item */
function onAgencyInfoMouseout(index, forceAction)
{
    // Don't run if agent is selected (has been clicked) or if index<0 
    if ((selectedAgent != index) || forceAction)
    {
        // Remove direction overlay
    	if (directionsPoly[index]) directionsPoly[index].hide();

    	// Swap marker image to default
    	agentMarkers[index].setImage(redicon.image);

    	document.getElementById("agencyForm:agencyInfo:"+index).style.backgroundColor = "#ebf3fd";
    }
}

/** Called when a mouseout occurs on the entire agencyInfo list */
function onAgencyInfoDivMouseout()
{
    //alert(document.getElementById("agencyInfoDiv").onmouseout);
    //alert("srcElement:" + e.srcElement.id + ",toElement:" + e.toElement.id + ",fromElement:" + e.fromElement.id + ",cancelBubble:" + e.cancelBubble);
    //var e = e || window.event;
    //e.cancelBubble = true;
    //if (e.stopPropogation) e.stopPropogation();
    // Don't run if agent is selected (has been clicked) 
    if (selectedAgent == -1)
    {
    	// Restore overall zoom level
		map.setCenter(nearbyAgentsBounds.getCenter(), map.getBoundsZoomLevel(nearbyAgentsBounds));
    }
    else
    {
        // Zoom to directions between baseLocation & selected agent
        onAgencyInfoClick(selectedAgent);
        if (directionsPoly[selectedAgent]) directionsPoly[selectedAgent].show();
    	//map.setCenter(agentMarkers[selectedAgent].getLatLng(), 15);
    }
}

/** Asynchronously loads directions from baseLocation to all nearby agents 
  * Reuses GDirections objections, hoping to avoid Google speed limit for GDirection calls 
  * Still may need insert randomized timer in for loop so load() calls don't fire off
  * too quickly */
function loadDirections()
{
	for (i = 0; i < nearbyAgents.length; i++)
	{
    	// clear previous directions used for this object
		if (directions[i]) directions[i].clear();

    	lat = nearbyAgents[i].agency.latitude;
    	lng = nearbyAgents[i].agency.longitude;
    	toLocation = new GLatLng(lat, lng);
				
		// Makes asynchronous call.  Comes back using event handler onDirectionsLoad().							        		
		directions[i].load("from: " + baseLocation.lat() + ", " + baseLocation.lng() +
			               "  to: " + toLocation.lat() + ", " + toLocation.lng(), { getPolyline:true });
	}
}

/** Callback function for GDirections.load() */							        
function onDirectionsLoad(index)
{
    // Store GPolyline with directions path 
	if (directions[index]) directionsPoly[index] = directions[index].getPolyline();
	if (index != selectedAgent) directionsPoly[index].hide();
	// Adding overlay here so that show/hide can be used instead of add/remove
	map.addOverlay(directionsPoly[index]);
}

/** Callback function for GDirections.load() when error occurs 
  * See Google Map API for description of error codes */							        
function onDirectionsError(index)
{
    alert("Unable to load driving directions at this time.  [" + index + ": " + directions[index].getStatus().code + "]");
}

/** Called when user drags baseLocation marker to a new location */					        
function onBaseLocationDrag(latlng)
{
    // If a user has an agent selected, just update the directions & distances
    if (selectedAgent >= 0)
    {
		baseLocation = latlng;
		map.removeOverlay(directionsPoly[selectedAgent]);
		loadDirections();
		// Updates distance field on AgencyMetadata objects; does not resort list though.
			Seam.Component.getInstance("findAgentAction").updateDistances(latlng.lat(), latlng.lng(), updateDistances_callback);
		}
    // Otherwise, requery to see if closer agent locations exist to new point
    else
    {
		onMapClick(null, latlng);
    }
}

function updateDistances_callback(result)
{
    // Need to find a javascript function that will reRender agencyInfoList!

    // Refresh list of agents below map "agencyInfo"
		// Makes asynchronous call to findAgentAction.getNearbyAgencyList()
		// When complete, callback method activateAgencyList() is called 
		document.getElementById("agencyForm").submit();
}

/* Dynamically creates a google marker icon for given options (width, height, primaryColor, strokeColor, cornerColor) 
 * Usage: myGIcon = createMarkerIcon({width: 32, height:32, primaryColor:"#ff0000", strokeColor:"#000000", cornerColor:"#ffffff"}); */
function createMarkerIcon(opts) 
{
  var width = opts.width || 32;
  var height = opts.height || 32;
  var primaryColor = opts.primaryColor || "#ff0000";
  var strokeColor = opts.strokeColor || "#000000";
  var cornerColor = opts.cornerColor || "#ffffff";
   
  var baseUrl = "http://chart.apis.google.com/chart?cht=mm";
  var iconUrl = baseUrl + "&chs=" + width + "x" + height + 
      "&chco=" + cornerColor.replace("#", "") + "," + primaryColor.replace("#", "") + "," + strokeColor.replace("#", "") + "&ext=.png";
  var icon = new GIcon(G_DEFAULT_ICON);
  icon.image = iconUrl;
  icon.iconSize = new GSize(width, height);
  icon.shadowSize = new GSize(Math.floor(width*1.6), height);
  icon.iconAnchor = new GPoint(width/2, height);
  icon.infoWindowAnchor = new GPoint(width/2, Math.floor(height/12));
  icon.printImage = iconUrl + "&chof=gif";
  icon.mozPrintImage = iconUrl + "&chf=bg,s,ECECD8" + "&chof=gif";
  var iconUrl = baseUrl + "&chs=" + width + "x" + height + 
      "&chco=" + cornerColor.replace("#", "") + "," + primaryColor.replace("#", "") + "," + strokeColor.replace("#", "");
  icon.transparent = iconUrl + "&chf=a,s,ffffff11&ext=.png";

  icon.imageMap = [
      width/2, height,
      (7/16)*width, (5/8)*height,
      (5/16)*width, (7/16)*height,
      (7/32)*width, (5/16)*height,
      (5/16)*width, (1/8)*height,
      (1/2)*width, 0,
      (11/16)*width, (1/8)*height,
      (25/32)*width, (5/16)*height,
      (11/16)*width, (7/16)*height,
      (9/16)*width, (5/8)*height
  ];
  for (var i = 0; i < icon.imageMap.length; i++) {
    icon.imageMap[i] = parseInt(icon.imageMap[i]);
  }

  return icon;
}
