/**
 * SoCalWeather.Net Fire Season Map
 *
 * A script that uses the Google Maps API and AJAX to display a map showing
 * the approximate locations of all fires for a given fire season.
 *
 * @version 0.1.0b 20060714 (Primero)
 * @author Andrew Murphy <andrew@socalweather.net>
 * @copyright 2006 SoCalWeather.Net 
 * @license Creative Commons 2.5 <http://creativecommons.org/licenses/by/2.5/>
 */



/**
 * Personal google map key used by the domain displaying the map
 */
//var MAP_KEY = "ABQIAAAAnR7OI87pLjGiOGNeF8ZxOhTEbfuct5bGiEWczKzNR8LfW99AHRQrGNFpL547WVed51mvyaiW4tSKkA";
var MAP_KEY = "ABQIAAAAnR7OI87pLjGiOGNeF8ZxOhTEbfuct5bGiEWczKzNR8LfW99AHRQrGNFpL547WVed51mvyaiW4tSKkA";

/**
 * Storage for the info markers displayed on the maps
 */
var FIRE_MARKERS      = new Array();
/**
 * Storage for individual fire descriptions
 */
var FIRE_DESCRIPTIONS = new Array();


/**
 * Id of the HTML entity that will contain the listing of all fires
 */
var ID_FIRE_LIST = "fire-listing";

//include the Google Map API
include("http://maps.google.com/maps?file=api&v=1&key="+MAP_KEY);
//include our personal macros and functions for the Google Map API
include(SCRIPT_BIN+"maps.js"); //load local map scripting

/**
 * Cannon fodder data to force a refresh of fire.xml every time the script is loaded
 */
var fodder = new Date();

/**
 * Relative or absolute path to the xml file that will contain our fire data
 */
var PATH_FIRE_FEED  = "fires.xml?"+fodder.valueOf(); //path to the fires data feed

/**
 * Id of the HTML entity that will contain our status message as it is updated
 */
var ID_FIRES_STATUS = "fires-status";


/**
 * Template for each fires individual description.
 *
 * This description is displayed in an infoWindow above each fires marker.
 */
var TEMPLATE_FIRE_DESCRIPTION = "\n<div class=\"fire-marker\">\n\t<div class=\"title\"><strong>%FIRE-TITLE%</strong></div>\n\t<div class=\"stat timeframe\"><strong>Timeframe:</strong> %FIRE-TIMEFRAME%</div>\n\t<div class=\"stat status\"><strong>Status:</strong> %FIRE-STATUS%</div>\n\t<div class=\"summary\">%FIRE-SUMMARY%</div>\n\t<small class=\"revision\">Last Updated: %FIRE-REVISION%</small>\n</div>\n";

var map = null;


var TEMPLATE_FIRE_LIST       = "\n<ol>\n%FIRES%\n</ol>\n";
var TEMPLATE_FIRE_LIST_EMPTY = "<em>There are haven't been any fires this season.</em>";
var TEMPLATE_FIRE_LIST_ITEM  = "\n<li><h4><a href=\"javascript:display_fire(%FIRE-ID%);\">%FIRE-TITLE%</a></h4></li>\n";





/**
 * Update Fires Satus Message
 *
 * Update the message box displaying the status of the map.<b> 
 * If msg is an empty string, the box's css display property is set to "none"
*/
update_fires_status = function(msg){
	//msg = trim(msg);

	if(document.getElementById){
		node = document.getElementById(ID_FIRES_STATUS);
		node.innerHTML = msg;

		if(msg == ""){
			node.style.display = "none";
		}else{
			if(node.style.display == "none"){
				node.style.display = "block";
			}
		}

		return true;
	}

	return false;
}







/**
 * Update Fires Satus Message
 *
 * Return a string containing a description of the fire, formatted in html,
 * for placing on the map.
 * The fire argument as a hash table with the following keys:
 *
 * title:     (String) The name of the fire
 * timeframe: (String) A preformatted start and end date for the fire    (this may change in a later version)
 * status:    (String) The fires current status
 * summary:   (String) A summary of the fire, and any damage it may have caused
 * revision:  (String) A preformatted string contained the date of the last revision and its author
*/
build_fire_description = function(fire){
	var description = TEMPLATE_FIRE_DESCRIPTION;
	var months = new Array(
		"Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" ,
		"Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec"
	);
	var started = new Date();
	var ended   = new Date();
	var revised = new Date();

	var timeframe = "";
	var revision  = "";

	format_date = function(ts){
		return (
			months[ts.getMonth()] + " "  +
			(
				ts.getDate() < 10 ?
				"0"               :
				""
			)                     +
			ts.getDate()          + ", " +
			ts.getFullYear()
		);
	}


		started.setTime( fire["started"] );
		ended.setTime(   fire["ended"]   );
		revised.setTime( fire["revised"] );

		timeframe = format_date(started) + " - "  + format_date(ended);
		revision  = format_date(revised) + " by " + fire["author"];

		description = str_replace("%FIRE-TITLE%"     , fire["title"]   , description);
		description = str_replace("%FIRE-TIMEFRAME%" , timeframe       , description);
		description = str_replace("%FIRE-STATUS%"    , fire["status"]  , description);
		description = str_replace("%FIRE-SUMMARY%"   , fire["summary"] , description);
		description = str_replace("%FIRE-REVISION%"  , revision , description);

	return description;
}







/**
 * Retrieve a fires information
 *
 * Takes an xml document piece and returns a hash table with the following keys:
 *
 * title:     (String) The name of the fire
 * timeframe: (String) A formatted start and end date for the fire    (this may change in a later version)
 * status:    (String) The fires current status
 * summary:   (String) A summary of the fire, and any damage it may have caused
 * revision:  (String) A formatted string contained the date of the last revision and its author
 * point      (GPoint) A GPoint that will be used by the map to place the marker above where the fire occurred
*/
get_fire_data_from_xml = function(fireData){

	var fire     = new Object();
	var property = null;
	var ts       = new Date();

	properties = fireData.getElementsByTagName("property");


	var i = 0;
	var j = 0;
	for(i = 0; i < properties.length; i++){
		property = properties[i];

		fire[property.getAttribute("id")] = property.getAttribute("value");

	}

	description = fireData.getElementsByTagName("description");


	fire["title"]   = fireData.getAttribute("id");
	fire["revised"] = ts.setTime(Date.parse(fire["revised"]));
	fire["started"] = ts.setTime(Date.parse(fire["started"]));
	fire["ended"]   = ts.setTime(Date.parse(fire["ended"]));

	var loc = fire["location"].split(" , ");

	fire["point"]     = new GPoint(parseFloat(loc[0]), parseFloat(loc[1]));
	fire["summary"]   = description.item(0).childNodes[0].nodeValue;



	return fire;
}














populate_fires = function(feedUrl, map, markers){
	var request = GXmlHttp.create();

	update_fires_status("Requesting Fires Data...");

	request.open("GET", feedUrl, true);

	request.onreadystatechange = function(){

		//if we're ready to roll
		if(request.readyState == 4){
			var letter = null;
			var image  = null;
			var fireListingArea = document.getElementById(ID_FIRE_LIST);
			var fireList        = "";

			update_fires_status("Generating Fires Map...");

			var xmlDoc = request.responseXML; //xml returned
			var fires = xmlDoc.documentElement.getElementsByTagName("fire");

			if(fires){

				if(fires.length > 0){
					var i = 0;
					for(i = 0; i < fires.length; i++){
					
					
						letter = String.fromCharCode("A".charCodeAt(0) + i); //letter indexing a fire
						image = "http://www.google.com/mapfiles/marker" + letter + ".png";

						fire = get_fire_data_from_xml(fires[i]);
						FIRE_DESCRIPTIONS[i] = build_fire_description(fire);


						markers[i] = create_gmap_marker(fire["point"], image, FIRE_DESCRIPTIONS[i]);

						//populate the map
						map.addOverlay(markers[i]);

						li = str_replace("%FIRE-ID%" , i , TEMPLATE_FIRE_LIST_ITEM);
						li = str_replace("%FIRE-TITLE%" , fire["title"] , li);
						fireList += li;

					}
					fireListingArea.innerHTML = str_replace("%FIRES%", fireList, TEMPLATE_FIRE_LIST);
				}else{
					fireListingArea.innerHTML = TEMPLATE_FIRE_LIST_EMPTY;
				}
				update_fires_status(""); //hide the status message
				return true;


			}else{
				update_fires_status("Fatal error! Map will not be generated!");
				alert("No fire data was returned!");
				return false;
			}
		}
	}

	request.send(null);

}





build_fire_map = function(container, map, markers, loc, zoom){
	map = build_gmap(MAP_DEFAULT_CONTAINER);
	map.centerAndZoom(loc, zoom);
	populate_fires(PATH_FIRE_FEED, map, markers);

	return map;
}





display_fire_on_map = function(index, markers, descriptions){
	if(index < markers){
		markers[index].openInfoWindowHtml(descriptions[index]);
	}
	return;
}



display_fire = function(fireId){
	if(
		typeof fireId == "number"         &&
		fireId >= 0                       &&
		fireId < FIRE_MARKERS.length      &&
		fireId < FIRE_DESCRIPTIONS.length
	){
		map.recenterOrPanToLatLng(FIRE_MARKERS[fireId].point);
		FIRE_MARKERS[fireId].openInfoWindowHtml(FIRE_DESCRIPTIONS[fireId]);
	}

	return;
}



//at startup, load the map with the following properties:
//region container: "map"
//map object: map
//fire markers: FIRE_MARKERS
//center at: -119.0, 37.4419 (lat, lng)
//zoom: 11
load_at_startup("map = build_fire_map('map', map, FIRE_MARKERS, new GPoint(-119.0, 37.4419), 11); update_fires_status('');");

