/** 
   :Class: tabset

   :Synopsis:  
	 A class for managing a windows-interface-like set of "tabs" in an
	 html container.

   :Description:  
   The tabset manager consists of:
		The tabset container, which contains all the tab buttons and the tab 
		contents
		
		The tabs buttons container, where all the buttons go (duh).
		
		The tabs contents container, where all the contents that correspond to
		the various tab buttons will be placed.
		
		Various methods and properties for adding, hiding and showing the tab
		contents and highlighting/unhighlighting the tab buttons.

   :Notes: 
	How to implement:
	
	You will need:
		1) a container for the tabset. This can be a div or a table cell, or 
			really any block container.
		2) 2 or more divs to be "tab contents".
		3) This library :)
		
	Assuming you have the HTML containers mentioned above, here's how you would
	implement a tabset interface:
	
	var myTabset = top.gw.getTabset(document.getElementById("tabsetContainer"));
	myTabset.addTabContents(document.getElementById("formContainer1"), "Name");
	myTabset.addTabContents(document.getElementById("formContainer2"), "Checkbox");
	
	NOTE: The id's used in the examples above are arbitrary, you can call your
	divs anything you like.
	
	In the above example, the two formContainer divs will be appended as children
	to the tabs container. And two corresponding tab buttons will be added as
	children to the tabs buttons container, and they'll have labels as sepcified
	by the second argument to addTabContents().
	
	If you have specific actions that need to take place when one tab is clicked
	on, you can write your own function in your application and pass it to this
	libraries setShowMe() method. Continuing from the previous example:
	
	function doTabStuff() {alert("You clicked on tab number " + this.getAttribute("tabIndex"));}
	myTabset.setShowMe(doTabStuff);
	
	When you pass your own function to setShowMe(), any references to "this." will
	refer to to the tab's div element (not the tab contents, but the actual tab
	button the user clicked on). This change in scope is a little confusing 
	initially, but the ability to write your own custom function for handling
	tab changes can give you a lot of flexibility.
	
	In your custom function, you can get back to this library's methods via
	this.tabManager, which refers back to the tabset object. 
	
	function doTabStuff()
	{
		var tabIndex = this.getAttribute("tabIndex");
		alert("You clicked on tab # " + tabIndex);
		this.tabManager.showTab(tabIndex);
	}
	myTabset.setShowMe(doTabStuff);
	
	NOTE: This library currently uses our tab background images from the main
	navigation to provide a consistent look and feel. The tab background images
	are all handled via CSS classes. You'll need to define your own in the style
	sheet for your application.
	
	:History:
		None.
**/

/*
top.gw is a global variable for all groupware-related utilities. It provides a
safe name space for groupware utility functions and objects. It should be
at the top of any file that defines groupware utilities.
*/
if (typeof top.gw == "undefined")
{
	top.gw = new Object();
}


top.gw.getTabset = function(containerDiv)
{
	var tabset = new Object();
	tabset.container = containerDiv;
	tabset.tabsButtonsContainer = document.createElement("div");
	tabset.tabsContentsContainer = document.createElement("div");
	tabset.tabs = new Array();
	tabset.tabContents = new Array();
	tabset.activeTab = null;
	
	// add the containers for the tab buttons and the tab contents to the
	// main tabset container.
	tabset.container.appendChild(tabset.tabsButtonsContainer);
	tabset.tabsButtonsContainer.style.border = "0px solid black";
	tabset.tabsButtonsContainer.style.borderBottomWidth = "1px";
	tabset.tabsButtonsContainer.style.padding = "4px 2px 0px 2px";
	tabset.tabsButtonsContainer.style.whitespace = "";
	tabset.tabsButtonsContainer.style.backgroundColor = "white";
	tabset.container.appendChild(tabset.tabsContentsContainer);
	
	tabset.addTabContents = function(tabContentsDiv, tabLabel)
	{
		// add tab contents to the tabs array.
		var tabIndex = tabset.tabContents.length;
		tabset.tabContents[tabIndex] = tabContentsDiv;
		tabContentsDiv.style.display = "none";
		
		// remove tab contents div from document.
		var tabParent = tabContentsDiv.parentNode;
		tabParent.removeChild(tabContentsDiv);
		
		// append tab contents to the tabs container.
		tabset.tabsContentsContainer.appendChild(tabContentsDiv);
		
		// add the index attribute to the tab contents div.
		tabContentsDiv.setAttribute("tabIndex", tabIndex);
		
		// make a tab button for this tab.
		tabset.makeTabButton(tabLabel, tabIndex);
		
		// if this is the first tab added, highlight it.
		if (tabIndex == 0)
		{
			tabset.showTab(tabIndex);
		}
		else
		{
			tabset.hideTab(tabIndex);
		}
	}
	
	
	tabset.makeTabButton = function(tabLabel, contentsID)
	{
		// make the label for the tab and the tab end.
		var labelText = document.createTextNode(tabLabel);
		var labelSpan = document.createElement("span");
		labelSpan.className = "dialogBoxTabLeftEnd";
		labelSpan.style.display = "block";
		labelSpan.appendChild(labelText);
		
		var tabDiv = document.createElement("div");
		tabDiv.appendChild(labelSpan);
		tabDiv.setAttribute("tabIndex", contentsID);
		tabDiv.className = "dialogBoxTab";
		tabDiv.style.styleFloat = "left";
		tabDiv.style.cssFloat = "left";
		tabDiv.style.display = "block";
		tabDiv.onclick = tabset.showMe;
		tabDiv.tabManager = tabset;
		tabset.tabs[contentsID] = tabDiv;
		tabset.tabsButtonsContainer.appendChild(tabDiv);
		tabset.tabsButtonsContainer.style.height = labelSpan.clientHeight;
	}
	
	
	tabset.showTab = function(tabIndex)
	{
		if(!tabIndex)
		{
			tabIndex = 0;
		} 
		// check to see if container is a table cell or row and use appropriate
		// styles.
		if (tabset.activeTab)
		{
			var activeTabIndex = tabset.activeTab.getAttribute("tabIndex");
			tabset.hideTab(activeTabIndex);
		}
		var tabContents = tabset.tabContents[tabIndex];
	 	if(tabContents)
		{
			tabContents.style.display = "block";
			tabset.highlightTab(tabIndex);
			tabset.activeTab = tabContents;
		}
	}
	
	
	// showMe() will actually be called from a different scope than the other
	// functions in this object. showMe() is called from the scope of the tab
	// div element, so "tabset." refers to that tab div, NOT to the top.gw.this
	// object everything else refers to. 
	tabset.showMe = function()
	{
		var tabIndex = this.getAttribute("tabIndex");
		this.tabManager.showTab(tabIndex);
	}
	
	
	/*
	setShowMe() will change the onClick method for all the tab objects. This
	allows an application to set it's own handler for tab clicks, which can be
	handy if there's some application-specific action that needs to take place
	when one tab or another is selected.
	*/
	tabset.setShowMe = function(funcRef)
	{
		tabset.showMe = funcRef;
		for (var i = 0; i < tabset.tabs.length; i++)
		{
			tabset.tabs[i].onclick = funcRef;
		}
	}
	
	
	tabset.hideTab = function(tabIndex)
	{
		var tabContents = tabset.tabContents[tabIndex];
		tabset.unHighlightTab(tabIndex);
		if(tabContents)
		{
			tabContents.style.display = "none";
		}
	}
	
	
	tabset.hideAllTabs = function()
	{
		for (var i = 0; i < tabset.tabContents.length; i++)
		{
			tabset.hideTab(i);
		}
	}
	
	
	tabset.highlightTab = function(tabIndex)
	{
		var tab = tabset.tabs[tabIndex];
		var label = tab.firstChild;
		
		tab.className = "dialogBoxTab_highlighted";
		label.className = "dialogBoxTabLeftEnd_highlighted";
	}
	
	
	tabset.unHighlightTab = function(tabIndex)
	{
		var tab = tabset.tabs[tabIndex];
		var label = tab.firstChild;
		
		tab.className = "dialogBoxTab";
		label.className = "dialogBoxTabLeftEnd";
	}
	
	return tabset;
}