/** LeftMenu
* A Singleton class that provides the methods for working with the left menu (side bar),
* giving the functionality to initialize its subobjects (LeftMenuCampus), and switch between
* those campuses.
* 
* @class LeftMenu
*	@singleton
* @returns {void}
*/
var LeftMenu = new function() {

	this.leftMenuRef = null;
	this.campuses = new Array();
	
	this.selectedMapItemIDs = new Array();		// Array to hold all mapItemID's that are selected in the left menu
																						// This array may hold duplicate values, such as if two categories are
																						// shown with the same mapItemID

	this.getSelectedMapItemIDs = function() { return this.selectedMapItemIDs; }


	/** init
	* Initialize the LeftMenu object
	*
	* @method init
	* @return {void}
	*/
	this.init = function() {
		this.leftMenuRef = document.getElementById( "leftMenu" );
		
		// Put some text in the left menu for now to show that its loading (this can be commented out if you dont want it)
		this.leftMenuRef.appendChild( document.createTextNode( "Loading..." ) );
		
		// Create Left Menu with Categories XML Data
		var callback = {
			success: function( response ) {
				// Subscribe to the initializedEvent from Map, to run this.createLeftMenu when it fires
				var createLeftMenu = function() {
					this.createLeftMenu( response ); 
				}
				Map.initializedEvent.subscribe( createLeftMenu, this, true );
				
				// If the map has already been initialized (meaning that we missed the 
				// initializedEvent's firing), then just run this.createLeftMenu() immediately.
				// It's best however to subscribe to the event first, as it is possible (altho unlikely)
				// that Map.initialized will be set to true just before the event is subscribed to in this function.
				if( Map.initialized ) this.createLeftMenu( response );
			},
			failure: this.handleAjaxFailure, 
			scope: this 
		};
		var requestCategories = YAHOO.util.Connect.asyncRequest( 'GET', 'data/leftMenuCategories.xml', callback ); 
	}
	
	
	/** createLeftMenu
	* Creates the left menu based on the XML received
	*
	* @method createLeftMenu
	* @param {XMLDocument} response
	* @return {void}
	*/
	this.createLeftMenu = function( response ) {
		var xml = response.responseXML.documentElement;
		var campuses = xml.getElementsByTagName( "campus" );
		//var documentFragment = document.createDocumentFragment();
		
		// Clear the "Loading..." from the left menu
		while( this.leftMenuRef.firstChild ) this.leftMenuRef.removeChild( this.leftMenuRef.firstChild );
		
		for( var i = 0, numCampuses = campuses.length; i < numCampuses; i++ ) {
			var campusXmlNode = campuses[ i ];
			var leftMenuCampus = new LeftMenuCampus();
			leftMenuCampus.init( campusXmlNode );
			this.campuses.push( leftMenuCampus );
		}
				
		// Show the first campus
		var tabView = new YAHOO.widget.TabView( this.leftMenuRef );

		for( var i = 0, numCampuses = this.campuses.length; i < numCampuses; i++ ) {
			var tab = new YAHOO.widget.Tab( {
				label: this.campuses[ i ].campusName,
				contentEl: this.campuses[ i ].element
			});
			tabView.addTab( tab );
		}
		tabView.selectTab( 0 );
		
		// Add an event listener to the tab index change, to have the map switch between campuses.
		tabView.addListener( 'activeIndexChange', function( evt ) {
			if( evt.newValue == 0 ) {
				Map.showMainCampus();
			} else {
				Map.showRiverCampus();
			}
		}, null, this );
	}
	
	
	
	/** showMarkers
	* General toggle sub menu / show markers function.  Show's/Hide's a sub menu when a checkbox is clicked
	*
	* @method showMarkers
	* @param {HTMLEvent} evt
	* @param {HTMLElement} subMenuElement : The sub menu element (div) to show/hide
	* @return {void}
	*/
	this.showMarkers = function( evt, args ) {
		var checkbox = YAHOO.util.Event.getTarget( evt ),
				subMenuElement = args.subMenuElement,
				mapItemIDs = args.mapItemIDs,
				Event = YAHOO.util.Event;
		
		subMenuElement.style.display = ( checkbox.checked ) ? "block" : "none" ;
		
		if( checkbox.checked ) {
			this.selectedMapItemIDs = this.selectedMapItemIDs.concat( mapItemIDs );
			Map.showMapItems( this.selectedMapItemIDs );
		} else {
			for( var i = 0, numMapItemIDs = mapItemIDs.length; i < numMapItemIDs; i++ ) {
				for( var j = 0, numSelectedMapItemIDs = this.selectedMapItemIDs.length; j < numSelectedMapItemIDs; j++ ) {
					if( mapItemIDs[ i ] == this.selectedMapItemIDs[ j ] ) {
						this.selectedMapItemIDs.splice( j, 1 );
						break;  // break out of the inner loop, to only delete the first found mapItemID, and not all found mapItemID's
					}
				}
			}
			Map.showMapItems( this.selectedMapItemIDs );
			
			
			// Close all child submenus (basically, uncheck them all and then run their click handlers)
			var childCheckboxes = subMenuElement.getElementsByTagName( "INPUT" );
			for( var i = 0, numCheckboxes = childCheckboxes.length; i < numCheckboxes; i++ ) {
				var currentCheckbox = childCheckboxes[ i ];
				
				// If the current checkbox is checked, uncheck it and run the checkbox's click event handler to remove map markers
				if( currentCheckbox.checked ) {
					currentCheckbox.checked = false;	// Uncheck child checkbox
					
					// Get the click event listeners (should only be one) for the checkboxes, and run them
					var listeners = Event.getListeners( currentCheckbox, 'click' );
					for( var j = 0, numListeners = listeners.length; j < numListeners; j++ ) {
						var l = listeners[ j ];
						l.fn.call( l.scope, { target: l.adjust, srcElement: l.adjust }, l.obj );			// Call listener function in correct scope with the correct object argument
					}
				}
			}
		}
	}
	
	
	
	
	/** handleAjaxFailure
	* Handle XML load failure 
	*
	* @method handleAjaxFailure
	* @return {void}
	*/
	this.handleAjaxFailure = function( response ) {
		var errorMsg = "An error occurred while loading the left menu.  The following message is for developers purposes only.<br>";
		if ( response.responseText !== undefined ) {
			errorMsg += "<li>Transaction id: " + response.tId + "</li>";
			errorMsg += "<li>HTTP status: " + response.status + "</li>";
			errorMsg += "<li>Status code message: " + response.statusText + "</li>";
		}
		this.leftMenuRef.innerHTML = errorMsg;
	}
}