/* npaihb.js */
//$(document).ready(function(){ //derails the map for unknown reason

var createIcons = function(){
	var locationTypes = ['healthcare',
						 'police',
						 'fish_wildlife',
						 'environmental',
						 'court',
						 'convalescent',
						 'elders',
						 'hospital',
						 'emergency_medical',
						 'fire',
						 'government',
						 'counselling',
						 'youth_child',
						 'disaster_response',
						 'area_overview',
						 'other'];
	
	var altSize = new GSize(32, 32);
	var altIconAnchor = new GPoint(16, 32);
	var standardSize = new GSize(21, 29);
	var standardIconAnchor = new GPoint(10, 29);
	
	
	var iconCollection = new Array();
	for(type in locationTypes){
		iconCollection[locationTypes[type]] = new GIcon(G_DEFAULT_ICON);
		iconCollection[locationTypes[type]].image = "/images/map_icons/";
		iconCollection[locationTypes[type]].iconSize = standardSize;
		iconCollection[locationTypes[type]].iconAnchor = standardIconAnchor;
		iconCollection[locationTypes[type]].shadow = '';
		iconCollection[locationTypes[type]].imageMap = [0,0, 21,0, 21,29, 0,29];
		
	}
	iconCollection['healthcare'].image += 		"marker_health.png";
	iconCollection['police'].image += 			"marker_police.png";
	iconCollection['fish_wildlife'].image += 	"marker_government.png";
	iconCollection['environmental'].image += 	"marker_government.png";
	iconCollection['court'].image += 			"marker_government.png";
	iconCollection['convalescent'].image += 	"marker_health.png";
	iconCollection['elders'].image += 			"marker_health.png";
	iconCollection['hospital'].image += 		"marker_emergency.png";
	iconCollection['emergency_medical'].image += "marker_emergency.png";
	iconCollection['fire'].image += 			"marker_emergency.png";
	iconCollection['government'].image += 		"marker_government.png";
	iconCollection['counselling'].image += 		"marker_health.png";
	iconCollection['youth_child'].image += 		"marker_health.png";
	iconCollection['disaster_response'].image += "marker_disaster.png";
	
	iconCollection['area_overview'].image += 	"marker_general.png";
	/*
	iconCollection['area_overview'].iconSize = 	altSize;
	iconCollection['area_overview'].iconAnchor = altIconAnchor;
	*/
	
	iconCollection['other'].image += 			"marker_general.png";
	return iconCollection;
};

var resetOverlays = function(){
	//clear arrays
	polygonsDrawn = []; 
	markersDrawn = []; 
	markers = [];
	map.clearOverlays(); //note this will also clear markers, etc!
};

/***
 * createOverlays(data)
 * purpose:
 * 	to draw any required overlays,
 *  including polygons, markers, labels, etc.
 *  that are required by the map.
 * arguments: 
 * 	data:	the multidimensional array
 * 			that is the result of the ajax call
 * 			in getMapOverlays().
 * returns:	null
 */
var createOverlays = function(data){
	if(createPolygonOverlays(data.areas) && createMarkerOverlays(data.markers)){
			//test for existence of a main marker
			if(data.main_marker.marker_id){ 
				//if it exists, look for it and open it.  this should only happen in area_map.
				var main_marker_index = getMarkerReference(data.main_marker.marker_id);
				if (main_marker_index >= 0){
					GEvent.trigger(markers[main_marker_index], "click");
				}
			}
	}
	//else? i am unsure of why the above code is inside a conditional. --- ???
}; 

//Searches through markers array for a marker object with a particular id.
//The id property is the stored marker_id: the primary key of the markers table in the database.
//This id is stored when the marker is created.  See createMarker().
//Returns the array index of that marker so it may be referenced.
//Returns -1 if there is no match.
var getMarkerReference = function(id){
	for (var i = 0; i < markers.length; i += 1){
		if (markers[i].id === id){
			return i;
		}
	}
	return -1;
};

//This function tests whether the polygon has been already drawn, and if it has not,
//it creates a GPolygon object, sets its necessary properties, and adds it to the map.
//Then it adds the polygon's id to the array of polygons ids that have been already drawn.
//This id is the primary key of the polygons table in the database.
var createPolygonOverlays = function(polygon_data){
	for(var i = 0; i < polygon_data.length; i += 1){
		//test whether this area has been drawn already
		var drawn = false;
		for(var j = 0; j < polygonsDrawn.length; j += 1){
			if (polygon_data[i].id === polygonsDrawn[j]){
				drawn = true;
				break;
			}
		} 
		/*** POLYGON ***/
		if(!drawn){
			var polygon = new GPolygon.fromEncoded({
				polylines: [
				   {color: "#803624",
					weight: 0.5,
					opacity: 0.8,
					points: polygon_data[i].points,
					levels: polygon_data[i].levels,
					zoomFactor: polygon_data[i].zoomFactor, 
					numLevels: polygon_data[i].numLevels
					}],
				fill:true,
				color: "#d18e7d",
				opacity: 0.5,
				outline: true,
				//id is not standard google maps code.  
				//helps keep track of which polygons have been drawn.
				//see polygonsDrawn.push() below.
				id: polygon_data[i].id 	
			});
			map.addOverlay(polygon);
			polygonsDrawn.push(polygon_data[i].id); //keep track of which polygons have been drawn
		} /*** END POLYGON ***/
	} 
	return true; //for the conditional in createOverlays() --- ???
};

//this function iterates through the array of marker data sets,
//checks if the marker has already been drawn, and if not, 
//it calls addOverlay for each marker.
//Then it adds the marker's id to the array of marker ids that have already been drawn.
//This id is the primary key of the markers table in the database.
var createMarkerOverlays = function(marker_data){
	//code block for markers.  also see below createMarker().
	
	//newMarkers is for markermanager -- here in case strategy reversed 
	//var newMarkers = new Array();
	for(var i = 0; i < marker_data.length; i += 1){
		//test whether this marker has been drawn already
		var drawn = false;
		for(var j = 0; j < markersDrawn.length; j += 1){
			if (marker_data[i].marker_id === markersDrawn[j]){
				drawn = true;
				break;
			}
		}
		if(!drawn){
			//these two markermanager lines no longer used -- here in case strategy reversed 
			//mgr.addMarker(createMarker(marker_data[i]), 6);
			//newMarkers.push(createMarker(marker_data[i]));
			
			map.addOverlay(createMarker(marker_data[i]));
			markersDrawn.push(marker_data[i].marker_id);
		}
	}
	//these two markermanager lines no longer used -- here in case strategy reversed 
	//mgr.addMarkers(newMarkers, 5); // 5 is the min-zoom to see markers
	//mgr.refresh(); // draws markers on map
	
	return true; //for the conditional in createOverlays() --- ???
};

/***
 * createMarker(marker_data)
 * purpose:
 * 	to instatiate one marker and 
 *  give it an infoWindow that will open upon click.
 * arguments: 
 * 	marker_data:	an array that originally comes from
 * 					the result of the ajax call in getMapOverlays().
 * 					marker_data is synonymous with data.markers[index].	
 * returns:	a GMarker object.
 */
var createMarker = function(marker_data){
	
	var location = new GLatLng(marker_data.marker_lat, marker_data.marker_lng);
	var title = marker_data.location_name ? marker_data.location_name : marker_data.area_name;
	var icon = marker_data.location_type ? icons[marker_data.location_type] : icons['area_overview'];
	var markerOptions = {title: title, icon: icon};
	var marker = new GMarker(location, markerOptions);
	marker.id = marker_data.marker_id;
	
	GEvent.addListener(marker, "click", function() {
		getInfoWindowHtml(marker, marker_data.marker_id, marker_data.area_name);
    });
	
	markers.push(marker);
	
	//GEvent.addListener(marker, "remove", function(){alert('test');}); //shows the problem with using MarkerManager
    
	return marker;
};

/***
 * getInfoWindowHtml(marker_id)
 * purpose:
 * 	to perform an ajax call and retrieve the html string for an infoWindow.
 * arguments: 
 *  marker: Reference to the marker that will open the infoWindow.
 * 	marker_id:  This is the primary key of the markers table in the database.
 * 				It is also a foreign key in the locations table.
 *  area_name: name of the area that this marker is associated with.
 * returns:	null
 */
var getInfoWindowHtml = function(marker, marker_id, area_name){
	$.ajax({
		async: true,
		url: "/info_window",
		type: "POST",
		data: {	marker_id: marker_id, area_name: area_name },
		dataType: "html",
		error: function(){
			marker.openInfoWindowHtml('ajax error');
		},
		success: function(data){
			var dimensions = getInfoWindowSize();
			var html = "<div id='iw_content' style='" + 
			        "height:" + dimensions.height + "px; " +
			        "width:" + dimensions.width	+ "px; " +
			        "'>" + data + "</div>";
			var latlng = marker.getLatLng();
			map.savePosition();
			map.openInfoWindowHtml(latlng, html, {
				onOpenFn: function(){
					$('#iw_content').css('visibility', 'hidden');
					
					adjustInfoWindowSize();
					
					var closeIwListener = GEvent.addListener(map.getInfoWindow(), 'closeclick', function(){
						cleanUpInfoWindowOnClose(closeIwListener); //prevent memory leak
					});
					
					setTimeout("presentInfo()", 100); //delay might help with overflowing content?
					
				}
			});
		}
	});
};

var presentInfo = function(){
	map.updateInfoWindow(); //disables buttons if it comes before their event binding (???)
	$('#iw_content').css('visibility', 'visible');
	
};

var getInfoWindowSize = function(){
	var dimensions = {
			height: $('#content').height() - 150,
			width: $('#content').width() / 2
	};
	return dimensions;
};

var adjustInfoWindowSize = function(){
	if($('#info_window_main').outerHeight(true) < $('#iw_content').height()){
		$('#iw_content').height($('#info_window_main').outerHeight(true)).width($('#info_window_main').outerWidth(true));
	}
};

//this function prevents memory leaks 
//and allows the map to return to position it was in before opening the infoWindow.
//
var cleanUpInfoWindowOnClose = function(closeIwListener){
	//alert('test: ' + oldCenter.equals(newCenter)); //shows that this is not a good test.  getMapOverlays is being called too much and it is overwriting the test values.
	$('#map #iw_content').remove();
	resetOverlays(); //why do this?
	var moveendListener = GEvent.addListener(map, "moveend", function(){
		var sameZoom = map.getZoom();
		getMapOverlays(1, sameZoom, sameZoom);
		GEvent.removeListener(moveendListener);
	});
	map.returnToSavedPosition();
	GEvent.removeListener(closeIwListener); //prevent memory leak
	if (map.getBounds().containsBounds(savedBounds)){ //if the map has not moved
		var sameZoom = map.getZoom();
		getMapOverlays(1, sameZoom, sameZoom);
	}
	
};

/***
 * getMapOverlays(zoom_check)
 * purpose:
 * 	to perform an ajax call and
 * 	retrieve a multidimensional array of data
 * 	for all required overlays on the map.
 * arguments: 
 * 	zoom_check:	1 = true; 0 = false.  
 * 				this tells the server whether to check 
 * 				map data against zoom level.
 * returns:	null
 */
var getMapOverlays = function(zoom_check, old_zoom, new_zoom){
	
	//alert('getMapOverlays called');
	
	//ajax call to retrieve map data
	$.ajax({
		url: "/map_data",
		type: "POST",
		data: {	max_lat: map.getBounds().getNorthEast().lat(),
				max_lng: map.getBounds().getNorthEast().lng(), 
				min_lat: map.getBounds().getSouthWest().lat(),
				min_lng: map.getBounds().getSouthWest().lng(),
				zoom_level: map.getZoom(), //0 = fully out; 19 = fully in
				zoom_check: zoom_check
			  },
		dataType: "json", //($.browser.msie) ? "text" :
		error: function(){
			$('#message').text('ajax error');
		},
		success: function(data){
			
			//This is a work-around due to Engine Hosting's lack of support for JSON
			//Delete this line when they get their act together.
			eval('data = ' + data);
			
			$('#message').text('ajax success / areas: '+data.areas.length+' / markers: '+data.markers.length);
			
			/* clear the overlay tracking arrays and
			 * clear the map overlays (markers, polygons, etc.) 
			 * if the map has moved -- and -- 
			 *    the zoom has changed  
			 *    -- or --
			 *    the number of areas drawn exceeds 100.
			 *
			 * purpose: restrict the amount of data being saved in memory and rendered on map.
			 */
			if (!map.getBounds().containsBounds(savedBounds) && ((new_zoom != old_zoom) || (polygonsDrawn.length > 100))){
				resetOverlays();
			}
			
			//create polygons, labels
			createOverlays(data);	
		}
	});				
};

//});