/**
 * Object for creating quick Google Maps with EPP Locations on 'em
 *
 */
var locationsGoogleMap = function() 
{
	/**
	 * List of EPP Locations
	 *
	 * @access protected
	 * @var JSON
	 */
	this.locations = {
		apl: new locationsGoogleMap_Location({
			lat: 39.160356,
			lng: -76.895456,
			zoom: 15,
			name: "Applied Physics Laboratory",
			address: "11100 Johns Hopkins Road",
			city: "Laurel",
			state: "MD",
			zip: "20723",
			url: "apl"			
		}), //end APL
		
		crystalcity: new locationsGoogleMap_Location({
			lat: 38.851986,
			lng: -77.051593,
			zoom: 15,
			name: "Crystal Center Center",
			address: "2461 South Clark Street, Suite 1200",
			city: "Arlington",
			state: "VA",
			zip: "22202",
			url: "crystal-city"			
		}), //end crystal-city
		
		dorsey: new locationsGoogleMap_Location({
			lat: 39.184778,
			lng: -76.753929,
			zoom: 13,
			name: "Dorsey Student Services Center",
			address: "6810 Deerpath Road",
			city: "Elkridge",
			state: "MD",
			zip: "21075",
			url: "dorsey"			
		}), //end Dorsey
		
		homewood: new locationsGoogleMap_Location({
			lat: 39.329161,
			lng: -76.617765,
			zoom: 15,
			name: "Homewood Campus",
			address: "3400 N. Charles St.",
			city: "Baltimore",
			state: "MD",
			zip: "21218",
			url: "homewood"
		}),//end homewood
		
		mcc: new locationsGoogleMap_Location({
			lat: 39.105377,
			lng: -77.196517,
			zoom: 14,
			name: "Montgomery County Campus",
			address: "9601 Medical Center Drive",
			city: "Rockville",
			state: "MD",
			zip: "20850",
			url: "mcc"	
		}),//end mcc
		
		dccenter: new locationsGoogleMap_Location({
			lat: 38.907684,
			lng: -77.037805,
			zoom: 16,
			name: "Washington DC Center",
			address: "1625 Massachusetts Ave. N.W.",
			city: "Washington",
			state: "DC",
			zip: "20036",
			url: "dc-center"
			
		}),//end dc center
		
		smhec: new locationsGoogleMap_Location({
			lat: 38.311909,
			lng: -76.536603,
			zoom: 13,
			name: "Southern MD Higher Education Center",
			address: "44219 Airport Road",
			city: "California",
			state: "MD",
			zip: "20619",
			url: "smhec"			
		}),//end smhec
		
		heat: new locationsGoogleMap_Location({
			lat: 39.530333,
			lng: -76.196894,
			zoom: 13,
			name: "HEAT Center",
			address: "1201 Technology Drive",
			city: "Aberdeen",
			state: "MD",
			zip: "21001",
			url: "heat"
		})//end heat
	}//end locations
	
	/**
	 * The default latitude for the initial map position - this is for a 
	 * point halfway between Baltimore and DC
	 *
	 * @access protected
	 * @var float
	 */
	this.default_lat = 39.00;
	
	/**
	 * The default longitude for the initial map position - this is for a 
	 * point halfway between Baltimore and DC
	 *
	 * @access protected
	 * @var float
	 */
	this.default_lng = -76.67;
	
	/**
	 * The default zoom level for the map
	 *
	 * @access protected
	 * @var int
	 */
	this.default_zoom = 8;
	
	/**
	 * Holds the gmap, once createGMap has been called
	 *
	 * @access protected
	 * @var GMap2
	 */
	this.gmap = null;
	
	/**
	 * Creates the google map with the given dimensions and adds the necessary html to the 
	 * body of the page.  Stores the google map internally, but also returns a reference
	 *
	 * @access public
	 * @return GMap
	 */
	this.createGMap = function(width, height)
	{
		if ( this.gmap != null ) {
			return this.gmap;
			
		}
		
		if ( !GBrowserIsCompatible() ) {
			throw new Exception("The browser being used is not compatible with Google Maps.");
			
		}
		
		var elem_div = document.createElement('div');
		elem_div.id = "epp_locations_gmap";
		Element.setStyle(elem_div, {width: width + "px", height: height + "px"});
		$('main_content').appendChild(elem_div);
		
		this.gmap = new GMap2(elem_div);
		this.gmap.setCenter(new GLatLng(this.default_lat, this.default_lng), this.default_zoom);
		return this.gmap;
		
	}//end createGMap
	
	/**
	 * Adds the given control ( which must implement the interface GControl ) to the GMap. 
	 * An error is thrown if the GMap is not yet instantiated.  
	 *
	 * Built in valid controls are: GSmallMapControl, GLargeMapControl, GSmallZoomControl, 
	 * GScaleControl, GMapTypeControl
	 *
	 * @access public
	 * @throws Exception
	 * @param control 		-	Implements the GControl interface
	 * @return void
	 */
	this.addMapControl = function(control)
	{
		if ( this.gmap == null ) {
			throw new Exception("Cannot add that control because the GMap is not yet instaniated.");
			
		}
		
		this.gmap.addControl(control);
		
	}//end addMapControl
	
	/**
	 * Add the EPP Location, given by name, to the map.  Valid values are:
	 * apl, dorsey, homewood, mcc, dccenter, smhec, and heat
	 * 
	 * @access public
	 * @throws Exception
	 * @return void
	 */
	this.addEppLocation = function(name, center)
	{
		//Check that the gmap has been initialized
		if ( this.gmap == null ) {
			throw new Exception("Cannot add " + name + " to the map because the map is not yet initialized.");
			
		}
		
		//Check that the name of the location is valid
		if ( typeof this.locations[name] == "undefined" ) {
			throw new Exception(name + " is not a valid location.");
			
		}
		
		//Add the point and marker to the map
		this.gmap.addOverlay(this.locations[name].getGMarker());	
		
		//Check if we want to center on this center
		if ( arguments.length == 2 && arguments[1] == true ) {
			this.gmap.setCenter(this.locations[name].getGLatLng(), this.locations[name].getZoom());
			this.locations[name].openInfoWindowHtml();
			
		}
		
	}//end addLocation
	
	/**
	 * Add all locations to the map
	 *
	 * @access public
	 * @return void
	 */ 
	this.addAllEppLocations = function()
	{
		for ( name in this.locations ) {
			this.gmap.addOverlay(this.locations[name].getGMarker());
			
		}//for
		
	}//end addAllEppLocations
	
	/**
	 * Static method shortcut for creating a google map with a single, given, location
	 *
	 * @static
	 * @access public
	 * @param string location
	 * @return void
	 */
	this.createGoogleMapForLocation = function(location)
	{
		var googleMap = new locationsGoogleMap();
		googleMap.createGMap(535, 400);
		googleMap.addMapControl(new GSmallMapControl());
		googleMap.addMapControl(new GMapTypeControl());
		googleMap.addEppLocation(location, true);
		
	}//end createGoogleMapForLocation
	
	/**
	 * Static method shortcut for creating a google map with all locations
	 *
	 * @static
	 * @access public
	 * @param string location
	 * @return void
	 */
	this.createGoogleMapForAllLocations = function()
	{
		var googleMap = new locationsGoogleMap();
		googleMap.createGMap(540, 400);
		googleMap.addMapControl(new GSmallMapControl());
		googleMap.addMapControl(new GMapTypeControl());
		googleMap.addAllEppLocations();
		
	}//end createGoogleMapForAllLocations	

}//end locationsGoogleMap

/**
 * Class for handling a location
 *
 * @access public
 * @param JSON json
 * @return void
 */
var locationsGoogleMap_Location = function(json)
{
	/**
	 * Holds a JSON of all the info for this location
	 *
	 * @access protected
	 * @var JSON
	 */
	this.info = json;
	
	/**
	 * Holds a reference to the marker, once it's created
	 *
	 * @access protected
	 * @var GMarker
	 */
	this.marker = null;
	
	/**
	 * Holds a reference to the GLatLng once created
	 *
	 * @access protected
	 * @var GLatLng
	 */
	this.latlng = null;
	
	/**
	 * Extracts the necessary address info from this.info and returns it in a nice HTML string
	 *
	 * @access public
	 * @return string
	 */
	this.getAddressHtml = function()
	{
		return "<strong>" + this.info.name + "</strong><br />" + this.info.address + "<br />" + this.info.city + ", " + this.info.state + " " + this.info.zip;
		
	}//end getAddressHtml
	
	/**
	 * Extracts the necessary address info from this.info and reteurns it formatted for us in a link 
	 * to the google maps website.  This output needs to be escaped before being used in a link.
	 *
	 * @access public
	 * @return string
	 */
	this.getAddressMap = function()
	{
		return this.info.address + ',' + this.info.city + ',' + this.info.state + ',' + this.info.zip;
		
	}//end getAddressMap
	
	this.getLocalInfoLink = function()
	{
		return '<a href="/locations/' + this.info.url + '">More Info</a>';
		
	}//end getLocalInfoLink
	
	/**
	 * Generates the HTML to be used in a GMarker.showInfoWindowHtml call
	 *
	 * @access public
	 * @return string
	 */
	this.getInfoWindowHtml = function()
	{
		return this.getAddressHtml() + '<br />' + 
				'<div style="text-align: center">' + 
				this.getLocalInfoLink() + '<br />' +  
				'<a href="http://maps.google.com/maps?f=g&h1=en&q=' + this.getAddressMap().replace(/\s/, "+") + 
				'&ie=UTF8&z=15&om=1&iwloc=A">Get Drive Directions</a></div>';
		
	}//end getInfoWindowHtml
	
	/**
	 * Just a wrapper for the GMarker.openInfoWindowHtml() method
	 *
	 * @access public
	 * @return void
	 */
	this.openInfoWindowHtml = function()
	{
		this.getGMarker().openInfoWindowHtml(this.getInfoWindowHtml());
		
	}//end openInfoWindowHtml
	
	/**
	 * Get the zoom set for this location
	 *
	 * @access public
	 * @return int
	 */
	this.getZoom = function()
	{
		return this.info.zoom;
		
	}//end getZoom
	
	/**
	 * Return the GLatLng object based on the lat and lng stored in this.info
	 *
	 * @access public
	 * @return GLatLng
	 */
	this.getGLatLng = function()
	{
		if ( this.latlng != null ) {
			return this.latlng;
			
		}
		
		var gPos = new GLatLng(this.info.lat, this.info.lng);
		this.latlng = gPos;
		return gPos;
		
	}//end getGLatLng
	
	/**
	 * Return the GMarker object based on the info stored in this.info
	 *
	 * @access public
	 * @return GMarker
	 */
	this.getGMarker = function()
	{
		if ( this.marker != null ) {
			return this.marker;
			
		}
		
		var gMarker = new GMarker(this.getGLatLng());
		GEvent.addListener(gMarker, "click", this.hndlGMarkerClick.bind(this));
		this.marker = gMarker;
		return gMarker;
		
	}//end getGMarker
	
	/**
	 * Handler for a marker gettign clicked
	 *
	 * @access public
	 * @return void
	 */
	this.hndlGMarkerClick = function()
	{
		this.openInfoWindowHtml();
		
	}//end hndlGMarkerClick	
	
}//end locationsGoogleMap_Location