/**
 * MHC Global Google Map
 *
 * Requirements:
 * - prototype
 * - google maps api v2
 * - a function named mhcMapInit that adds layers and markers
 * - a window load event to call the initialize() function
 * - a div in the DOM of the page with an ID of "intmap"
 *
 */

// globals
var map = null;
var geocoder = null;
var mhcMarkers = new Object(); // associative array of all layers by name
var mhcLayers = new Array(); // array of layer names
var mapcontrols = null;
var mapCenter = null;
var defaultLayer = null;

/**
 * Initialize the map
 */
function initialize() {

	if (GBrowserIsCompatible()) {

		// setup DOM for the map
		var mapcontainer = $('intmap');
		mapcontrols = new Element('div', { 'id': 'mapcontrols' });
		var mapdiv = new Element('div', { 'id': 'map' });
		var infodiv = new Element('div', { 'id': 'mapinfo' });
		mapcontainer.insert(mapcontrols);
		mapcontainer.insert(infodiv);
		mapcontainer.insert(mapdiv);

		// geocoder
		geocoder = new GClientGeocoder();
		
		// mhc location
		mhcLatLng = new GLatLng(42.2555514, -72.5745935);	
		//mapCenter = new GLatLng(39.0807391, 17.1270792); // Crotone, Italy
		//mapCenter = new GLatLng(4.849569, 31.60463); // Juba, Sudan
		mapCenter = new GLatLng(43.8564300,18.4134200); // Sarajevo

		// map
		map = new GMap2(document.getElementById("map"), { backgroundColor:"#e5ddcc", size: new GSize(570, 350) });
		map.setMapType(G_NORMAL_MAP);
		map.setCenter(mapCenter, 1);
		
		// custom map type
		var mhcType = mhcCustomMapType('MHC', '/offices/comm/global/gmap/tiles/', 1, 5);
		//var gridType = mhcCustomMapType('Grid', '/offices/comm/global/gmap/gridtiles/', 0, 3);
		map.setMapType(mhcType);
		
		// UI
		var customUI = map.getDefaultUI();
		/*customUI.maptypes.normal = false;
		customUI.maptypes.hybrid = false;
		customUI.maptypes.physical = false;
		customUI.maptypes.satellite = false;*/
		customUI.controls.scalecontrol = false;
		customUI.controls.maptypecontrol = false; // hides the type switcher
		customUI.controls.largemapcontrol3d = true;
		customUI.controls.smallzoomcontrol3d  = false;
		map.setUI(customUI);
		
		// custom map layers and markers setup function
		mhcMapInit();
		
		// add all layers to the controls
		var layerlist = new Element('ul');
		var layerlink = null;
		var liclass = '';
		for (i = 0; i < mhcLayers.length; i++) {
			// although much less code, this didn't work in IE
			//layerlink = new Element('a', {'href': '#','onclick': 'mhcShowMarkers("'+mhcLayers[i].id+'"); return false;', 'class': 'mhclayerbutton', 'id': 'mhclayer-'+mhcLayers[i].id}).update(mhcLayers[i].name);
			layerlink = new Element('a', {'href': '#', 'class': 'mhclayerbutton', 'id': 'mhclayer-'+mhcLayers[i].id}).update(mhcLayers[i].name);
			layerlink.observe('click', function(event) { var el = Event.element(event); var elemID = el.readAttribute('id'); mhcShowMarkers(elemID.sub('mhclayer-','')); return false; });
			layerlist.insert(new Element('li').update(layerlink));
		}
		mapcontrols.update(layerlist);
		
		// add all region markers to the map
		mhcShowMarkers(defaultLayer);
		
		// unload added here because GUnload doesn't exist before here
		Event.observe(window, 'unload', GUnload);
				
	}
  
}

/**
 * Shows all markers in a given layer
 */
function mhcShowMarkers(layer) {

	// remove all old
	map.clearOverlays();

	var m = mhcMarkers[layer];
	
	for (var i = 0; i < m.length; i++) {
		map.addOverlay(m[i]);
	}
	
	mhcZoomToCenter();
	//mhcSetMapBounds(layer);
	
	// remove highlighted buttons
	var buttons = $$('#mapcontrols ul li a.here');
	buttons.each(function(item) { item.removeClassName('here') });
	// highlight current layer button
	$('mhclayer-'+layer).addClassName('here');
	
	// info div
	var l = mhcGetLayer(layer);
	$('mapinfo').update(l.info);

}

/**
 * Adds a layer
 */
function mhcAddLayer(id, name, info) {

	// first add the layer to the layer list
	var l = new Object();
	l.id = id;
	l.name = name;
	l.info = info;
	mhcLayers.push(l);
	
	// second, add an empty array to the marker container
	mhcMarkers[id] = new Array();

}

/**
 * Gets a layer
 */
function mhcGetLayer(id) {

	for (i = 0; i < mhcLayers.length; i++) {
		if (mhcLayers[i].id == id) return mhcLayers[i];
	}
	
	return false;

}

/**
 * Adds a marker to the map.
 */
function mhcAddMarker(lat, lng, layer, title, content) {

	var opts = null;
	var mhcIcon = new GIcon(G_DEFAULT_ICON);
	//mhcIcon.image = "http://www.mtholyoke.edu/offices/comm/global/gmap/markers/marker-blue.png";
	opts = { icon:mhcIcon };
	var marker = new GMarker(new GLatLng(lat, lng), opts);
	
	// check that the layer exists
	if (mhcMarkers[layer] == null) {
		alert('Layer "'+layer+'" does not exist.');
		return;
	}
	
	// add an infowindow to the marker
	GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowHtml('<h3>'+title+'</h3>'+content);
	});

	
	// add the marker to the new layer
	mhcMarkers[layer].push(marker);
	
}

/**
 * Sets the map's zoom level and center to focus on MHC
 */
function mhcZoomToCenter() {

	map.setCenter(mapCenter, 1);

}

/**
 * Sets the map's zoom level and center to show all points
 */
function mhcSetMapBounds(layer) {

	var bounds = new GLatLngBounds();
	
	var ma = mhcMarkers[layer];
	for (i = 0; i < ma.length; i++) {
		bounds.extend(ma[i].getLatLng());
	}
	
	// set center and zoom
	map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

}

/**
 * Handles the addition of custom Map types.
 */
function mhcCustomMapType(name, directory, minz, maxz) {

	// zoom levels. 0 (farthest) -> 17 (closest)
	var minzoom = minz;
	var maxzoom = maxz;

	// copyright
	// <index>, <bounds[GLatLngBounds()], <minZoom>, <copyrightText>
	var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180)), minzoom, "&copy;2009 Mount Holyoke College");
	
	// copyright collection
	var copyrightCollection = new GCopyrightCollection('Map');
	copyrightCollection.addCopyright(copyright);

	// create the custom tile layer
	// the two number params represent min and max zoom levels
	var tilelayers = [new GTileLayer(copyrightCollection, minzoom, maxzoom)];
	tilelayers[0].getTileUrl = function (point, zoom) {
		return directory + "tile_" + zoom + "_" + point.x + "_" + point.y + ".png";
	};
	
	// custom Grid map type
	// The mercator value represents the number of zoom levels needed.
	// It needs to be at least one more than the largest zoom level, e.g. (max_zoom_level + 1).
	// If you want polylines to work, it must be 18 or above.
	var gridType = new GMapType(tilelayers, new GMercatorProjection(maxzoom+1), name, {errorMessage:"No data available at this zoom level."});
	map.addMapType(gridType);

	return gridType;

}
