/**
	@file This file contains constants, variables, and functions needed for
	displaying region 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 DEFAULT_BORDER_WEIGHT = "0"; // default thickness of a polyline or polygon border
var DEFAULT_BORDER_COLOR = "#FFFFFF"; // default color of a polyline or polygon border
var DEFAULT_FILL_COLOR = "#FFFFFF"; // default fill color of a polygon
var DEFAULT_OPACITY = "1.0"; // default opacity of a polyline, polygon, or polygon border

/* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function creates a GPolygon object and adds it to the array
	of global regions.
	@param area Region to add to global array.

	@note 'area' contains the following members:
		points
		border_weight
		border_color
		fill_color
		opacity
		zoom
 */
function AddRegion(area) { /* {{{ */

	// check if the object contains a defined region, if not then do nothing
	if (area.points.length < 2) {
		return;
	}

	// create GPolygon object and add to array
	area.region = new GPolygon(area.points, area.border_color, area.border_weight, area.opactiy, area.fill_color, area.opacity);
	g_region_data.push(area);

	// add click listener
	GEvent.addListener(g_region_data[g_region_data.length - 1].region, 'click', RegionClick);

	// if enabled, add region to map

	if (true == g_state.regions_enabled) {
		if ((area.zoom.min <= g_state.curr_zoom) && (area.zoom.max >= g_state.curr_zoom) && (area.display)) {
			g_map.addOverlay(area.region);
		}
	}
	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function hides all regions on the map.
 */
function HideRegions() { /* {{{ */

	for (var i = 0; i < g_region_data.length; i++) {
		g_map.removeOverlay(g_region_data[i].region);
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function displays all regions on the map.
 */
function ShowRegions(tag) { /* {{{ */

	if (true == g_state.regions_enabled) {

		for (var i = 0; i < g_region_data.length; i++) {
			// check that overlay is in visible zoom level
			if ((g_region_data[i].zoom.min <= g_map.getZoom()) && (g_region_data[i].zoom.max >= g_map.getZoom()) && (g_region_data[i].display)) {
				g_map.addOverlay(g_region_data[i].region);
			}
		}
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function makes an XMLHttpRequest to an XML file to retrieve
	data for the region overlays.
	@param request_url URL to make the request to.
 */
function LoadRegions(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) {
		AddRegions(xml_request);
	}

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function parses the response XML document and creates
	region overlays based on the data.
	@param response Response containing the XML document.
 */
function AddRegions(response) { /* {{{ */

	var area_nodes = null; // nodes from XML document that hold the region 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 region overlay data
			var area_nodes = xml_doc.getElementsByTagName("area");

			// loop through and process each region overlay
			for (var j = 0; j < area_nodes.length; j++) {

				// get region overlay from collection
				var area = ParseRegionData(area_nodes.item(j));

				// process region overlay
				AddRegion(area);
			}
		}
		// if 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 creates an object containing the data that the
	given XML node contains.
	@param xml_node Node containing the region data to parse out.
	@return Returns an object (area) that contains the extracted data from
	the given XML node.

	@note 'area' contains the following members:
		points
		border_weight
		border_color
		fill_color
		opacity
		zoom
 */
function ParseRegionData(xml_node) { /* {{{ */

	var area			= new Object();		// create new area data object

	// initialize area data object
	area.points			= new Array();				// create new array for holding points
	area.border_weight	= DEFAULT_BORDER_WEIGHT;	// set border weight to default weight
	area.border_color	= DEFAULT_BORDER_COLOR;		// set border color to default color
	area.fill_color		= DEFAULT_FILL_COLOR;		// set fill color to default color
	area.opacity		= DEFAULT_OPACITY;			// set opacity to default opacity
	area.zoom			= null;						// container object holding min and max zoom level display data
	area.tags			= new Array();				// array of tags describing the region
	area.display		= true;						// flag for determining if the area should be displayed

	// get fill color from XML node
	area.fill_color = '#' + xml_node.getAttribute("fillcolor");

	// get opacity from XML node
	area.opacity = xml_node.getAttribute("opacity");

	// get zoom level properties from XML node
	var min_zoom = xml_node.getAttribute("minzoom");
	var max_zoom = xml_node.getAttribute("maxzoom");

	// create area zoom level object
	area.zoom = CreateZoomLevelObject(min_zoom, max_zoom);

	// get border properties from XML node
	var border_weight = GetNodeAttribute(xml_node, "border", "weight");
	var border_color = GetNodeAttribute(xml_node, "border", "color");

	// Region borders are optional in the XML schema, so need to make sure one was specified
	
	// check if a border weight was found
	if (border_weight) {
		// ... if so replace default with retrieved weight
		area.border_weight = border_weight;
	}

	// check if a border color was found
	if (border_color) {
		// ... if so replace default with retrieved color
		area.border_color = '#' + border_color;
	}

	// get tag list
	var tags = xml_node.getElementsByTagName("tag");

	// loop through and process tags
	for (var i = 0; i < tags.length; i++) {
		area.tags.push(tags.item(i).firstChild.nodeValue);
	}
	// all regions belong to the 'all' group
	area.tags.push('all');

	// retrieve vertices data from the XML node
	var vertices = xml_node.getElementsByTagName("vertex");

	// check if a defined region was specified (at least a triangle)
	if (vertices.length < 2) {
		// ... if not, then return area object as is
		return area;
	}

	// loop through and process vertices data
	for (var i =0; i < vertices.length; i++) {

		var vertex = vertices.item(i);	// get vertex node from collection

		var lat = vertex.getAttribute("lat");	// get latitude coordinate
		var lng = vertex.getAttribute("lng");	// get longitude coordinate

		// add vertex to points array
		area.points.push(new GLatLng(lat, lng));
	}

	// return area object
	return area;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function removes all overlays from the map.
*/
function HideOverlays() { /* {{{ */

	g_map.clearOverlays();

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function displays all overlays on the map.
 */
function ShowOverlays() { /* {{{ */

	ShowMarkers();
	ShowRegions();

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function handles click events for a region overlay. It
	displays the info window associated with the clicked region.
	@param point The point of the mouse click
 */
function RegionClick(point) { /* {{{ */

	// get index of region
	var index = GetRegionIndex(this);
	var html = '';

	// check if index is valid
	if (index == -1) {
		// if not, do nothing
		return;
	}

	// Add RegionClick event task here

	return;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function returns the index of the given region in the global
	region array.
	@param region Reference a region object.
	@return The index of the given region in the global region array, or
	-1 if not found.
 */
function GetRegionIndex(region) { /* {{{ */

	// index in global array, -1 for not found
	var index = -1;

	// loop over all regions to search
	for (var i = 0; i < g_region_data.length; i++) {

		// check if the regions are the same
		if (g_region_data[i].region == region) {
			index = i;
			break;
		}
	}

	return index;
} /* }}} */

/*--------------------------------------------------------------------------*/
/**
	@brief This function set the display flag of all regions with a matching
	tag to the value of is_enabled.
	@param is_enabled Value to set the display attribute to.
	@param tag Region tag to toggle display for.
 */
function ToggleRegions(is_enabled, tag) { /* {{{ */

	// loop over all regions
	for (var i = 0; i < g_region_data.length; i++) {

		var tag_list = g_region_data[i].tags; // get tag list for current region
		var match_found = false; // whether or not a matching tag was found

		// loop over the tag list of the region
		for (var j = 0; j < tag_list.length; j++) {

			if (tag == tag_list[j]) {
				match_found = true;
			}
		}

		// check if a match was found
		if (true == match_found) {

			// if so, set display value
			g_region_data[i].display = is_enabled;

			// update region display
			if (true == is_enabled) {
				g_map.addOverlay(g_region_data[i].region);
			}
			else {
				g_map.removeOverlay(g_region_data[i].region);
			}
		}
	}

	return;
} /* }}} */

