var debug=0;

// global vars
var map;
var map_latitude; 
var map_longitude; 
var map_zoom_level;
var map_zoom_control_size = '' ;

// marker/bubble vars
var sitePath = '';
var load_markers = false;
var marker_type = '' ;
var map_is_small = false;  
var map_gb_link = '';
var view_event_url;
var view_event_label;
var view_profile_url;
var view_profile_label;
var customIcons = [];
var markerGroups = { "event": [], "person": [] };
var json = { 'event': [], 'person': [] };
var bubbleHTML ;
var bubble_html_template = '' ;
var map_bubble_break = '' ;
var cluster=[];
var markerGroupPreviouslyLoaded = { 'event': false, 'person': false };
var cluster_marker_title = '';
var cluster_options={ borderPadding:256, intersectPadding:0, clusteringEnabled:true, fitMapMaxZoom:15 };
var load_marker_type ;
var people_cluster_ready = false;
var people_cluster_queue = [] ; 

var ajax_url_queue_ready = true;
var ajax_url_queue = [];
var timeout_interval_ajax = 750;

var person  = { max_min: { max_lat:0, max_lng:0, min_lat:0, min_lng:0 } } ; 
var event   = { max_min: { max_lat:0, max_lng:0, min_lat:0, min_lng:0 } } ; 
var overall = { max_min: { max_lat:0, max_lng:0, min_lat:0, min_lng:0 } } ; 

var response_object ;

// main_map vars
var map_main = false ;
var events_xml_url ;
var	people_xml_url ;
var max_steps_needed_to_load_persons_on_map = 1;
var max_steps_needed_to_load_persons_on_map_multiple = 1;
var display_checkboxes = false;
var use_labels = false;

// select dropdown vars
var polyline ;
var polyline_params = { lineColor:'#979797', lineWeight:10, lineOpacity:.5, flash_start:500, flash_interval:250, flash_times:4 } ;

// createGoogleMap
// --includes the necessary libraries, sets up the icons, and adds the load and unload events 
function createGoogleMap() {

	createCustomIcons() ;
	addLoadEvent(load);
	addUnLoadEvent(GUnload);

	if(events_xml_url) 
	{
		includeFile(events_xml_url) ;
	}

//	includeFile(sitePath+'templates/go/scripts/extlargemapcontrol_packed.js') ;	

	// note: _packed does not include modification to use fitMapMaxZoom on click of clustered marker
	includeFile(sitePath+'templates/go/scripts/ClusterMarker.js') ;
//	includeFile(sitePath+'templates/go/scripts/ClusterMarker_packed.js') ;

	if(people_xml_url) 
	{
		includeFile(people_xml_url) ; // this includes the first batch of json people data (like json['person'][1])

		var $step_url = people_xml_url + '&process_step=';

		var $timeout_num = 1;
		var $step_index = 2; // 1 is handled in the first iteration above
		while($step_index <= max_steps_needed_to_load_persons_on_map)
		{
			var next_marker_group_title = 'person_'+$step_index;
			markerGroups[next_marker_group_title] = [];

			var $next_ajax_url = $step_url + $step_index;
			ajax_url_queue.push($next_ajax_url); 
			setTimeout("processAjaxQueue()", timeout_interval_ajax*$timeout_num) ; // time between attempts of processing JSON calls
			$timeout_num = $timeout_num+1;
			$step_index = $step_index+1;
		}

		var $multiple_url = people_xml_url + '&multiple_people_per_location=1&process_step=' ;

		var $step_index = 1; 
		while($step_index <= max_steps_needed_to_load_persons_on_map_multiple)
		{
			var next_marker_group_title = 'person_mult'+$step_index;
			markerGroups[next_marker_group_title] = [];

			var $next_ajax_url = $multiple_url + $step_index;
			ajax_url_queue.push($next_ajax_url); 
			setTimeout("processAjaxQueue()", timeout_interval_ajax*$timeout_num) ; // time between attempts of processing JSON calls
			$step_index = $step_index+1;
			$timeout_num = $timeout_num+1;
		}
	}
} 
// End of createGoogleMap



// createCustomIcons
// --this provides the necessary code for the icons
// --to change the icon simply change the URL
function createCustomIcons() {

    var iconBlue = new GIcon(); 
    iconBlue.image = sitePath+'templates/go/images/map_marker_20_blue.png';
    iconBlue.shadow = sitePath+'templates/go/images/map_marker_20_shadow.png';
    iconBlue.iconSize = new GSize(12, 20);
    iconBlue.shadowSize = new GSize(22, 20);
    iconBlue.iconAnchor = new GPoint(6, 20);
    iconBlue.infoWindowAnchor = new GPoint(5, 1);
    customIcons["event"] = iconBlue;

    var iconBlueCluster = new GIcon(); 
    iconBlueCluster.image = sitePath+'templates/go/images/map_marker_arrow_39x34_blue.png';
    iconBlueCluster.shadow = sitePath+'templates/go/images/map_marker_arrow_39x34_shadow.png';
    iconBlueCluster.iconSize = new GSize(39, 34);
    iconBlueCluster.shadowSize = new GSize(39, 34);
    iconBlueCluster.iconAnchor = new GPoint(9, 31);
    iconBlueCluster.infoWindowAnchor = new GPoint(9, 31);
    customIcons["event_cluster"] = iconBlueCluster;
    
    var iconRed = new GIcon(); 
    iconRed.image = sitePath+'templates/go/images/map_marker_20_red.png';
    iconRed.shadow = sitePath+'templates/go/images/map_marker_20_shadow.png';
    iconRed.iconSize = new GSize(12, 20);
    iconRed.shadowSize = new GSize(22, 20);
    iconRed.iconAnchor = new GPoint(6, 20);
    iconRed.infoWindowAnchor = new GPoint(5, 1);
    customIcons["person"] = iconRed;

    var iconRedCluster = new GIcon(); 
    iconRedCluster.image = sitePath+'templates/go/images/map_marker_arrow_39x34_red.png';
    iconRedCluster.shadow = sitePath+'templates/go/images/map_marker_arrow_39x34_shadow.png';
    iconRedCluster.iconSize = new GSize(39, 34);
    iconRedCluster.shadowSize = new GSize(39, 34);
    iconRedCluster.iconAnchor = new GPoint(9, 31);
    iconRedCluster.infoWindowAnchor = new GPoint(9, 31);
    customIcons["person_cluster"] = iconRedCluster;

    cluster_options.clusterMarkerTitle = cluster_marker_title;
} 
// End of createCustomIcons



// load
// -- sets up the map
// -- requires a div with id=map and either
// 1) the three vars: map_latitude, map_longitude, and map_zoom_level
// 2) map_main = true 
function load() {
	if (GBrowserIsCompatible()) {

        map = new GMap2(document.getElementById("map"));
        var point = new GLatLng(map_latitude,map_longitude) ;
        if(!map_main) {
        	map.setCenter(point, map_zoom_level); 
        }
		map.setMapType(G_NORMAL_MAP); // G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP
		
		switch(map_zoom_control_size)
		{
//			case 'extra_large':
//				map.addControl(new ExtLargeMapControl()); <!--{* alternatives: ExtLargeMapControl(), GLargeMapControl(), GSmallMapControl(), GSmallZoomControl() *} //-->
//				break;
			default :
			case 'large':
				map.addControl(new GLargeMapControl()); <!--{* alternatives: ExtLargeMapControl(), GLargeMapControl(), GSmallMapControl(), GSmallZoomControl() *} //-->
				break;
			case 'small':
				map.addControl(new GSmallMapControl()); <!--{* alternatives: ExtLargeMapControl(), GLargeMapControl(), GSmallMapControl(), GSmallZoomControl() *} //-->
				break;
			case 'zoom_only':
				map.addControl(new GSmallZoomControl()); <!--{* alternatives: ExtLargeMapControl(), GLargeMapControl(), GSmallMapControl(), GSmallZoomControl() *} //-->
				break;
			case 'off':
				// do nothing
				break;
		}
		if(map_main) {
			map.addControl(new GOverviewMapControl()); <!--{* shows overview box in lower right corner *} //--> 
			map.addControl(new GMapTypeControl()); <!--{* lets visitor flip between types of maps *} //-->
			
			var center_and_zoom_all = true;
			if(load_marker_type)
			{
				if(load_marker_type == 'event' || load_marker_type == 'all') {
					loadMarkersFromJSON('event') ;
					cluster_options.clusterMarkerIcon = customIcons["event_cluster"] ;
					cluster_options.markers = markerGroups['event'] ;
					cluster['event']=new ClusterMarker(map, cluster_options);
					if(load_marker_type != 'all') // event only on first load
					{
						centerAndZoom(event.max_min);
						center_and_zoom_all = false ;
					}
					cluster['event'].refresh();
					markerGroupPreviouslyLoaded['event'] = true;
				}
				if(load_marker_type == 'person' || load_marker_type == 'all') 
				{
					loadMarkersFromJSON('person') ;
					cluster_options.clusterMarkerIcon = customIcons["person_cluster"] ;
					cluster_options.markers = markerGroups['person'] ;
					cluster['person']=new ClusterMarker(map, cluster_options);
					if(load_marker_type != 'all') // person only on first load
					{
						centerAndZoom(person.max_min);
						center_and_zoom_all = false ;
					}
					cluster['person'].refresh();
					markerGroupPreviouslyLoaded['person'] = true ;
					people_cluster_ready = true ;
					
				}
			}
			if(center_and_zoom_all)
			{
				centerAndZoom(overall.max_min);
			}
			
		} else if(load_markers) { // not map_main but still load_markers (single marker) 
			var marker = createMarker(point, (bubbleHTML ? bubbleHTML.getHTML() : ' '), ( marker_type ? marker_type : 'event'));
			map.addOverlay(marker);	
		}

		// turn off loading graphic by replacing the background: url() with a color
		document.getElementById('map').style.background = '#99B3CC'; // #99B3CC is the color of the ocean

    }
} 
// End of load



function centerAndZoom($max_min_obj)
{
	if($max_min_obj.max_lat || $max_min_obj.min_lat 
	   || $max_min_obj.max_lng || $max_min_obj.min_lng
	   ) 
	{
		// we have the outer bounds, so use them to determine the map boundaries/zoom
		var $sw = new GLatLng($max_min_obj.max_lat,$max_min_obj.min_lng)
		var $ne = new GLatLng($max_min_obj.min_lat,$max_min_obj.max_lng)
		var $map_boundary=new GLatLngBounds($sw,$ne); // add the max/min points to the viewable area
		
		var $zoomLevel=map.getBoundsZoomLevel($map_boundary); // get the zoom level for this size map
			
		map.setCenter($map_boundary.getCenter(), $zoomLevel); // redraw the map
		
	} else {
		// we don't have the outer bounds, so we have to use the default center/zoom instead
	    var $point = new GLatLng(map_latitude,map_longitude) ;
		map.setCenter($point, map_zoom_level); 
	}
}


function loadMarkersFromJSON(type) {

	if(type == 'event' || type == 'person' ) {
		for (var i=0; i<json[type].length; i++) {
			var marker = createMarker(new GLatLng(json[type][i].lat, json[type][i].lng), json[type][i].html, type);
			markerGroups[type].push(marker);
		}
		return true;
	}
	else { return false ; }
}

/*	
	loadNextJSONfile($url_to_load)
		@param $url_to_load - url of the JSON data
		purpose:
			AJAX call to load the JSON data into a batch_object
		requires:
			AJS object in AJS.js for request processing and eval of resulting string
			loadNextMarkerBatch() to load markers after getting JSON data 
		used by:
			createGoogleMap() to load data files
*/
function loadNextJSONfile($url_to_load) {
	var $request = AJS.getRequest($url_to_load);
	$request.addCallback(function(res_txt, req) {
	    //Eval response text to turn response into a JSON object
	    var $batch_object = AJS.evalTxt(res_txt);
		loadNextMarkerBatch($batch_object);
	});
	$request.sendReq();
}

/*	
	processAjaxQueue()
		purpose:
			used to create timeout between ajax requests to ease server burden
		requires:
			ajax_url_queue (array of temp urls to process)
			ajax_url_queue_ready (boolean whether or not to process queue now or wait)
			loadNextJSONfile() called to issue ajax request
		used by:
			createGoogleMap() adds a url to the queue and calls this function
			processAjaxQueue() recursively calls itself when a timeout is needed
*/
function processAjaxQueue() {
	if(typeof(ajax_url_queue) == 'undefined' 
	   || ajax_url_queue.length == 0) {
		// nothing in the queue
//		alert('nothing in queue');
	} else {
		var $url_to_load = ajax_url_queue.pop() ;
		if(!ajax_url_queue_ready) {
			// so we wait... 
			ajax_url_queue.push($url_to_load); 
			setTimeout("processAjaxQueue()", timeout_interval_ajax) ; // time between attempts of processing JSON calls
		} else {
			// success! the url queue is ready
//			alert('processing AjaxQueue with url_to_load'+$url_to_load);
			ajax_url_queue_ready = false;
			loadNextJSONfile($url_to_load);
			ajax_url_queue_ready = true;
		}
	}	
}



/*	
	loadNextMarkerBatch($batch_object)
		@param $batch_object - JSON object to load
		purpose:
			creates markers, adds them to the temp marker group, adds the title to the queue, and calls processMarkerQueue()
		requires:
			$batch_object.marker_group_title (title of the marker group)
			$batch_object.person_temp (JSON array with 'lat', 'lng', and 'html' elements)
			createMarker() (creates the markers)
			markerGroups[] (holds the markers)
			people_cluster_queue (holds the title of this group of markers until processed)
			processMarkerQueue() 
		used by:
			loadNextJSONfile() uses this function in its callback function
*/
function loadNextMarkerBatch($batch_object) {
	if(typeof($batch_object) == 'undefined' 
	   || typeof($batch_object.marker_group_title) == 'undefined'
	   || typeof($batch_object.person_temp) == 'undefined'
    ) { 
		// do nothing (empty file)
	} else {
		// load the markers in the array

//		alert('$batch_object.marker_group_title: '+$batch_object.marker_group_title);
		
		
		for (var i=0; i<$batch_object.person_temp.length; i++) {
			var $marker = createMarker(new GLatLng($batch_object.person_temp[i].lat, $batch_object.person_temp[i].lng), $batch_object.person_temp[i].html, 'person');
			markerGroups[$batch_object.marker_group_title].push($marker);
		}
		people_cluster_queue.push($batch_object.marker_group_title); 
		processMarkerQueue() ;
	}
}



/*	
	processMarkerQueue()
		purpose:
			used to ensure no collisions when creating new clusters
		requires:
			people_cluster_queue (array of temp marker group titles to process)
			people_cluster_ready (boolean whether or not to process queue now or wait)
			cluster['person'] (cluster object to add markers to)
			mergeTempMarkersWithMaster() called after adding temp markers to clusters
		used by:
			loadNextMarkerBatch() adds a title to the queue and calls this function
			processMarkerQueue() recursively calls itself when a timeout is needed
*/
function processMarkerQueue() {

	if(typeof(people_cluster_queue) == 'undefined' 
	   || people_cluster_queue.length == 0) {
		// nothing in the queue
	} else {
		var $marker_group_title = people_cluster_queue.pop() ;
		if(load_marker_type != 'person' && load_marker_type != 'all') {
			// no need to load the markers
			// just merge the temp markers with the master marker group (so they'll toggle together)
			mergeTempMarkersWithMaster($marker_group_title) ;
		} else if(!people_cluster_ready) {
			// so we wait... 
			people_cluster_queue.push($marker_group_title); 
			setTimeout("processMarkerQueue()", 500) ; // time between attempts of processing JSON calls
		} else {
			// success! the people cluster is ready
			// now add the markers to it
			people_cluster_ready = false ;
			cluster['person'].addMarkers(markerGroups[$marker_group_title]) ;
			cluster['person'].refresh();
			// and merge with the master array (so they toggle together)
			mergeTempMarkersWithMaster($marker_group_title) ;
			people_cluster_ready = true ;
		}
	}
}


/*	
	mergeTempMarkersWithMaster($marker_group_title)
		@param $marker_group_title - title of temporary marker group
		purpose:
			joins temporary marker groups with master marker group
			needed so toggle can on/off the whole group of markers
		requires:
			markerGroups['person'] (master array - can be empty)
		used by:
			processMarkerQueue() after adding the temp group to the cluster
*/
function mergeTempMarkersWithMaster($marker_group_title) {
	for(i=0; i<markerGroups[$marker_group_title].length; i++) {
		markerGroups['person'].push(markerGroups[$marker_group_title][i]);
	}
}


// createMarker
// --creates an individual marker
// --adds InfoWindow to marker's onclick event
// --when it's a single marker (!map_main) it opens the InfoWindow attached to the marker
//function createMarker(point, html, type, label, visibility) {
function createMarker(point, html, type) {
	var marker ;
	marker = new GMarker(point, customIcons[type]);
	
	// get the max bubble_width of the bubble (otherwise long words force the bubble off the map)
	var bubble_width = getMapBubbleWidth();
                                                                                                                              
    if (map_is_small)
    {                                              
        //HACK This can me made more special purpose -- function with global variables.  Just like the rest of this class....
        GEvent.addListener(marker, 'click', function() {
            GB_showCenter('', map_gb_link, 502, 722);
        });
    }
    else
    {     
        GEvent.addListener(marker, 'click', function() {
            marker.openInfoWindowHtml(html, { maxWidth: bubble_width });
        });
        if(!map_main) { // open bubble when single marker
            map.openInfoWindowHtml(point, html, { maxWidth: bubble_width });
        }
    }
    return marker;
} 
// End of createMarker


// bubbleHTMLObject
// --builds the HTML for the marker's bubble
// -- we use this for maps with single markers
function bubbleHTMLObject(itemid, name, name2, street, city, state, zip, country, date, time, link_url, link_label, is_onclick) {
	this.getHTML = function() 
	{
		var html = bubble_html_template ;
		
		var thumbnail = '' ; // no thumbnail on the individual maps, yet
		if(thumbnail) html = html.replace('+THUMBNAIL+', date).replace('+THUMBNAIL_BREAK+', map_bubble_break) ;
		else html = html.replace('+THUMBNAIL+', '').replace('+THUMBNAIL_BREAK+', ' ') ;
		
		if(date) html = html.replace('+DATE+', date).replace('+DATE_BREAK+', map_bubble_break) ;
		else html = html.replace('+DATE+', '').replace('+DATE_BREAK+', ' ') ;

		if(time) html = html.replace('+TIME+', time).replace('+TIME_BREAK+', map_bubble_break) ;
		else html = html.replace('+TIME+', '').replace('+TIME_BREAK+', ' ') ;

		if(name) html = html.replace('+NAME1+', name).replace('+NAME1_BREAK+', map_bubble_break) ;
		else html = html.replace('+NAME1+', '').replace('+NAME1_BREAK+', ' ') ;

		if(name2) html = html.replace('+NAME2+', name2).replace('+NAME2_BREAK+', map_bubble_break) ;
		else html = html.replace('+NAME2+', '').replace('+NAME2_BREAK+', ' ') ;

		if(street) html = html.replace('+STREET+', street).replace('+STREET_BREAK+', map_bubble_break) ;
		else html = html.replace('+STREET+', '').replace('+STREET_BREAK+', ' ') ;

		if(city) 
		{
			html = html.replace('+CITY+', city) ;
			if(state) html = html.replace('+CITY_STATE_COMMA+', ', ') ;
			else html = html.replace('+CITY_STATE_COMMA+', ' ') ;
		}
		else 
		{
			html = html.replace('+CITY+', '').replace('+CITY_STATE_COMMA+', '') ;
		}

		if(state) html = html.replace('+STATE+', state) ;
		else html = html.replace('+STATE+', '') ;

		if(zip) html = html.replace('+ZIP+', zip) ;
		else html = html.replace('+ZIP+', '') ;

		if(city || state || zip) html = html.replace('+CITY_STATE_ZIP_BREAK+', map_bubble_break) ;
		else html = html.replace('+CITY_STATE_ZIP_BREAK+', '') ;

		if(link_url && link_label && itemid) 
		{
    		if (is_onclick)
    		{
    		    // TODO: Make is_onclick more than just a bool
                var location_link = '<a action="#" onclick="GB_showCenter(\'\',\'' + link_url;
                location_link += '\', 500, 720, this.href);"' + '>' + link_label + '</a>';
                html = html.replace('+VIEW_LOCATION_LINK+', location_link).replace('+LINKS_BREAK+', map_bubble_break); 
    		} 
    		else
    		{
			    var location_link = '<a href="' + link_url + itemid + '">' + link_label + '</a>' ;
			    html = html.replace('+VIEW_LOCATION_LINK+', location_link).replace('+LINKS_BREAK+', map_bubble_break) ; 
		    }
		}
		else 
		{
			html = html.replace('+VIEW_LOCATION_LINK+', ' ').replace('+LINKS_BREAK+', ' ') ; 
		}

		// grab all forced breaks
		var strTarget = '+FORCED_BREAK+' ;
		var intIndexOfMatch = html.indexOf( strTarget );
		while (intIndexOfMatch != -1)
		{
			// Relace out the current instance.
			html = html.replace( strTarget, map_bubble_break ) ;
			
			// Get the index of any next matching substring.
			intIndexOfMatch = html.indexOf( strTarget );
		}

		// TODO: add URLs to HTML for bubble
		// here is a sample URL to send via email: http://maps.google.com/staticmap?center=37.400465,-122.073003&markers=37.400465,-122.073003,red&zoom=13&size=500x300&key=YOUR_KEY_HERE
		
		
		// finally add the outer div wrapper to stop extra line breaks from pushing the bubble text down in IE
		var bubble_width = getMapBubbleWidth();
		html = '<div style="width: '+bubble_width+';">' + html + '</div>'; 
		
		debug=0; 
		if(debug) { alert('bubble_width: '+bubble_width); }

		// return the HTML
		return html;
	} ; // this.getHTML()
}
// End of bubbleHTMLObject


var MAX_BUBBLE_WIDTH = 280; // seems to be a good size
// getMapBubbleWidth
// -- gets the bubble_width of the bubble 
// -- called from bubbleHTMLObject (used for maps with single markers)
// -- called from createMarker (all maps)
function getMapBubbleWidth() {

	var bubble_width = MAX_BUBBLE_WIDTH; // initialized at a size the large map can handle
	var map_style_obj = getStyleObject('map') ;  // from common.js
	if(map_style_obj)
	{
		if(map_style_obj.width.charAt(map_style_obj.width.length-1) == '%'  // can't use width if it's a percentage 
		   || parseInt(map_style_obj.width) > 400  // bigger maps get the MAX_BUBBLE_WIDTH
		  )
		{
			// do nothing (bubble_width initialized above)		
		}
		else
		{
			// for smaller maps, use the map's width - 120px for the zoom bar and padding
			bubble_width = parseInt(map_style_obj.width) - 120;
		}
	}       
	return bubble_width;
}


// toggleGroup
// --used to turn on and off marker groups
function toggleGroup(type, obj) {
	if(!obj.checked)  
	{
		// turn off (if on)
		if(markerGroupPreviouslyLoaded[type])
		{
	    	cluster[type].removeMarkers();
	    }
    }
    else // 
    {
		// turn on
		if(markerGroupPreviouslyLoaded[type])
		{
			// just add to map and refresh
			cluster[type].addMarkers(markerGroups[type]);
			cluster[type].refresh();
		}
		else
		{
			// load the markers from scratch
			loadMarkersFromJSON(type) ;
			markerGroupPreviouslyLoaded[type] = true;
			cluster_options.clusterMarkerIcon = customIcons[type+"_cluster"];
			cluster_options.markers = markerGroups[type];
			cluster[type]=new ClusterMarker(map, cluster_options );
//			cluster[type].fitMapToMarkers(); // readjusts the zoom level for this markerGroup only (we use centerAndZoom() instead)
			cluster[type].refresh();
			centerAndZoom(overall.max_min);
		}
	}
} 
// End of toggleGroup


/*	
	zoomToState_US($state_code)
		@param $state_code - 2 letter code for US state
		purpose:
			calls zoomToArea() with stateBorders_US[] and specified state_code
			shows/hides element with id=show_state_again if a state exists with that 2 letter code
		requires:
			stateBorders_US[] (JSON array of state boundary lat/lngs)
		used by:
			US state dropdown selects 
*/
function zoomToState_US($state_code) {
 	var state_exists = zoomToArea(stateBorders_US, $state_code) ;
 	if(state_exists) show('show_state_again') ;
 	else hide('show_state_again') ;
} 


/*	
	zoomToArea($area_border_array, $area_index)
		@param $area_border_array - JSON array of area boundary lat/lngs
		@param $area_index - index of area in $area_border_array
		@return boolean - true if $area_border_array[$area_index] exists, false otherwise
		purpose:
			determines zoom level required to show entire area in viewport
			redraws map and calls flashPolyline()
		requires:
			map, polyline, polyline_params (as global vars)
		used by:
			area dropdown selects 
*/
function zoomToArea($area_border_array, $area_index) {
 	if($area_border_array[$area_index]) {  // check that we have area border info
		if(map) {
			if(polyline) { map.removeOverlay(polyline) ; } // clear any previous area lines
	
			var $area_boundary=new GLatLngBounds();
			for(i=$area_border_array[$area_index].length-1; i>=0; i--){
				$area_boundary.extend($area_border_array[$area_index][i]); // get the boundaries of the area
			}
			
			var $zoomLevel=map.getBoundsZoomLevel($area_boundary); // get the zoom level for this size map
			
			map.setCenter($area_boundary.getCenter(), $zoomLevel); // redraw the map
			
			// show the area border according to the global settings
			polyline = new GPolyline($area_border_array[$area_index], polyline_params.lineColor, polyline_params.lineWeight, polyline_params.lineOpacity);
			flashPolyline(polyline_params.flash_start, polyline_params.flash_interval, polyline_params.flash_times);
		}
		return true;
	} else {
		return false;
	}
} 

/*	
	flashPolyline($start, $interval, $times) 
		@param $start - number of seconds to wait before adding polyline to map
		@param $interval - number of seconds to wait when turning polyline on/off
		@param $times - number of times to flash polyline
		purpose:
			flashes the polyline to show user the current area being shown
		requires:
			map, polyline (as global vars)
		used by:
			zoomToArea()
*/
function flashPolyline($start, $interval, $times) {
	var $num_seconds_out = $start ;
	var $num_times = $times * 2; 
	if($num_times%2 != 0) $num_times++ ; // need to starrt with an even number
	if($num_times < 0) $num_times = 0 ;
	for(i=$num_times; i>0; i--) {
		if(i%2 == 0)
			setTimeout("map.addOverlay(polyline)", $num_seconds_out) ;
		else
			setTimeout("map.removeOverlay(polyline)", $num_seconds_out) ;
		$num_seconds_out += $interval ;
	}
}


// printMapInfo
// --helper function can be used to get lat/lng and zoom info from current map view
function printMapInfo() {
	var center = map.getCenter(); 
	var zoom = map.getZoom();
	alert("Lat/Lng of center: "+center.toUrlValue()+"\nZoomlevel: "+zoom);
} // printMapInfo()
// End of printMapInfo


// includeFile
// --reduces need to repeat javascript tags in each different template file
// --files can be included once in this javascript library, then only this library needs to be included from each template file
function includeFile(filename) 
{
	// '<' and script here are broken apart to avoid browser HTML conflicts
	document.write('<' + 'script src="' + filename + '"' +' type="text/javascript"><' + '/script>');
} 
// End of includeFile


