var map;
var icon0;
var markers = new Array();
var infoContent = new Array();
var locations = new Array();
var gdir;
var address;
var geocoder = null;

var maxLat = 0, maxLong = 0, minLat = 0, minLong = 0;
 
function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}
			func();
		}
	}
}

function loadMap(loc_array) {	
	map = new GMap2(document.getElementById("map"));
	map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());
	map.setCenter(new GLatLng(40.672306,-73.926315), 11);
	
	if ( document.getElementById("directions") != null ) {
		gdir = new GDirections(map, document.getElementById("directions"));
		GEvent.addListener(gdir, "load", onGDirectionsLoad);
		GEvent.addListener(gdir, "error", handleErrors);
	}
	
	geocoder = new GClientGeocoder();
 
	icon0 = new GIcon();
	icon0.image = "/template/images/gmarker.png";
	icon0.shadow = "http://www.google.com/mapfiles/shadow50.png";
	icon0.iconSize = new GSize(22, 36);
	icon0.shadowSize = new GSize(37, 34);
	icon0.iconAnchor = new GPoint(9, 36);
	icon0.infoWindowAnchor = new GPoint(9, 2);
	icon0.infoShadowAnchor = new GPoint(18, 25);
	
	addPoints();
}

function addPoints() {
		
	for( var i = 0; i < locations.length; i++ ) {
		
		var point = new GPoint(locations[i][2],locations[i][1]);
		infoContent[i] = "<div id=\"popup\">" + locations[i][0] + '<br />';		
		if ( address != null && address.length > 5 ) {
			infoContent[i] += '<a href="' + locations[i][3] + '?address=' + address + '" style="font-weight:bold;">Get Directions</a><br />';
		}
		infoContent[i] += '<a href="#" onclick="openMarker(' + i + '); return false;" style="font-weight:bold;">Zoom In</a> | <a href="#" onclick="openMarker(' + i + ', 11);return false;" style="font-weight:bold;">Zoom Out</a>';
		if ( locations[i][3].length > 1) {
			infoContent[i] += ' | <a href="' + locations[i][3] + '" style="font-weight:bold;">More Information &raquo;</a></div>';
		}
		
		markers[i] = createMarker(point, icon0, infoContent[i]);
		map.addOverlay(markers[i]);
		
		// set min / max points
		if ( maxLat == 0 ) maxLat = locations[i][1];
		else if ( maxLat < locations[i][1] ) maxLat = locations[i][1];
		
		if ( minLat == 0 ) minLat = locations[i][1];
		else if ( minLat > locations[i][1] ) minLat = locations[i][1];

		if ( maxLong == 0 ) maxLong = locations[i][2];
		else if ( maxLong < locations[i][2] ) maxLong = locations[i][2];
		
		if ( minLong == 0 ) minLong = locations[i][2];
		else if ( minLong > locations[i][2] ) minLong = locations[i][2];
	}	
}
 
function createMarker(point, icon, popuphtml) {
	var marker = new GMarker(point, icon);
	GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowHtml(popuphtml);
	});
	return marker;
}

function centerAll() {
		
	var bounds = extendByRatio(new GLatLngBounds(new GLatLng(minLat, minLong), new GLatLng(maxLat, maxLong)), 0.05);
	var zoom = map.getBoundsZoomLevel(bounds);

	var center_lat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) / 2.0; 
	var center_lng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) / 2.0; 

	map.setCenter(new GLatLng(center_lat, center_lng), zoom);
}

function setCenter(lat, long, zoom) {
	map.setCenter(new GLatLng(lat,long), zoom);
}

function openMarker(i, zoom) {
	if ( !zoom) zoom = 15;
	
	setCenter(locations[i][1], locations[i][2], zoom);
	markers[i].openInfoWindowHtml(infoContent[i]);
}

function getDirections(fromAddress) {
	if ( fromAddress.length < 5 ) {
		var divError = document.getElementById('direction_error');
		divError.innerHTML = 'Please enter your full address.';
		divError.style.display = 'block';
	}
	
	var query = "from: " + fromAddress + " to: " + address;
	gdir.load(query);
}

function handleErrors(){
	var str = '';
	
   if ( gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS )
		str = "The specified location could not be found. This may be due to the fact that the address is relatively new, or it may be incorrect.";

else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
		str = "A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.";
   
   else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
	 	str = "The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.";
 
   else if (gdir.getStatus().code == G_GEO_BAD_KEY)
		str = "The given key is either invalid or does not match the domain for which it was given.";

   else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
		str = "A directions request could not be successfully parsed.";
   else 
		str = "An unknown error occurred.";
	
	var divError = document.getElementById('direction_error');
	divError.innerHTML = str;
	divError.style.display = 'block';
}

function onGDirectionsLoad(){ 
	markers[0].hide();
	markers[0].closeInfoWindow();
	
	var fm = gdir.getMarker(1).getIcon();
	fm.image = '/template/images/gmarker.png';

	var divMap = document.getElementById('map');
	var divDirections = document.getElementById('directions');
	var divError = document.getElementById('direction_error');
	
	divError.style.display = 'none';
}

function extendByRatio(bounds, ratio) {
	 var largerBounds = new GLatLngBounds(bounds.getSouthWest(), bounds.getNorthEast());
	 
	 // get lat, lng of north east and south west
	 var northEastLat = bounds.getNorthEast().lat();
	 var northEastLng = bounds.getNorthEast().lng();
	 var southWestLat = bounds.getSouthWest().lat();
	 var southWestLng = bounds.getSouthWest().lng();
	 var diffLat = northEastLat - southWestLat;
	 var diffLng = northEastLng - southWestLng;
	 
	 // multiply with ratio
	 northEastLat += diffLat * ratio;
	 southWestLat -= diffLat * ratio;
	 northEastLng += diffLng * ratio;
	 southWestLng -= diffLng * ratio;
	 
	 // extend north east
	 largerBounds.extend(new GLatLng(northEastLat, northEastLng));
	 largerBounds.extend(new GLatLng(southWestLat, southWestLng));

	return largerBounds;
} 