/**
* @fileoverview This file contains the tab manager object
* @author Andrew Tourtellot
* @version 0.1
*/

/**
* This is a manager object that handles initialization and transition between tabs
* @object
*/
var TabSystem = Class.create();

TabSystem.prototype = {
	
	/** declares all variables needed to maintain a tab system for a map
	* @contructor
	*/
	initialize: function() {
		this.tabs = new Array(); // associative array for open tabs
		this.curTab = null;
		this.uniqueIDs = 0;
		this.labelContainer = $('tabLabels');
		this.contentContainer = $('tabContentWrapper');
		this.tabContainer = $('tab');
		this.closer = $('closeLink');
		this.minner = $('miniLink');
		
		this.closeFunc = this._closeButton.bindAsEventListener(this);
		this.minFunc = this._minButton.bindAsEventListener(this);
		this.maxFunc = this._maxButton.bindAsEventListener(this);
		this.closer.observe("click",this.closeFunc);
		this.minner.observe("click",this.minFunc);
	},
	
	/** closes the current tab, triggered by close button 
	* @event
	*/
	_closeButton: function(event) {
		if (this.curTab != null) {
			this.closeTab(this.curTab);
		}
	},
	
	/** toggles the current tab, effecting a minimize or maximize on the whole system 
	* @event
	*/
	_minButton: function(event) {
		// show the maximize button and minimize the contents
		Effect.BlindUp($('tabBody'), {duration:0.5});
	},
	
	/** toggles the current tab, effecting a minimize or maximize on the whole system 
	* @event
	*/
	_maxButton: function(event) {
		Effect.BlindDown($('tabBody'), {duration:0.5});
	},
	
	/** utility function for creating IDs for tabs that do not provide their own*/
	getUniqueTabID: function() {
		var ret = this.uniqueIDs+'uniqueTabID';
		this.uniqueIDs++;
		return ret;
	},
	
	/** returns a tab of a specified ID if it is in the system 
	* @param {string} tabID the id of the tab container
	*/
	getTab: function(tabID) {
		var tab = null;
		// find a matching tab
		if (tabID != null) {
			this.tabs.each(function(aTab) {
				if (aTab.id == tabID) {
					tab = aTab;
				}
			});
		}
		return tab;
	},
	
	/** completely closes a given tab, removing it from the system and removing its HTML from the document
	* @param {object} tab tab object
	*/
	closeTab: function(tab) {
		// remove the tab from the array if not retained
		if(!tab.close()) {
			this.tabs = this.tabs.without(tab);
		}
		
		// if the closed tab is the current one showing, change to another one
		if (tab == this.curTab) {
			// search for tabs still open
			var newCur = null;
			this.tabs.each(function(aTab) {
				if (!aTab.closed) {
					newCur = aTab;
				}
			});
			// if there are no tabs left, slide the tab div back
			if (newCur == null) {
				Effect.BlindUp(this.tabContainer, {duration: 0.5});
				this.curTab = null;
			}
			else {
				this.curTab = newCur;
				this.curTab.show(this.labelContainer);
			}
		}
	},
	
	/** changes currently showing tab to a certain tab. closeIfOpen determines whether a tab is forced to stay open if it is already the current tab,
		or if it should toggle closed (closeIfOpen == 1 -> toggle) 
	* @param {object} tab tab object
	*/
	changeTab: function(tab,closeIfOpen) {
		// if the tab is already open, close it

		// if the tabs are minimized, maximize them
		if (this.contentContainer.style.display == 'none') {
			this.maxFunc();
		}
		tab.show(this.labelContainer);
		if (this.curTab != tab) {
			if (this.curTab == null) {
				Effect.BlindDown(this.tabContainer, {duration:0.5});
			}
			else {
				this.curTab.hide();
			}
			this.curTab = tab;
		}
		//}
	},
	
	/** creates a new tab object and HTML elements for it
	* @param {String} tabID id of the tab
	* @param {String} tabName name of the tab
	* @param {boolean} permanent whether the tab is permanent
	* @param {boolean} closed the initial state is closed
	*/
	makeTab: function(tabID,tabName,permanent,closed) {
		var arraySize = this.tabs.size();
		var tab = new Tab(tabID,tabName,this,permanent);
		tab.makeNewDivs(tabID,this.labelContainer,this.contentContainer);
		if (closed) {
			tab.close();
		}
		this.tabs[arraySize] = tab;
		return tab;
	},
	
	/** returns a tab matching tabID. if none exists, creates one with matching tabName unless tabName is empty. if no tabID is provided, creates tab with
		a unique ID and the provided name, unless no name is provided. If a new tab is created, the permanent variable sets whether the tab will be
		completely discarded when it closes or whether it will be retained. the closed parameter sets whether the tab starts as closed or open 
	* @param {String} tabID id of the tab
	* @param {String} tabName name of the tab
	* @param {boolean} permanent whether the tab is permanent
	* @param {boolean} closed the initial state is closed
	*/
	loadTab: function(tabID,tabName,permanent,closed) {
		var tab = this.getTab(tabID);
		var newTab = false;
		
		// make tab if nonexistent
		if (tab == null && tabName != null) {
			newTab = true;
			if (tabID == null) {
				tabID = this.getUniqueTabID();
			}
			tab = this.makeTab(tabID,tabName,permanent,closed);
		}
		// reopen tab if closed
		else if (tab != null && tab.closed) {
			tab.reOpen(this.labelContainer);
		}
		return {tab: tab, madeNew: newTab};
	},
	
	/**
	* change the current active tab to the one w/ tabID=tabID
	*/
	showTab: function(tabID) {
		var tab = this.getTab(tabID);
		if (tab != null) {
			this.changeTab(tab,false);
		}
		return tab;
	}
}