var map;
var geocoder;
var directions;
var directionsOptions;

var baseIcon;

var request;
var unitMarkers = [];
var showingUnitMarkers = [];
var youMarker;

// Call this function when the page has been loaded
function initUnitFinder()
{
	geocoder = new GClientGeocoder();

	map = new GMap2(document.getElementById("unit_map"));
	map.addControl(new GSmallMapControl());
	map.addControl(new GMapTypeControl());
	map.addControl(new GScaleControl());

	directions = new GDirections(map, null);
	directionsOptions = { getSteps: true };
	GEvent.addListener(directions, "load", onGDirectionsLoad);
	GEvent.addListener(directions, "error", handleGDirectionsErrors);

	baseIcon = new GIcon();
//	baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
	baseIcon.iconSize = new GSize(33, 34);
//	baseIcon.shadowSize = new GSize(37, 34);
	baseIcon.iconAnchor = new GPoint(9, 34);
	baseIcon.infoWindowAnchor = new GPoint(16, 32);
//	baseIcon.infoShadowAnchor = new GPoint(24, 20);

	if (jQuery('input#latitude').val()) {
		latLng = new GLatLng(jQuery('input#latitude').val(), jQuery('input#longitude').val());
		findUnitsByCoords(latLng);
	} else if (jQuery('input#zip').val()) {
		findUnitsByZip();
	}
}

/*
 * Searches for snUnitLocations by zip code and radius
 */
function findUnitsByZip()
{
	var zip = jQuery('input#zip').val();
	
	geocoder.getLatLng(zip,
		function(point) {
			if (!point) {
				alert("Zip code " + zip + " not found");
			} else {
				findUnitsByCoords(point);
			}
		});
}

/*
 * Sends the AJAX query to get the units near these coordinates
 */
function findUnitsByCoords(coords)
{
	// Remove the old "You" marker if it exists
	if (youMarker) {
		map.removeOverlay(youMarker);
	}

	// Place the "You" marker
	var graphic = "/images/design/you.png";
	
	var markerIcon = new GIcon(baseIcon);
	markerIcon.image = graphic;
	youMarker = new GMarker(coords, markerIcon);

	map.addOverlay(youMarker);

	var radius = jQuery('select#search_radius').val();

	request = GXmlHttp.create();
	var xmlQueryUrl = xmlRequestPage
						+ '?radius=' + radius
						+ '&lat=' + coords.lat()
						+ '&lng=' + coords.lng()

	request.open("GET", xmlQueryUrl, true);
	request.onreadystatechange = showUnits;
	request.send(null);
}

/*
 * Accepts the response XML and adds the units to the map
 */
function showUnits()
{
	if (request.readyState == 4)
	{
		// Clear old directions
		directions.clear();

		unitMarkers = new Array();

		var xmlDocElem = request.responseXML.documentElement;
		
		// obtain the array of markers and loop through it
		var xmlMarkers = xmlDocElem.getElementsByTagName("Placemark");
		
		var points = new Array();

		for (var i = 0; i < xmlMarkers.length; i++)
		{
			// obtain the attribues of each marker
			var addr = xmlMarkers[i].getElementsByTagName("description")[0].firstChild.nodeValue;
			var coords = xmlMarkers[i].getElementsByTagName("coordinates")[0].firstChild.nodeValue.split(",");
			var lat = parseFloat(coords[0]);
			var lng = parseFloat(coords[1]);
			var point = new GLatLng(lat,lng);
			points[i] = point;
			var type = xmlMarkers[i].getElementsByTagName("type")[0].firstChild.nodeValue;
			var name = xmlMarkers[i].getElementsByTagName("name")[0].firstChild.nodeValue;

			// create the marker
			var html = '<div class="unit_finder_popup" style="width: 210px">'
								+ '<h5><a href="javascript:mapPanAndZoomTo(' + lat + ',' + lng + ')" title="zoom">'
								+ name + '</a></h5><br />'
								+ addr + '<br /><hr /><br />Enter your starting address<br />'
								+ '<form name="route_'+i+'" action="#" onsubmit="return false;">'
								+ '<input type="text" id="starting_address_'+i+'" /> '
								+ '<input type="submit" id="submit_address_'+i+'" value="Go!" '
								+	'onclick="showDirectionsFromUnit('+i+', '+lat+', '+lng+'); return false;" />'
								+	'</form></div>';
			var marker = createMarker(point, type, html, i);
			marker.type = type;
			unitMarkers.push(marker);
		}
		if (xmlMarkers.length > 0) {
			fitMap(map, points);
		} else {
			// Don't move the map
			// Show an alert saying that no locations were found
			var radius = jQuery('select#search_radius').val();
			var zip = jQuery('input#zip').val();
			var milesPlural = "mile" + ((radius==1) ? '' : 's');
			alert("No units were found within "	+ radius +" "+ milesPlural +" of " + zip);
		}
	}

	refreshOverlays();
}

/*
 * Removes any old overlays and adds overlays of the checked types
 */
function refreshOverlays()
{
	// Remove old unit markers
	for (var i=0; i<showingUnitMarkers.length; i++) {
		map.removeOverlay(showingUnitMarkers[i]);
	}
	showingUnitMarkers = new Array();

	for (var i = 0; i < unitMarkers.length; i++) {
		var marker = unitMarkers[i];
		// If the marker's type is checked
		if (jQuery('input#'+marker.type.toLowerCase()+'_checkbox:checked').val() != null) {
			// create the marker
			map.addOverlay(marker);
			showingUnitMarkers.push(marker);
		}
	}
}


/*
 * Creates the marker and sets up the event window that pops up on click
 */
function createMarker(point, type, html, index) {
	var graphic = "/images/design/" + type + ".png";
	
	var markerIcon = new GIcon(baseIcon);
	markerIcon.image = graphic;
	var marker = new GMarker(point, markerIcon);
	marker.html = html;

	GEvent.addListener(marker, "click", function() {
		var newPoint = new GLatLng(point.lat(), point.lng());
		map.panTo(newPoint);
		marker.openInfoWindowHtml(html);
	});
	
	return marker;
}


/*
 * Fits the map to be just big enough to contain all the results
 */
function fitMap(map, points) {
	var bounds = new GLatLngBounds();
	for (var i=0; i<points.length; i++) {
		bounds.extend(points[i]);
	}
	// Include the "You" marker
	bounds.extend(youMarker.getPoint());
	var zoomLevel = map.getBoundsZoomLevel(bounds)
	// Don't automatically zoom in way too far
	if(zoomLevel > 13) {
		zoomLevel = 13;
	}
	map.setCenter(bounds.getCenter());
	map.setZoom(zoomLevel);
}


/*
 * Centers the map on the selected location and opens its info pannel
 */
function mapPanAndZoomTo(lat,lng) {
	if (map != null) {
		map.setZoom(16);
		map.setCenter(new GLatLng(lat, lng));
	}
}


/*
 * Called when a user clicks to find directions from somewhere to a unit (in the popup)
 */
function showDirectionsFromUnit(unitIndex, lat, lng)
{
	var fromAddress = jQuery('input#starting_address_'+unitIndex).val();
	var fromAndTo = "from: " + fromAddress
								+ " to: " + lat + ", " + lng;

	directions.load(fromAndTo, directionsOptions);
	// This will continue at onGDirectionsLoad
}


/*
 * Handles the response from the GDirections after finding directions
 */
function onGDirectionsLoad() {
//	Nothing to do
}


function handleGDirectionsErrors() {
	if (directions.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
		alert("The starting or ending address you entered couldn't be found. Make sure you typed them both in correctly.");
	else if (directions.getStatus().code == G_GEO_SERVER_ERROR)
		alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);
	   
	else if (directions.getStatus().code == G_GEO_MISSING_QUERY)
		alert("Please specify both a starting and ending address");

	else if (directions.getStatus().code == G_GEO_BAD_REQUEST)
		alert("A directions request could not be successfully parsed.");
		
	else alert("An unknown error occurred.");

}
