/** Map
* A Singleton class that provides the methods for working with the actual map, and its map items.
* 
* @class Map
*	@singleton
* @returns {void}
*/
Map = new function() {
	
	// Class Variables
	this.MapUtil = null;	// Will be a reference to Map.util
	this.map = null;			// Class variable to hold the map object
	this.mapItems = new MapItemCollection();
	
	// Variables to synchronize any functions that must load after this class has 
	// finished nitializing (i.e. map items have been set up)
	this.initialized = false;
	this.initializedEvent = new YAHOO.util.CustomEvent( "initializedEvent" );
	
	
	/** init
	* Build and initialize the map
	*
	* @method init
	* @return {void}
	*/
	this.init = function() {
		var self = this,
				Event = YAHOO.util.Event;
		

		
		// Create the map
		this.map = new GMap2( document.getElementById( "map" ) );		// Store a reference to the map in this class
		this.map.setCenter( new GLatLng( 37.315294, -89.528146 ), 16 );
		
		this.map.addControl( new GMapTypeControl() );
		this.map.addControl( new GLargeMapControl() );
		this.map.enableContinuousZoom();
		
		
		// Get the Map Items Data and Setup the Map object
		GDownloadUrl( "data/getMapItems.php", function( doc ) {
			var xmlDoc = GXml.parse( doc );
			
			// Setup Markers
			var markers = xmlDoc.documentElement.getElementsByTagName( "marker" );
			for( var i = 0, numMarkers = markers.length; i < numMarkers; i++ ) {
				var mapItemID = markers[ i ].getAttribute( "mapItemID" );
				var name = markers[ i ].getAttribute( "name" );
				var address = markers[ i ].getAttribute( "address" );
				var url = markers[ i ].getAttribute( "url" );
				var wirelessLocation = markers[ i ].getAttribute( "wirelessLocation" );
				var img = markers[ i ].getAttribute( "img" );
			
				if( img == "" )		// No image, use the default
					img = "http://wds.semo.edu/map/img/VT_Redhawk.jpg";  
				
				//var category = markers[ i ].getAttribute( "category" );
				var iconURL = markers[ i ].getAttribute( "iconURL" );
				
				var lat = parseFloat( markers[ i ].getAttribute( "lat" ) );
				var lng = parseFloat( markers[ i ].getAttribute( "lng" ) );
				var point = new GLatLng( lat, lng );
				
				
				//var gMarker = MapItemFactory.createMarker( point, category );
				var gMarker = MapItemFactory.createMarker( point, iconURL );
				
				// Use closures to create a click handler function that uses the current value of mapItemID (instead of referencing it)
				var createClickHandler = function( mapItemID ) { 
					return function() { self.showMapItemInfoWindow( null, mapItemID ); };
				}
				GEvent.addListener( gMarker, "click", createClickHandler( mapItemID ) );
				
				self.addMapItem( mapItemID, name, address, img, url, wirelessLocation,  gMarker ); 
				gMarker.hide();
			}
				
			// Setup Polygons
			var polygons = xmlDoc.documentElement.getElementsByTagName( "polygon" );
			for( var i = 0, numPolygons = polygons.length; i < numPolygons; i++ ) {
				var mapItemID = polygons[ i ].getAttribute( "mapItemID" );
				var name = polygons[ i ].getAttribute( "name" );
				var address = polygons[ i ].getAttribute( "address" );
				var img = polygons[ i ].getAttribute( "img" );
				var url = polygons[ i ].getAttribute( "url" );
				var wirelessLocation = polygons[ i ].getAttribute( "wirelessLocation" );
				
				var color = polygons[ i ].getAttribute( "color" );
				var points = polygons[ i ].getAttribute( "points" );
				var levels = polygons[ i ].getAttribute( "levels" );
				
				if( img == "" )
					img = "http://wds.semo.edu/map/img/VT_Redhawk.jpg";
				
				var gPolygon = MapItemFactory.createPolygon( color, points, levels );
				
				// Use closures to create a click handler function that uses the current value of mapItemID (instead of referencing it)
				var createClickHandler = function( mapItemID ) { 
					return function() { self.showMapItemInfoWindow( null, mapItemID ); };
				}
				GEvent.addListener( gPolygon, "click", createClickHandler( mapItemID ) ); 
				self.addMapItem( mapItemID, name, address, img, url, wirelessLocation, gPolygon );
				self.getMapItem( mapItemID ).show();
				self.getMapItem( mapItemID ).hide();
			}
			
				
			// Setup Lines (i.e. bus routes, etc)
			var lines = xmlDoc.documentElement.getElementsByTagName( "line" );
			for ( var i = 0, numLines = lines.length; i < numLines; i++ ) {
				var mapItemID = lines[ i ].getAttribute( "mapItemID" );
				var name = lines[ i ].getAttribute( "name" );
				var color = lines[ i ].getAttribute( "color" );
				var points = lines[ i ].getAttribute( "points" );
				var levels = lines[ i ].getAttribute( "levels" );
				
				var gPolyline = MapItemFactory.createPolyline( color, points, levels );
				self.addMapItem( mapItemID, name, '', '', '', '', gPolyline );
				gPolyline.hide();
			}
				
			// Set Map.initialized to true and fire the initializedEvent
			self.initialized = true;
			self.initializedEvent.fire();
			
			// Listens for mapItemID in the URL, if there shows marker + infowindow, otherwise, it is ignored
			if( urlParams.mapItemID ) {
				YAHOO.lang.later( 100, null, function() {
					Map.showMapItems( new Array( urlParams.mapItemID ) );
					Map.showMapItemInfoWindow("click", urlParams.mapItemID);
				} );
			}

		} ); // == end of gDownloadURL ==
		
		
		
		// Show the Main Campus
		this.showMainCampus();
		

	}
	
	
	
	/** showMainCampus
	* Shows the Main Campus Left Menu and Map.  Responds to the click of the "Main Campus" button.
	*
	* @method showMainCampus
	* @returns {void}
	*/
	this.showMainCampus = function() {
		var currentPoint = new GLatLng( 37.312662, -89.530871 );
		this.map.setCenter(currentPoint, 16);
		this.map.openInfoWindowHtml( currentPoint, '<div style="white-space: no-wrap;"><h3><a target="blank" href="http://www.semo.edu/">Southeast Missouri State University</a> - Main Campus</h3><ul><li><a href="http://www.semo.edu/visitors/">Visitor information</a></li><ul></div>' );
		
	}
	
	
	/** showRiverCampus
	* Shows the River Campus Left Menu and Map.  Responds to the click of the "River Campus" button.
	*
	* @method showRiverCampus
	* @returns {void}
	*/
	this.showRiverCampus = function() {
		var currentPoint = new GLatLng( 37.296443,-89.521741 );
		this.map.setCenter( currentPoint, 17 );
		this.map.openInfoWindowHtml( currentPoint, '<div style="white-space: no-wrap;"><h3><a target="blank" href="http://www.semo.edu/">Southeast Missouri State University</a> - River Campus</h3><ul><li><a href="http://www.semo.edu/visitors/">Visitor information</a></li><ul></div>' );
				
	}
	
	
	
	/** addMapItem
	* Adds a map item
	*
	* @method addMapItem
	* @param {int} mapItemID
	* @param {String} name
	* @param {String} address
	* @param {String} img
	* @param {String} url
	* @param {String} wirelessLocation
	* @param {GMarker | GPolygon | GPolyline} gItem
	* @return {void}
	*/
	this.addMapItem = function( mapItemID, name, address, img, url, wirelessLocation,  gItem ) {
		this.mapItems.add( mapItemID, name, address, img, url, wirelessLocation,  gItem );
		
	}
	
	
	/** getMapItem
	* Gets a map item by mapItemID
	*
	* @method getMapItem
	* @param {int} mapItemID
	* @return {MapItem}
	*/
	this.getMapItem = function( mapItemID ) {
		return this.mapItems.get( mapItemID );
	}
	
	
	/** showMapItems
	* Show map items on the map
	*
	* @method showMapItems
	* @param {Array} aMapItemIDs : The mapItemID's of the markers to be shown
	* @return {void}
	*/
	this.showMapItems = function( aMapItemIDs ) {
		this.map.closeInfoWindow();		// Close any open info window on the map
		
		this.mapItems.hideAll();						// Hide
		this.mapItems.show( aMapItemIDs );
	}
	
	
	
	
	/** showMapItemInfoWindow
	* Shows the info window for a map item. Responds to the clicking of left menu links.
	*
	* @method showMapItemInfoWindow
	* @param {HTMLEvent} evt : The click event on the link
	* @param {String} mapItemID : The mapItemID of the map item
	* @returns {void}
	*/
	this.showMapItemInfoWindow = function( evt, mapItemID ) {
		// Close any already open info window
		this.map.closeInfoWindow();		// Close any open info window on the map
		
		// Show all markers that should be shown from the left menu
		// (while hiding any shown markers that were shown from a previous marker search)
		this.showMapItems( LeftMenu.getSelectedMapItemIDs() ); 
		
		// Show the info window
		this.mapItems.showInfoWindow( mapItemID );
	}
}