/**
	@file This file contains constants, variables, and functions needed for
	displaying marker overlays on the map.

	USES:
		/maps/scripts/globals.js
		/maps/scripts/utility.js

	USED BY:
		/maps/scripts/init.js

	INCLUDED BY:
		/maps.php
 */

/*--------------------------------------------------------------------------*/
// CONSTANTS /* {{{ */
var MARKER_ICON_IMAGE = MAPS_BASE_URL + 'maps/images/marker.png'; // image used for the generic marker icon
var MARKER_SHADOW_IMAGE = MAPS_BASE_URL + 'maps/images/shadow50.png'; // image used for the generic marker shadow
var MAP_LINK_LIST_ID = 'map-link-list'; // id of the link list container (must be a <ul> tag)
var MAP_LINK_LIST_ITEM_CLASS = 'map-link-list-item'; // class used for the link list item (<li>) tags
var MAP_LINK_LIST_ANCHOR_CLASS = 'map-link-list-anchor'; // class used for the link list anchor (<a>) tags

/* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function creates and returns a generic marker icon object
	for a map marker.
	@return Returns a GIcon generic marker icon object.
 */
function GetGenericMarkerIcon() { /* {{{ */

	// create new marker icon
	var icon = new GIcon();

	// set marker properties
	icon.image = MARKER_ICON_IMAGE;
	icon.shadow = MARKER_SHADOW_IMAGE;
	icon.iconSize = new GSize(20, 34);
	icon.shadowSize = new GSize(37, 34);
	icon.iconAnchor = new GPoint(9, 34);
	icon.infoWindowAnchor = new GPoint(9, 2);

	return icon;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function creates and returns a marker from the given point,
	tabs, and icon.
	@param point GLatLng point to place the marker when displayed.
	@param tabs Array containing the GInfoWindowTab objects.
	@param title Title of the marker that appears on mouse hover.
	@param icon GIcon marker icon object.
	@return GMarker object that can be added to the map.

	@note The marker is not added to the map in this function.
 */
function CreateMarker(point, tabs, title, icon) { /* {{{ */

	// if no icon is given, create a generic marker
	if (!icon) {
		icon = GetGenericMarkerIcon();
	}

	// if no title is given, use an empty string
	if (!title) {
		title = '';
	}

	// setup marker options
	var options = new Object();

	options.icon = icon;
	options.title = title;

	// marker object to be returned
	var marker = new GMarker(point, options);

	// bind the tabs to the marker
	marker.bindInfoWindowTabsHtml(tabs);

	// return the marker object
	return marker;
} /* }}} */

/****************************************************************************
 * FUNCTION:	addLinks
 *		RETURN:	none
 *	This function creates links below the map for each marker from the
 *	global marker data container.  Each index in the marker data container
 *	represents a different marker.
****************************************************************************/
/*--------------------------------------------------------------------------*/
/**
	@brief This function creates links below the map for each marker from
	the global marker data array (g_marker_data).
	
	@note Each index in the marker data array represents a different marker.
 */
function AddMarkerLinks() { /* {{{ */

	// html to be added to the list of links
	var html = '';

	// loop through the marker data
	for (var i = 0; i < g_marker_data.length; i++) {

		var label = g_marker_data[i].linklabel;
		if (!label) {
			label = 'Location ' + parseInt(i + 1, 10).toString();
		}

		// create a new html list item for each marker
		html += '<li class="' + MAP_LINK_LIST_ITEM_CLASS + '">\n';
		html += '    <a class="' + MAP_LINK_LIST_ANCHOR_CLASS + '" href="javascript: //;" onclick="ShowLocation(g_marker_data[' + i + '].latlng);">' + label + '</a>\n';
		html += '</li>\n';
	}

	// add html to the list of links
	document.getElementById(MAP_LINK_LIST_ID).innerHTML = html;

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function creates an array of GInfoWindowTab objects
	containing data for creating marker tabs by processing the given XML
	node collection.
	@param arr_xml_nodes Collection of XML nodes containing data
	for creating marker tabs.
	@return Returns array of GInfoWindowTab objects.
 */
function GetMarkerTabData(arr_xml_nodes) { /* {{{ */

	// array of objects containing tab data (label, text)
	var tabs = new Array();

	// loop through XML node collection
	for (var i = 0; i < arr_xml_nodes.length; i++) {

		var xml = arr_xml_nodes.item(i); // get XML node

		// we want to get a label and text tag.  There should only ever be one
		// for each parent node.
		var labels = xml.getElementsByTagName("label"); // get 'label' tags
		var texts = xml.getElementsByTagName("text"); // get 'text' tags

		var label = GetNodeValue(xml, 'label'); // get value of first 'label' tag
		var text = GetNodeValue(xml, 'text'); // get value of first 'text' tag

		// add tab data object to array
		tabs.push(new GInfoWindowTab(label, text));
	}

	// return array of tab data objects
	return tabs;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function updates the display status of all markers.
 */
function UpdateMarkerDisplay() { /* {{{ */

	// loop through all markers
	for (var i = 0; i < g_marker_data.length; i++) {

		// check if within visible range
		if ((g_marker_data[i].zoom.min <= g_state.curr_zoom) && (g_marker_data[i].zoom.max >= g_state.curr_zoom)) {

			// if so, add to map
			g_map.addOverlay(g_marker_data[i].marker);

		}
		// if not, remove from map
		else {

			// close info window if open
			if (!g_map.getInfoWindow().isHidden()) {
				g_marker_data[i].marker.closeInfoWindow();
			}

			// remove marker from map
			g_map.removeOverlay(g_marker_data[i].marker);
		}
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function displays all markers on the map.
 */
function ShowMarkers() { /* {{{ */

	// loop through markers and add to map
	for (var i = 0; i < g_marker_data.length; i++) {

		// make sure marker is in visible zoom area
		if ((g_marker_data[i].zoom.min <= g_state.curr_zoom) && (g_marker_data[i].zoom.max >= g_state.curr_zoom)) {
			g_map.addOverlay(g_marker_data[i].marker);
		}
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function hides all markers on the map.
 */
function HideMarkers() { /* {{{ */

	// loop through all markers
	for (var i= 0; i < g_marker_data.length; i++) {

		// close info window if open
		if (!g_map.getInfoWindow().isHidden()) {
			g_marker_data[i].marker.closeInfoWindow();
		}

		// remove marker from map
		g_map.removeOverlay(g_marker_data[i].marker);
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function makes an XMLHttpRequest to an XML file to retrieve
	data for the marker overlays.
	@param request_url URL to make the request to.
 */
function LoadMarkers(request_url) { /* {{{ */

	// create XmlHttpRequest object
	var xml_request = new GXmlHttp.create();

	// make a GET request for the XML data ('id' is to prevent caching)
	xml_request.open("GET", request_url + '?id=' + new Date().getTime(), false);

	// send no POST variables
	xml_request.send(null);

	if (xml_request.status == 200) {
		AddMarkers(xml_request);
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function parses the response XML document and creates
	marker overlays based on the data.
	@param response Response containing the XML document.
 */
function AddMarkers(response) { /* {{{ */

	var marker_nodes = null; // nodes from XML document that hold the marker data
	var xml_doc = null; // XML document root node

	// if we have received the entire response
	if (response.status == 200) {

		// get xml document from response
		xml_doc = GetXMLDocument(response);

		// check that xml_doc is non-null
		if (xml_doc) {

			// get marker overlay data
			marker_nodes = xml_doc.getElementsByTagName('point');

			// loop through and process each marker overlay
			for (var i = 0; i < marker_nodes.length; i++) {

				// get marker overlays from collection
				var marker = ParseMarkerData(marker_nodes.item(i));

				// process marker overlay
				AddMarker(marker);

				/*
				// get control window information
				var infos = point.getElementsByTagName("info");
				
				// loop through and process each control window info
				for (var j = 0; j < infos.length; j++) {

					// get control window info from collection
					var info = getInfoData(infos.item(j));

					// process control window info
					addInfoData(info);
				}
				*/
			}
		}
		// xml_doc is null, report error
		else {
			alert("Sorry, there was an error in loading the map data.\nPlease refresh the page to try again.");
		}
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function and adds the given marker to the global marker data
	array. It also adds the marker to the Google map if markers are enabled.
	@param marker Marker to add to array and map.
 */
function AddMarker(marker) { /* {{{ */

	// add marker data to global marker_data variable for later retrieval
	g_marker_data.push(marker);

	// if enabled, add marker to map
	if (true == g_state.markers_enabled) {
		g_map.addOverlay(marker.marker);
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function creates a marker from the given XML node.
	@param xml_node XML node that contains data for marker creation.
	@return Returns a marker object that can be used for adding
	a marker to the map.
 */
function ParseMarkerData(xml_node) { /* {{{ */

	var marker_data = new Object(); // contains the data to be stored in the global marker data array

	// get latitude and longitude coordinates from current marker
	var lat = xml_node.getAttribute("lat");
	var lng = xml_node.getAttribute("lng");

	// create GLatLng point for the marker
	var latlng = new GLatLng(lat, lng);

	// get data for the marker
	var data = xml_node.getElementsByTagName("data");

	// get tab data from the data for the marker
	var tabs = GetMarkerTabData(data);

	// get the link label for the marker
	var linklabel = GetNodeValue(xml_node, 'linklabel');

	// get the min zoom for the marker
	var min_zoom = xml_node.getAttribute('minzoom');

	// get the max zoom for the marker
	var max_zoom = xml_node.getAttribute('maxzoom');

	// create a marker
	var marker = CreateMarker(latlng, tabs, linklabel);

	// set marker data attributes
	marker_data.latlng = latlng;
	marker_data.linklabel = linklabel;
	marker_data.marker = marker;
	marker_data.zoom = CreateZoomLevelObject(min_zoom, max_zoom);

	return marker_data;
} /* }}} */

