

	
var area_displayed_categories = {};
var area_subcategories = {};

var areaLat = null;
var areaLng = null;
var areaZoom = null;


var chosenAreaLat = null;
var chosenAreaLng = null;
var chosenAreaZoom = null;
var areaShapeIds = null;

function getAreaInfo() {

	if (areaLat == null || areaLat != map.getCenter().lat() ||
			areaLng == null || areaLng != map.getCenter().lng() ||
			areaZoom == null || areaZoom != map.getZoom()) {
		areaLat = map.getCenter().lat();
		areaLng = map.getCenter().lng();
		areaZoom = map.getZoom();
	} else {
		return; // nothing to do ; what they see is current
	}

	//if ((typeof(window.allTypeNum)!='undefined') && window.allTypeNum == 0) { //alert('allTypeNum = '+allTypeNum); }

	var filterDiv = document.getElementById('area_subcatsCol1');
	filterDiv.innerHTML = "Loading...";

	area_displayed = {};
	area_subcategories = {};

	var callback =
	{
		success: getAreaInfoSuccess,
		failure: getAreaInfoFailure,
		argument: []
	}
		
	var d = new Date();
	var transaction = YAHOO.util.Connect.asyncRequest('GET',
					htmlbase +
					(window.location.pathname.substring(htmlbase.length).match(/^[^/?]*/)[0])+'/getAreaInfo?'
						//+'noCache='+(Math.random()+''+(new Date()).getTime()) // dont ever cache results
						+'cache='+(d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate()) // let it be cached for one full day
						+'&lat='+areaLat+'&lng='+areaLng+'&zoom='+areaZoom+"&json=1",
					callback);
}

var getAreaInfoFailure = function(o){
	//document.getElementById('loadingDiv').style.display='none';
	var filterDiv = document.getElementById('area_subcatsCol1');
	filterDiv.innerHTML = "An error has occured. The filter could not load.";
	//window.setMessage( window.serverAddr, "ERROR");
}

var availAreaFilter = null;
var getAreaInfoSuccess = function (o){

	// updates shapeToShapefileMap, smallShapeInfo, shapefile_id_names
//try {
	//alert(o.responseText);
	availAreaFilter = eval("("+o.responseText+")");
	availAreaFilter = availAreaFilter.Shapefile;
	area_displayed_categories = {};
	area_subcategories = {};

	var ihtml = [];
	if (availAreaFilter) {
		ihtml.push("<div class='areaFilterSectionHeading'>Apply New Filter: </div>");
		for (var i = 0; ; i++) {
			if (typeof(availAreaFilter[i])=='undefined') {
				break;
			}
			var shpf = availAreaFilter[i];
			var shpf_id = shpf['@attrs']['shapefileid'];
			var shpf_title = shpf['@attrs']['title'];
			shapefile_id_names[shpf_id] = shpf_title;
			var onclick = ' onclick="toggleOneMainCategory('+shpf_id+', \'area_\');" ';
			ihtml.push("<div class='crimeGroup'>");
			ihtml.push("	<div class='crimeTypeMain' id='area_category_main_"+shpf_id+"' "+onclick+" >");
			ihtml.push("		"+shpf_title);
			ihtml.push("	</div><!-- end class=crimeTypeMain -->");
			area_displayed_categories[shpf_id] = {};
			area_subcategories[shpf_id] = {};
			var shps = shpf['Shape'];
			for (var k = 0; ; k++) {
				if (typeof(shps[k]) == 'undefined')
					break;
				var shp = shps[k];
				var shp_id = shp['@attrs']['shapeid'];
				var shp_title = shp['#text'];
				if (typeof(smallShapeInfo[shp_id])!='object')
					smallShapeInfo[shp_id] = {};
				smallShapeInfo[shp_id].name = shp_title;
				smallShapeInfo[shp_id].centroid = shp['@attrs']['centroid'];
				shapeToShapefileMap[shp_id] = shpf_id;
				onclick = ' onclick="toggleOneSubCategory('+shpf_id+','+shp_id+', \'area_\');" ';
				ihtml.push("	<div class='crimeTypeSub' id='area_category_sub_"+shpf_id+"_"+shp_id+"' "+onclick+" >");
				ihtml.push("		"+shp_title);
				ihtml.push("	</div>");
				area_subcategories[shpf_id][shp_id] = shp['#text'];
			}
			ihtml.push("</div><!-- end class=crimeGroup -->");
		}
	}
	if (ihtml.length == 0) {
		ihtml.push("No Areas were found near the map center.");
	}
	var filterDiv = document.getElementById('area_subcatsCol1');
	filterDiv.innerHTML = ihtml.join("\n");
//} catch (e) {alert('erro:'+e.message + " " + e.name);}
}


function placeNamesOfCurrentAreaIds() {
	var ihtml = [];
	var ids = areaShapeIds;
	if (typeof(ids)=='string') {
		ids = areaShapeIds.split(',');
	}
	if (ids && ids.length > 0 && areaShapeIds!='') {
		ihtml.push("<div class='areaFilterSectionHeading'>Current Filter: </div>");
		ihtml.push("<div class='crimeGroupNoAction' >");
		var shapefileid = null;
		var someFilters = false;
		for (var i in ids) {
			if (!String(ids[i]).match(/^\d+$/))
				continue;
			if (shapefileid == null) { // we assume for now that they can only select one shapefile. this will have to change if/when we allow them to select more than one shapefile
				shapefileid = shapeToShapefileMap[ids[i]];
				ihtml.push("<div class='crimeTypeMainNoAction'>"+shapefile_id_names[shapefileid]+"</div>");
			}
			ihtml.push("<div class='crimeTypeSubNoAction' style='padding-left:10px;'>"+smallShapeInfo[ids[i]].name+"</div>");
			someFilters = true;
		}
		if (!someFilters) {
			ihtml.push("<div class='crimeTypeMainNoAction'>[None]</div>");
		}
		ihtml.push("</div>");
	}
	
	var div = document.getElementById('areaFilterCurrent');
	if (div != null)
	{
		div.innerHTML = ihtml.join("\n");
	}
}


function getSelectedAreaIds() {
	var ids = [];
	for (var i in area_displayed_categories) {
		for (var j in area_displayed_categories[i]) {
			if (area_displayed_categories[i][j]) {
				ids.push(j);
			}
		}
	}
	return ids.join(',');
}



var areaFilterStateOpen = 0;
function setupAreaPanTrigger() {
	GEvent.addListener(map, "dragstart", function() {
			if (areaFilterStateOpen) {
				o = toggleTypes('area');
				if (o=='on')
					toggleTypes('area');
				areaFilterStateOpen = 0;
			}
		});
	GEvent.addListener(map, "dragend", function() {
			if (areaFilterStateOpen) {
				getAreaInfo();
			}
		});
}


	var curSelected = null;

	function loadAreaFilterTiles() {
		var lat = parseFloat(chosenAreaLat);
		var lng = parseFloat(chosenAreaLng);

		var zoom = map.getZoom();
		if (chosenAreaZoom != null)
			zoom = parseInt(chosenAreaZoom);
		map.setCenter(new GLatLng(lat, lng), zoom);
		window.chosenShapefileId = shapeToShapefileMap[areaShapeIds.split(',')[0]];
		
		initAFTileOverlay(map);
	}


	function loadShapefilePreview(index) {
		var lat = parseFloat(shpinfo[index].centerlat);
		var lng = parseFloat(shpinfo[index].centerlng);
		var zoom = parseInt(shpinfo[index].zoom);

		if (curSelected!==null) {
			var old = document.getElementById('shpfile_index_'+curSelected);
			old.className = old.className.replace(/\s*shapefileSelected\s*/,'');
		}
		var ele = document.getElementById('shpfile_index_'+index);
		if (!ele.className.match(/shapefileSelected/)) {
			ele.className = ele.className + ' shapefileSelected';
		}
		curSelected = index;

		map.setCenter(new GLatLng(lat, lng), zoom+1);
		
		
		initTileOverlay(map, index);
	}

	var defaultShapefileIndex = null;
	function createMGMap(){
		if (GBrowserIsCompatible() ) { 
			
			map = new GMap2(document.getElementById("map"));
					
			map.setCenter(new GLatLng(38.89,-77.037),4);
			map.setMapType(G_SATELLITE_MAP); // G_HYBRID_MAP or G_NORMAL_MAP
			map.addControl(new GLargeMapControl());
			map.addControl(new GMapTypeControl());

				//map.setCenter(new GLatLng(shpinfo[k].centerlat*1, shpinfo[k].centerlng*1), shpinfo[k].zoom*1);

			if (typeof(defaultShapefileIndex)=='string') {
				defaultShapefileIndex = parseInt(defaultShapefileIndex);
			}
			if (defaultShapefileIndex === null && typeof(shpinfo)==='object') {
				defaultShapefileIndex = 0;
				for (var i = 0; i < shpinfo.length; i++) { 
					if (shpinfo[i].is_default) {
						defaultShapefileIndex = 0;
					}
				}
			}
		
			if (chosenAreaLat && chosenAreaLng) {
				loadAreaFilterTiles();
			} else if (typeof(defaultShapefileIndex)=='number' && !isNaN(defaultShapefileIndex)) {
				loadShapefilePreview(defaultShapefileIndex);
			} else {
				i = defaultShapefileIndex;
				map.setCenter(new GLatLng(parseFloat(shpinfo[i].centerlat),
						parseFloat(shpinfo[i].centerlng)),
						parseInt(shpinfo[i].zoom));
			}
			if (typeof(doSetupAreaPanTrigger) != 'undefined' && doSetupAreaPanTrigger) {
				setupAreaPanTrigger();
			}
		}
	}

	function initTileOverlay(map, index) {
		if (map.tileLayer)
			map.removeOverlay(map.tileLayer);
		var tilelayer = new GTileLayer(new GCopyrightCollection(''), 5, 14);
		tilelayer.getTileUrl = function(tile, zoom) {
			var url =  "http"+PE_Shapefile_BASE_URL+"bin/renderCRpreview.php?api_key="+PE_Shapefile_API_KEY
					+"&type="+shpinfo[index].shape_type.toUpperCase()
					+"&f="+shpinfo[index].ga_file_name
					+"&z="+zoom
					+"&label_field="+shpinfo[index].chosen_field_number
					+"&ul_x="+shpinfo[index].br_ul_long
					+"&ul_y="+shpinfo[index].br_ul_lat
					+"&lr_x="+shpinfo[index].br_lr_long
					+"&lr_y="+shpinfo[index].br_lr_lat
					+"&x="+tile.x
					+"&y="+tile.y
					+"&m=0"
					+"&h=3"
					+"&w=geoamp"
					+"&border_alpha=220"
					+"&splash_meters=0"
					+"&all_borders=1"
					+"&border_width=2"
					+"&show_labels=1"
					;
			//alert(url);
			return url;
		}   
		tilelayer.isPng = function() {return true;}
		tilelayer.getOpacity = function() {return 1;}
		map.tileLayer = new GTileLayerOverlay(tilelayer);
		map.addOverlay(map.tileLayer);
	}

	function initAFTileOverlay(map) {
		if (map.tileLayer)
			map.removeOverlay(map.tileLayer);
		var tilelayer = new GTileLayer(new GCopyrightCollection(''), 5, 14);
		tilelayer.getTileUrl = function(tile, zoom) {
			//GLog.write(areaShapeIds);
			if(areaShapeIds.length)
				return "http://tiles.geoamp.com/z/serveTiles?"+PE_Shapefile_API_KEY+"+"+PE_Shapefile_LAYER_NAME+"[SRC_FILEID="+window.chosenShapefileId+"]["+areaShapeIds+"]&0&+"+tile.x+"+"+tile.y+"+"+zoom;
			else
				return "http://tiles.geoamp.com/z/serveTiles?"+PE_Shapefile_API_KEY+"+"+PE_Shapefile_LAYER_NAME+"[SRC_FILEID="+window.chosenShapefileId+"]&0&+"+tile.x+"+"+tile.y+"+"+zoom;
		}   
		tilelayer.isPng = function() {return true;}
		tilelayer.getOpacity = function() {return 1;}
		map.tileLayer = new GTileLayerOverlay(tilelayer);
		map.addOverlay(map.tileLayer);
	}


	function setMapCenterForAreaIds() {
		var ids = areaShapeIds;
		if (typeof(ids)=='string') {
			ids = areaShapeIds.split(',');
		}
    var minLat = 90;
    var maxLat = -90;
    var minLng = 180;
    var maxLng = -180;
		var inIt = false;

		if (ids && ids.length > 0 && areaShapeIds!='') {
			for (var i in ids) {
				if (!String(ids[i]).match(/^\d+$/))
					continue;
				
				inIt = true;
				var centroid = smallShapeInfo[ids[i]].centroid;
				var centroidArr = centroid.split(',');
				if (centroidArr && centroidArr.length == 2 || centroidArr.length == 3) {
					var lat = centroidArr[0];
					var lng = centroidArr[1];
					var radius = centroidArr[2];
					
					var leftSide = getDestPoint(lat, lng, 180+90, radius);
					var rightSide = getDestPoint(lat, lng, 90, radius);
					var topSide = getDestPoint(lat, lng, 0, radius);
					var bottomSide = getDestPoint(lat, lng, 180, radius);
					//map.addOverlay(new GMarker(new GLatLng(bottomSide.lat(),leftSide.lng())));
					//map.addOverlay(new GMarker(new GLatLng(topSide.lat(), rightSide.lng())));
					//alert('addedone');
				
					minLat = Math.min(bottomSide.lat(), minLat);
					maxLat = Math.max(topSide.lat(), maxLat);
					minLng = Math.min(leftSide.lng(), minLng);
					maxLng = Math.max(rightSide.lng(), maxLng);
				}
			}
			//alert(minLat + ',' + minLng + ': :' + maxLat + ',' + maxLng);
			//map.addOverlay(new GMarker(new GLatLng(minLat, minLng)));
			//map.addOverlay(new GMarker(new GLatLng(maxLat, maxLng)));
			
			if (inIt) {
				centerLat = (maxLat - minLat)/2 + minLat;
				centerLng = (maxLng - minLng)/2 + minLng;
				newctr = new GLatLng(centerLat, centerLng);
				map.setCenter(newctr);
				//map.addOverlay(new GMarker(newctr));
			}
		}
	}

	Number.prototype.toRad = function() {  // convert degrees to radians
		return this * Math.PI / 180;
	}

	Number.prototype.toDeg = function() {  // convert radians to degrees (signed)
		return this * 180 / Math.PI;
	}

	Number.prototype.toBrng = function() {  // convert radians to degrees (as bearing: 0...360)
		return (this.toDeg()+360) % 360;
	}

	/*
	 * calculate destination point given start point, initial bearing (deg) and distance in mi
	 *   see http://www.movable-type.co.uk/scripts/latlong.html
	 */
	function getDestPoint(lat, lon, brng, d) {
		var R = 3963; // earth's mean radius in mi
		var lat1 = Number(lat).toRad(), lon1 = Number(lon).toRad();
		brng = Number(brng).toRad();

		var lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) + 
													Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng) );
		var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1), 
																 Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
		//lon2 = (lon2+Math.PI)%(2*Math.PI) - Math.PI;  // normalise to -180...+180 // instantiation of GLatLng takes care of this for us

		if (isNaN(lat2) || isNaN(lon2)) return null;
		return new GLatLng(lat2.toDeg(), lon2.toDeg());
	}



