//global instance of the map
var map;
//global instance of the markers layer
var markers; 
//global instance of the vector layer used for displaying the routes
var routingLayer;
//Hash variable for associating building names with coordinates
var buildingHash;
//An array that maps a select tag's selectedIndex poperty to a building name
var selectHash;
//Start and stop points
var startIcon, stopIcon;
var iconToggle = true;
var startPos, stopPos;
var startMark, stopMark;
var click_lon, click_lat;

//getBuildingInfo marker stuff
var currentBldgPopup = null;
var pointStyle;
var buildingLayer;

//Current selectedFeature
var selectedFeature;
// Feature modifications Control
var modifyFeatureControl;
// Select Feature Control
var selectFeatureControl;
//Popup menu
var popupMenu, popupToggle;

// Set default routing style (required to function properly in IE)
var routingStyle = {
	strokeWidth: 6,
	strokeColor: "#ff0000",
	strokeOpacity: 0.8
};
OpenLayers.Util.applyDefaults(routingStyle, OpenLayers.Feature.Vector.style['default']);

// Set the color of the exclusion area
var style_blueblue, style_redred;
	
// Set the style for the building layer area
var bldgLayerStyle, selectBldgFeatureControl, selectedBldgFeature;
var bldgMarkerLayer, bldgMarkersArray;

// Set icons: start and stop
var size = new OpenLayers.Size(50,30);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var startIcon = new OpenLayers.Icon('./images/startIcon.png',size,offset);
var stopIcon = new OpenLayers.Icon('./images/stopIcon.png',size,offset);

var size2 = new OpenLayers.Size(26,26);
var offset2 = new OpenLayers.Pixel(-(size2.w/2), -size2.h);
buildingIcon = new OpenLayers.Icon('./images/star.png', size2);

eventIcon = new OpenLayers.Icon('./images/star.png', size2);

// Initialize popupHTML
var popupHTML =
"<table cellspacing=0 cellpadding=0 id=\"popupMenu\" style='color:blue;width:100px;font-size:0.8em;'>"+
"<tbody>"+
"<tr><td class=\"menuItem\" onclick=\"setStart()\">Set Start</td><tr>"+
"<tr><td class=\"menuItem\" onclick=\"setStop()\">Set Stop</td><tr>"+
"<tr><td class=\"menuItem\" onclick=\"showErrorPopup()\">Report Error</td><tr>"+
"<tr><td class=\"menuItem\" onclick=\"avoidPoint(); computeIfReady();\">Avoid Point</td><tr>"+
//"<tr><td class=\"menuItem\" style=\"text-align:center\" onclick=\"destroy_Popup()\">Close Menu</div></td><tr>"+
"</tbody></table>";
var popupToggle = true;

/**
 *	@function lonLatToMercator
 *	Converts regular longitude/latitude coordinates into Mercator units
 *
 *	@param ll OpenLayers.LonLat object with geographic lon/lat
 *	@return OpenLayers.LonLat object with mercator lon/lat units.
 */
function lonLatToMercator(ll) {
  var lon = ll.lon * 20037508.34 / 180;
  var lat = Math.log (Math.tan ((90 + ll.lat) * Math.PI / 360)) / (Math.PI / 180);
  lat = lat * 20037508.34 / 180;
  
  return new OpenLayers.LonLat(lon, lat);
}

/**
 * 	@function initMap
 * 	Initializes the OpenLayers map, map listeners, and layers.
 *
 *	@uses this var map
 * 	@uses this var routingLayer
 * 	@uses this var routingStyle
 * 	@uses this var startMark
 * 	@uses this var stopMark
 * 	@uses this var markers
 * 	@uses this var style_redred
 * 	@uses this var style_blueblue
 * 	@uses this var avoidAreas
 * 	@uses this var selectFeatureControl
 * 	@uses this var modifyFeatureControl
 * 	@uses this var pointStyle
 * 	@uses this var buildingLayer
 */ 
function initMap() {
	//starting coordinates and zoom level
	var lon = -8565200;
	var lat =  4720100
	var zoom=  16;
	var extent = 9000;
	var left_x = lon - extent;
	var left_y = lat - extent;
	var right_x = lon + extent;
	var right_y = lat + extent;
	map = new OpenLayers.Map ("map", {
		maxExtent: new OpenLayers.Bounds(left_x, left_y, right_x, right_y),
		restrictedExtent: new OpenLayers.Bounds(left_x, left_y, right_x, right_y),
		controls: [],
		maxResolution: 150000,
		units:"meters",
		projection: "EPSG:4326",
		numZoomLevels: 18,
		minZoomLevel: 14,
		maxZoomLevel: 18
	});
  
	// add map controls
	var zoomBar = new OpenLayers.Control.PanZoomBar();
	zoomBar.zoomStopHeight = 8;
	map.addControl(zoomBar);
	map.addControl(new OpenLayers.Control.Navigation()); // mouse nav: dbl click, wheel
	map.addControl(new OpenLayers.Control.Attribution());
	//map.addControl(new OpenLayers.Control.MousePosition());
  
	var theMap = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
	map.addLayer(theMap);
  
	// init and add vector layer for routes
	routingLayer = new OpenLayers.Layer.Vector("Routing Layer", { style: routingStyle,
	minResolution: 0.05});

	// init and add markers layer
	startMark = null;
	stopMark = null;
	markers = new OpenLayers.Layer.Markers("Markers", {'minResolution': 0.0, 'maxResolution': 10000.0});

	//init and add vectory layer for avoid areas
	var avoidAreaStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
	avoidAreaStyle.fillOpacity = 0.4;
	avoidAreaStyle.graphicOpacity = 1;
		
	style_redred = OpenLayers.Util.extend({}, avoidAreaStyle);
	style_redred.strokeColor = "red";
	style_redred.fillColor = "red";
	style_redred.strokeWidth = 2;
	
	style_blueblue = OpenLayers.Util.extend({}, avoidAreaStyle);
	style_blueblue.strokeColor = "blue";
	style_blueblue.fillColor = "blue";
	style_blueblue.strokeWidth = 2;
	avoidAreaStyle.minResolution = 0.05;

	avoidAreas = new OpenLayers.Layer.Vector( "Avoid Areas Layer" , {style: avoidAreaStyle, 'minResolution': 0.05});
	avoidAreas.isBaseLayer = false;
  
	//Setup and enable feature (avoid areas) selection
	//On select it will generate a popup
	selectFeatureControl = new OpenLayers.Control.SelectFeature(avoidAreas, 
		{
			clickout: true, toggle: true,
			multiple: false, hover: false,
			toggleKey: "crtlKey",
			multipleKey: "shiftKey",
			onSelect: onSelectFeature, //Function called when avoid area selected
			onUnSelect: onUnSelectFeature //Function called when avoid area unselected
		});
	map.addControl(selectFeatureControl);
	selectFeatureControl.activate();

	//Setup modification of features (avoid areas) functionality
	modifyFeatureControl = new OpenLayers.Control.ModifyFeature(avoidAreas, {clickout:true, toggle: true});
	modifyFeatureControl.mode = OpenLayers.Control.ModifyFeature.RESIZE | OpenLayers.Control.ModifyFeature.DRAG;
	modifyFeatureControl.selectFeature = function (obj) {
			avoidAreas.drawFeature(obj, style_blueblue);
		}
	modifyFeatureControl.unselectFeature = function (obj) {
			selectFeatureControl.unselect(obj);
		}
	map.addControl(modifyFeatureControl);
  
	buildingLayer = new OpenLayers.Layer.Vector("Building Marker Layer", 
		{style:pointStyle, 'minResolution': 0.05});
	buildingLayer.isBaseLayer = false;
	bldgMarkerLayer = new OpenLayers.Layer.Markers("bldg marker layer", {'minResolution':0.05});
	bldgMarkersArray = new Array();

  map.addLayers([routingLayer, avoidAreas, bldgMarkerLayer, markers]);

  //API calls to create custom icons
  var size = new OpenLayers.Size(30, 32);
  var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
  startIcon = new OpenLayers.Icon('./images/start_clear.gif',size,offset);
  startIcon.setOpacity(0.6);
  stopIcon = new OpenLayers.Icon('./images/stop_clear.gif',size,offset);
  stopIcon.setOpacity(0.6);

  //Click thingy
  map.events.register("click", map, function(e) {
	  if (popupToggle) {
		  popupToggle = false;
		  var lonlat = map.getLonLatFromViewPortPx(e.xy);
		  click_lon = lonlat.lon;
		  click_lat = lonlat.lat;
		  popupMenu = new OpenLayers.Popup(
				  "popup menu",
				  new OpenLayers.LonLat(lonlat.lon, lonlat.lat),
				  null,
				  popupHTML, false, destroy_Popup);
		  popupMenu.setBorder("1px solid black");
		  popupMenu.setOpacity(0.8);
		  popupMenu.autoSize = true;
		  popupMenu.events.register("onblur", popupMenu, destroy_Popup);
		  //popupMenu.onmouseout = destroy_Popup;
		  map.addPopup(popupMenu);
	  } else {
		  destroy_Popup();
	  }
});
map.events.register("movestart", map, function() {
	destroy_Popup();
	destroy_ErrorPopup();
});

  //Center on UMD Campus
  var lonLat = new OpenLayers.LonLat(lon, lat);
  map.setCenter (lonLat, zoom);
  
  setMessage("Map Loaded.");
}



/**
 *	@function destroy_Popup
 *	Closes the popup and removes item from memory.
 *
 *	@param evt object that triggered this event
 * 
 *	@uses this var popupMenu
 *	@uses this var popupToggle
 *	@uses this var map
 */
function destroy_Popup(evt) {
	if (popupMenu != null) {
		popupToggle = true;
		map.removePopup(popupMenu);
	}
}

/**
 *	@function clearMapStartStop
 *	Clears the start and stop markers, and the route from the map
 *
 *	@uses this function removeStartMark
 *	@uses this function removeStopMark
 *	@uses this var routingLayer
 *	@uses this var avoidAreas
 *	@uses this function avoidPopupCloseOnly
 *	@uses this function destroy_Popup
 */
function clearMapStartStop() {
	removeStartMark();
	removeStopMark();
	routingLayer.destroyFeatures(routingLayer.features);
	avoidAreas.destroyFeatures();
	avoidPopupCloseOnly();
	destroy_Popup();
}

/** 
 *	@function setMessage
 *	Sets a message on the msgBox in the menu
 *	
 *	@uses index.html DOMID msgBox
 */
function setMessage(msg) {
  var msgDiv = document.getElementById("msgBox");
  msgDiv.innerHTML = msg;
}

/**
 *	@function removeStartMark
 *	Removes the start mark from the markers layer.
 *
 *	@uses this var startPos
 * 	@uses this var startMark
 *	@uses this var markers
 */
function removeStartMark() {
	startPos = null;
	if (startMark != null) markers.removeMarker(startMark);
	startMark = null;
}

/**
 *	@function removeStopMark
 *	Removes the stop mark from the markers layer.
 *
 *	@uses this var stopPos
 *	@uses this var stopMark
 *	@uses this var markers
 */
function removeStopMark() {
	stopPos = null;
	if (stopMark != null) markers.removeMarker(stopMark);
	stopMark = null;
}

/**
 *	@function setStart
 *	Adds the start mark to the markers layer.
 *	Sets the start field textfield to "Custom location".
 *	
 *	@uses this var startMark
 *	@uses this var startPos
 *	@uses this var markers
 *	@uses index.html DOMID routingStartTextField
 *	@uses index.html function clearError
 *	@uses this function destroy_Popup
 */
function setStart() {
	if (startMark != null) markers.removeMarker(startMark);
	startMark  = new OpenLayers.Marker(new OpenLayers.LonLat(click_lon, click_lat), startIcon.clone());
	markers.addMarker(startMark);
	startPos = new OpenLayers.LonLat(click_lon, click_lat);
	document.getElementById("routingStartTextField").value = "Custom location"
	clearError("routingStartTextField");
	destroy_Popup();
	if (stopPos != null) setTimeout('compute()', 100);
}

/**
 *	@function setStop
 *	Adds the stop mark to the markers layer.
 *	Sets the stop field textfield to "Custom location".
 *	
 *	@uses this var stopMark
 *	@uses this var stopPos
 *	@uses this var markers
 *	@uses index.html DOMID routingStopTextField
 *	@uses index.html function clearError
 *	@uses this function destroy_Popup
 *	@uses this function compute
 */
function setStop() {
	if (stopMark != null) markers.removeMarker(stopMark);
	stopMark  = new OpenLayers.Marker(new OpenLayers.LonLat(click_lon, click_lat), stopIcon.clone());
	markers.addMarker(stopMark);
	stopPos = new OpenLayers.LonLat(click_lon, click_lat);
	document.getElementById("routingStopTextField").value = "Custom location"
	clearError("routingStopTextField");
	destroy_Popup();
	if (startPos != null) setTimeout('compute()', 100);
}

/**
 *	@function compute
 *	Calling compute does the following:
 *	  1. Clears all selected avoid area features - needed so that they will be
 *	     included in the exclusion area
 *	  2. Calls function getCheckedFilters to retrieve filters that have been
 *	     checked.
 *	  3. Calls function getExclusionAreas to retrieve exclusion areas that have
 *	     been declared.
 *	  4. Declare the proper type of object for start and stop, based on wether
 *	     a location was identified or a custom location
 *
 *	@uses this var selectFeatureControl
 *	@uses this var modifyFeatureControl
 *	@uses this function avoidPopupCloseOnly
 *	@uses this var startPos
 *	@uses this var stopPos
 *	@uses ui.js function getCheckedFilters
 *	@uses this function getExclusionAreas
 *	@uses index.html DOMID routingStartTextField
 *	@uses index.html DOMID routingStopTextField
 *	@uses this function setMessage
 *	@uses this var routingLayer
 *	@uses uiservices_api.js function ajax
 */
function compute() {
  //Unselect all feature controls so all will have properties
  selectFeatureControl.unselectAll();
  modifyFeatureControl.selectControl.unselectAll();
  avoidPopupCloseOnly();
  //setMessage("here");  // <<-- debugging
	var filters = getCheckedFilters();
	var avoidAreas = getExclusionAreas();
	if (startPos && stopPos) {
		var startValue = document.getElementById("routingStartTextField").value;
		var stopValue = document.getElementById("routingStopTextField").value;
		var param = {
			waypoint: [],
			filters: filters,
			exclusion_areas: avoidAreas
		}
		// set start point
		var startObj;
		if (startValue == "Custom location") {
			startObj = {
				type: "coordinates",
				x: startPos.lon,
				y: startPos.lat
			}
		} else {
			startObj = {
				type: "location",
				input: startValue
			}
		}
		var len = param.waypoint.length;
		param.waypoint[len] = startObj;
		// set stop point
		var stopObj;
		if (stopValue == "Custom location") {
			stopObj = {
				type: "coordinates",
				x: stopPos.lon,
				y: stopPos.lat
			}
		} else {
			stopObj = {
				type: "location",
				input: stopValue
			}
		}
		var len = param.waypoint.length;
		param.waypoint[len] = stopObj;

		var paramString = JSON.stringify(param)
		//setMessage(paramString);   //<<--- for debuggin
		setMessage("Loading route....");
		//setDebug1(paramString);
		//setDebug2("Loading...");
		routingLayer.destroyFeatures(routingLayer.features);
		ajax("getRoute2", paramString, displayRoute);
	} else {
		alert("Please set your start/stop points.");	
	}
}

function computeIfReady() {
	if (startPos && stopPos) compute();
}

function mercatorToLatLon(ll) {
	lon = ll.lon;
	lat = ll.lat;
	lat = lat * (180 / 20037508.34);
	lon = lon * (180 / 20037508.34);
	lat = ((360/Math.PI) * Math.atan(Math.pow(Math.E,(lat * (Math.PI/180))))) - 90;
	return new OpenLayers.LonLat(lon,lat);
}

// Used by latlonDistance
function toRad(degrees) {
   	var rad = (degrees * Math.PI) / 180;
	return rad;
}

function latlonDistance(lon1, lat1, lon2, lat2){
	var R = 6378137; // radius of earth in meters (estimate using equatorial radius)
	var dLat = toRad(lat2-lat1);
	var dLon = toRad(lon2-lon1); 
	var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
		Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * 
		Math.sin(dLon/2) * Math.sin(dLon/2); 
	var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
	var d = R * c;
	return d;
}

function calculateDistance(data) {
	var y1 = data[0][0];
	var x1 = data[0][1];
	var distance = 0.0;
	for(var i = 1; i < data.length; i++){
		var y2 = data[i][0];
		var x2 = data[i][1];
		var s = new OpenLayers.LonLat(y1, x1);
		var e = new OpenLayers.LonLat(y2, x2);
		s = mercatorToLatLon(s);
		e = mercatorToLatLon(e);
		distance += latlonDistance(s.lon,s.lat,e.lon,e.lat);
		x1 = x2;
		y1 = y2;
	}
	return Math.round(distance);
}


function displayRoute() {
	if (xmlHttp.readyState == 4 && xmlHttp.responseText.length > 0) {
		//setDebug2(xmlHttp.responseText);  // <<---- for debuggin
		try {
			var obj = eval('('+xmlHttp.responseText+')');
			if (obj.error != null) {
				setErrorMsg(obj.error);
			} else {
				routingLayer.destroyFeatures(routingLayer.features);
				var route = new OpenLayers.Format.GeoJSON();
				routingLayer.addFeatures(route.read(xmlHttp.responseText), {Boolean: "isVector"});
				setMessage("Route Loaded (" + Math.round(calculateDistance(obj.geometry.coordinates) * 1.09361329833771) + " yards)");
			}
		} catch (e) {
			alert(xmlHttp.responseText);
			setErrorMsg("Error: "+e.description);
		}
	}
}

/**
 *	@function specifyAvoidPoint
 *	Calling specifyAvoidPoint does the following:
 *	  Adds a avoid area to a specific point and uses a given range
 *
 */
function specifyAvoidPoint(x, y, range){
    var point = new OpenLayers.LonLat(x, y);
	var left = point.lon - range;
	var bottom = point.lat - range;
	var right = point.lon + range;
	var top = point.lat + range;
	
	var bounds = new OpenLayers.Bounds(left, bottom, right, top);
	var box = new OpenLayers.Feature.Vector(bounds.toGeometry(), null, style_redred);
	
	avoidAreas.addFeatures(box); //add box to the avoidAreas vector layer	
}

/* Function to create an avoid area box on the map */
function avoidPoint(){
	var point = new OpenLayers.LonLat(click_lon, click_lat);
	var zoom = map.getZoom();
	var range;
	//Box size depends on zoom level
	if(zoom == 18){
	  range = 5;
	}
	else if(zoom == 17){
	  range = 9;
	}
	else if(zoom == 16){
	  range = 26;
	}
	else if(zoom == 15){
	  range = 38;
	}
	else{
	  range = 100;
	}
	
	specifyAvoidPoint(click_lon, click_lat, range);

	destroy_Popup();
}

/* Function to get all the present avoid area boxes on the map
 * Returns an array of JSON objects that identifies the center coordinates of the 
 * box and the length of a side of the box
 */
function getExclusionAreas(){
  var exclusionAreas = new Array();
  var features = avoidAreas.features;
  var i;
  for(i=0; i<features.length; i++){
    var range = features[i].geometry.getLength()/2;
    var lonlat = features[i].geometry.getBounds().getCenterLonLat();
    exclusionAreas[exclusionAreas.length] = {x: lonlat.lon, y: lonlat.lat, range: range}
  }
  return exclusionAreas;
}
var avoidPopup = null;
var avoidPopupHTML = 
"<div><table cellpadding=0 id='avoidAreaPoupTbl' "+ 
"style='color:blue;width:120px;font-size:0.8em;'><tbody>"+
"<tr><td style='text-align:left;' onclick='avoidAreaModify()'>Modify Area</td></tr>"+
"<tr><td style='text-align:left;' onclick='avoidAreaDelete()'>Delete Area</td></tr>"+
"</tbody></table></div>";

/* Function called when a feature is selected on the map generates a popup menu
 * that allow you to choose to modify or delete an avoid area
 */
function onSelectFeature(feature){
  avoidPopupCloseOnly();  // close any other instantiation of the avoidPopup
	selectedFeature = feature;
	avoidPopup = new OpenLayers.Popup("building", 
			feature.geometry.getBounds().getCenterLonLat(), null,
			avoidPopupHTML, true, avoidPopupClose);
	avoidPopup.autoSize = true;
	avoidPopup.setBackgroundColor("white");
	avoidPopup.setBorder("1px solid");
	feature.popup = avoidPopup;
	destroy_Popup();
	map.addPopup(avoidPopup);
	avoidAreas.drawFeature(feature, style_blueblue);
}

/* Function called when a feature is unselected. It removes the avoid area popup
 * if one exists and sets the global variable selectedFeature to null
 */
 
function onUnSelectFeature(feature) {
	map.removePopup(feature.popup);
	feature.popup.destroy();
	feature.popup = null;
	avoidAreas.drawFeature(feature, style_redred);
	selectedFeature = null;
}

/* Closes the avoid area popup and deselects the selected feature */
function avoidPopupClose(evt) {
	selectFeatureControl.unselect(selectedFeature);
	map.removePopup(avoidPopup);
	avoidPopup.destroy();
	avoidPopup = null;
}
/* Closes only the popup box and the feature remains selected */
function avoidPopupCloseOnly(evt) {
  if(avoidPopup == null){
    return;
  }
	map.removePopup(avoidPopup);
	avoidPopup.destroy();
	avoidPopup = null;
}

/* Sets the modification mode */
function avoidAreaModify(){
  if (selectedFeature == null) {
		return;
	}
  modifyFeatureControl.mode = OpenLayers.Control.ModifyFeature.RESIZE | OpenLayers.Control.ModifyFeature.DRAG;
  avoidPopupCloseOnly();
}

/* Deletes the selectedFeature */
function avoidAreaDelete() {
	if (selectedFeature == null) {
		return;
	}
	avoidAreas.destroyFeatures([selectedFeature]);
	selectedFeature == null;
	avoidPopupClose();
}

//*************Harolds additions

//Error Popup
var errorPopup, errorToggle;

//keep the callback from happening more than once
var gotResponse = false;

var errorPopupHTML =
"<table cellspacing=0 style=\"width:300px\">"+
"<tbody>"+
"<tr><td class=\"menuItem\">Please describe the problem in this area:</td><tr>"+
"<tr><td class=\"menuItem\"><textarea id=\"errorText\" rows=\"3\" columns=\"35\" wrap=\"virtual\" style=\"width: 300px\"></textarea></td><tr>"+
"<tr><td class=\"menuItem\" alight=right><button onClick=\"submitError()\">Submit Report</button><button onClick=\"destroy_ErrorPopup()\">Cancel</button></td><tr>"+
"</tbody></table>";

//Destroy's my popup
function destroy_ErrorPopup() {
  if (errorPopup != null) {
    map.removePopup(errorPopup);
  }
}

//Closes Colin's menu popup and opens mine
function showErrorPopup(){
	destroy_Popup();
	
	errorPopup = new OpenLayers.Popup.FramedCloud(
		  "error popup",
		  new OpenLayers.LonLat(click_lon, click_lat),
		  //new OpenLayers.Size(310, 130),
		  null,
		  errorPopupHTML, null, false);
	errorPopup.setBackgroundColor("red");
	errorPopup.setBorder("2px outset");
	errorPopup.setOpacity(0.99);
	errorPopup.autoSize = true;
	map.addPopup(errorPopup);
}

//Calls the AJAX API function
function errorCallAPI(errorText, cbFunction) {
	if (errorText.length > 0) {
		var point = new OpenLayers.LonLat(click_lon, click_lat);
		var locationStructure = {
			x: point.lon,
			y: point.lat,
			range: 1
		};
		var jsonObj = {
			description: errorText,
			location: locationStructure
		};
		var input = JSON.stringify(jsonObj);
		gotResponse = false;
		ajax("submitError", input, errorCallback);
		//alert(input);
	}
}

//Function called after clicking 'Submit Error' on the Error Popup
function submitError(){
	var text = document.getElementById("errorText").value;
	destroy_ErrorPopup();
	errorCallAPI(text);
}

//callback
function errorCallback(){
	if(!gotResponse){
		alert("Thank you for submitting the error.");
		gotResponse = true;
	}
}

//************ End Harold

//Begin get Building info
//Begin get Building info
function getBuildingHelper(field){
	
	var field = document.getElementById("bldgField");
	
	//alert(document.getElementById("bldgField").value);
	
	if (field.value.length > 0) {
		var jsonObj = {
			input: field.value
		};
		var input = JSON.stringify(jsonObj);
		gotResponse = false;
		//alert(input);
		ajax("getBuildingInfo", input, getBuildingCallback);
	}
	
}

function getEventHelper(field){
	var field = document.getElementById("eventField");
	if (field.value.length > 0) {
                var jsonObj = {
                        input: field.value
                };
                var input = JSON.stringify(jsonObj);
                gotResponse = false;
                //alert(input);
                ajax("getEventInfo", input, getEventCallback);
        }
}

function getBuildingCallback(){
	if(xmlHttp.readyState == 4 && xmlHttp.responseText.length > 0 ){
		var respJSON;
		
		try{
			respJSON = eval('('+xmlHttp.responseText+')');
		}catch (e){
			//alert("Could not eval json string"+xmlHttp.responseText + " " +e.description);
			setErrorMsg("Could not find specified building.");
			return false;
		}
		
		//Convert Coordinates
		if(respJSON.x == null || respJSON.y == null) { 
			setErrorMsg("Could not find specified building.");
			//alert("Null coordinates.");
		} else {
			var coords = lonLatToMercator(new OpenLayers.LonLat(placeDec(respJSON.x), placeDec(respJSON.y)));
			//Generate the HTML
			var bldgHtml = 
			"<div align='center'>"+
			respJSON.fullName+
			"<table cellspacing=0 style='font-size:0.8em;'>"+
			"<th style='width:50%'/><th style='width:50%'/>"+
			"<tbody>";
                         if(respJSON.buildingNum && !respJSON.buildingNum.substr(0,1).match(/[a-zA-Z]/)){
				bldgHtml += "<tr><td style='vertical-align:top' class=\"bldgTitle\">Building Nmbr: " + respJSON.buildingNum;
			}
			if(respJSON.shortName){
				bldgHtml += "<br />Building Code: " + respJSON.shortName.toUpperCase();
			}
			if(respJSON.url != ""){
				bldgHtml += "<br /> <a href='" + respJSON.url + "' target='_window'>More Information</a></td>";
			}else{
				bldgHtml += "</td>";
			}
			bldgHtml += "<td class=\"bldgImg\"><img width=150 height=112 src=\"" + respJSON.imgsrc + "\"></td></tr>"+
			"</tbody></table></div>";
			
			attributes = { name : respJSON.fullName, html : bldgHtml, lonlat : coords };
			
			var mark = new OpenLayers.Marker(new OpenLayers.LonLat(coords.lon, coords.lat), buildingIcon.clone());
			mark.attributes = attributes;
			mark.events.register("click", mark, bldgPopupOpen);
			
			bldgMarkerLayer.addMarker(mark);
			map.setCenter(coords);
			bldgPopupOpen(mark);
			setMessage("Building marked.");
		}
	}
}

function getEventCallback(){
        if(xmlHttp.readyState == 4 && xmlHttp.responseText.length > 0 ){
                var respJSON;

                try{
                        respJSON = eval('('+xmlHttp.responseText+')');
                }catch (e){
                        //alert("Could not eval json string"+xmlHttp.responseText + " " +e.description);
                        setErrorMsg("Could not find specified building.");
                        return false;
                }

                //Convert Coordinates
                if(respJSON.x == null || respJSON.y == null) {
                        setErrorMsg("Could not find specified building.");
                        //alert("Null coordinates.");
                } else {
                        var coords = lonLatToMercator(new OpenLayers.LonLat(placeDec(respJSON.x), placeDec(respJSON.y)));
                        //Generate the HTML
                        var eventHtml =
                        "<div align='center'>"+
                        respJSON.eventName+"<br />"+respJSON.locationName+
			"<br />";
			if(respJSON.time){
				eventHtml += "Time: "+respJSON.time+"<br />";
			}
			if(respJSON.description){
				eventHtml += "<p>"+respJSON.description+"</p>";
			}
			if(respJSON.url){
				eventHtml += "<a href='"+respJSON.url+"' target='_window'>More Information</a><br />";
			}
			eventHtml += "</div>";

                        attributes = { name : respJSON.name, html : eventHtml, lonlat : coords };

                        var mark = new OpenLayers.Marker(new OpenLayers.LonLat(coords.lon, coords.lat), eventIcon.clone());
                        mark.attributes = attributes;
			// HACK ... uses building code on purpose
                        mark.events.register("click", mark, bldgPopupOpen);

                        bldgMarkerLayer.addMarker(mark);
                        map.setCenter(coords);
                        bldgPopupOpen(mark);
                        setMessage("Event marked.");
                }
        }
}


function bldgPopupOpen(evt) {
	var lonlat = this.attributes.lonlat;
	popup = new OpenLayers.Popup.FramedCloud("building", lonlat, null, this.attributes.html,
		null, true, bldgPopupClose);
	popup.autoSize = true;
	popup.setBorder("1px solid");
	this.popup = popup;
	map.addPopup(popup);
}
function onSelectBldgFeature(feature) {
	selectedBldgFeature = feature;
	var lonlat = new OpenLayers.LonLat(feature.geometry.x, feature.geometry.y);
	popup = new OpenLayers.Popup.FramedCloud("building", lonlat, null, feature.attributes.html,
		null, true, bldgPopupClose);
	//popup = new OpenLayers.Popup("building", lonlat, null, feature.attributes.html, true, bldgPopupClose);
	popup.autoSize = true;
	feature.popup = popup;
	map.addPopup(popup);
}
function bldgPopupClose(evt) {
	var pop = buildingLayer.getFeatureFromEvent(evt);
	//map.removePopup(selectedBldgFeature.popup);
	//selectedBldgFeature.popup.destroy();
	//selectedBldgFeature.popup = null;
	map.removePopup(this);
	this.destroy();
}
	
function clearBldgLayer() {
	buildingLayer.destroyFeatures();
	bldgMarkerLayer.clearMarkers();
	var popupList = map.popups;
	for (index in popupList) { 
		map.removePopup(popupList[index]);
		popupList[index].destroy();
	}
}
function placeDec(num) {

	var s = num + ''; //convert to string
	var l = s.length;

	if(s.charAt(0) == '-'){
		var f = parseFloat(s.substring(0,3) + "." + s.substring(3,l));
	}
	else{
		var f = parseFloat(s.substring(0,2) + "." + s.substring(2,l));
	}
	return f;
}

function createBuildingPopup(feature){
	currentBldgPopup = new OpenLayers.Popup(feature.attributes.fullName, feature.attributes.lonlat, new OpenLayers.Size(155, 135), feature.attributes.html, true, closeBuildingPopup);
	currentBldgPopup.setBorder("2px outset");
	currentBldgPopup.setOpacity(0.99);
	currentBldgPopup.maxSize = new OpenLayers.Size(155, 135);
	//currentBldgPopup.panMapIfOutOfView = true;	
	map.addPopup(currentBldgPopup);			
}

function buildingPopup(feature){
	//alert(feature.attributes.name);
	//alert(feature.attributes.coords);
	if(currentBldgPopup == null){
		createBuildingPopup(feature);	
	}
	else {
		map.removePopup(currentBldgPopup);
		createBuildingPopup(feature);
	}
}

function closeBuildingPopup(){
	map.removePopup(currentBldgPopup);
	currentBldgPopup = null;
}

/**
 *	@function addAvoidArea
 *	Adds an area to the avoidAreas layer.
 *	
 *	@param x x coordinate
 *	@param y y coordinate
 *	@param range the range of the box
 *	@uses this var avoidAreas
 */
function addAvoidArea(x, y, range) {
	range = range/4;
	var box = new OpenLayers.Bounds(x-range, y-range, x+range, y+range, null, style_redred);
	avoidAreas.addFeatures(box);
}
