/////////////////////////////////////////////////////////////////////////////
//
// Gladiator Components 
//
// http://www.gladiatorweb.com
//
// (c) 2006 by Edward H. Trager .  All Rights Reserved
//
// NAME: gladiatorTabContainer.js
//
// DESCRIPTION: Implements core functions, methods, and objects for the
//              Gladiator components toolkit.
//
// AUTHOR: Edward H. Trager
//
// LAST UPDATE: 2006.03.08
//
// NOTE: SEE "LICENSE" FILE FOR LICENSING TERMS
//
//////////////////////////////////////////////////////////////////////////////

//
// DEPENDENCY CHECKING:
//
if(typeof GLADIATOR_CORE_INCLUDED == 'undefined') alert('NOTE BENE: "gladiatorWindows.js" REQUIRES "gladiatorCore.js"!');


//
// gTabContainer
//
// id : Container id
// tabWidth : how wide the tabs should be
// tabHeight: how high the tabs should be
// tabPosition: Where the row or stack of tabs should go: 
//              "left","top","bottom", or "right"
//
function gTabContainer(id,tabWidth,tabHeight,tabPosition,parentNode){
	
	//
	// Need _self so that private methods can access the "this"
	// -- ECMAScript standardization screw up!
	//
	var _self = this;
	
	var _id;
	if(id) _id=id;
	else   _id="myTabContainer";
	
	var  _tabWidth;
	if(tabWidth) _tabWidth=tabWidth;
	else         _tabWidth=120;
	
	var _tabHeight;
	if(tabHeight) _tabHeight=tabHeight;
	else          _tabHeight=25;
	
	//
	// ROUGH SPOT : These could be wrong if CSS changes
	//
	var _coverUpHeight =1;
	var _summedBorderThickness =5;
	
	var ON_TOP    = 0;
	var ON_LEFT   = 1;
	var ON_RIGHT  = 2;
	var ON_BOTTOM = 3;
	
	var _tabPosition=ON_TOP;
	if(tabPosition){
		if      (tabPosition=="left"  ) _tabPosition = ON_LEFT;
		else if (tabPosition=="right" ) _tabPosition = ON_RIGHT;
		else if (tabPosition=="bottom") _tabPosition = ON_BOTTOM;
	}
	
	var _thisTabContainer = document.createElementNS(NS.xhtml,"div");
	_thisTabContainer.setAttribute("class","tabContainer");
	_thisTabContainer.id = _id;
	
	////////////////////////////////////////////////
	//
	// PARENT NODE :
	//
	// By default, add window to the BODY element,
	// unless some other parentNode was supplied as
	// an argument to the constructor.
	//
	// ==> 2006.03.16.ET ADDENDUM : parentNode can now
	//     be NULL which means "Don't add object to
	//     parent yet."
	//
	////////////////////////////////////////////////
	var _parentNode;
	if(isNull(parentNode)){
		
		_parentNode = null;
		
	}else if(parentNode){
		_parentNode = parentNode;
	}else{
		_parentNode = document.getElementsByTagName("body").item(0);
	}
	//
	// Tab Count:
	//
	var _tabCount=0;
	
	var _tabs        = new Array();
	var _tabCanvases = new Array();
	
	var _tabBar = document.createElementNS(NS.xhtml,"div");
	_tabBar.setAttribute("class","tabBar");
	
	//
	// Which tab is selected first ?
	// => 1000 is an arbitrarily large value used
	//    to force the initialization code:
	//
	var _selected=1000;
	
	///////////////////////////////////////////////
	//
	// PUBLIC METHOD : selectTab(int i)
	//
	///////////////////////////////////////////////
	this.selectTab = function( newSelection ){
		// Zero Offset:
		newSelection--;
		// Range check:
		if(!( newSelection > 0 && newSelection < _tabCount )) newSelection=0;
		
		//
		// Only if different from current ...
		//
		if( newSelection != _selected ){
			//
			// Deselect currently selected:
			//
			if( _selected < _tabCount ){
				_tabs[ _selected ].setAttribute("class","tab");
				_tabs[ _selected ].style.height = _tabHeight + "px";
				_tabCanvases[ _selected ].style.display="none";
			}
			//
			// Select the new tab:
			//
			_tabs[ newSelection ].setAttribute("class","selectedTab");
			_tabs[ newSelection ].style.height = (_tabHeight + _coverUpHeight) +"px";
			_tabCanvases[ newSelection ].style.display="block";
			//
			// Save:
			//
			_selected = newSelection;
			
		}
		
	}
	
	//////////////////////////////////////////
	//
	// PRIVATE _selectTab() method used for the onClick event listener:
	//
	//////////////////////////////////////////
	function _selectTab(e){
		e = gEvent(e);
		e.preventDefault();
		var ordinal = parseInt(e.targetElement.id);
		_self.selectTab(ordinal);
	}
	
	
	///////////////////////////////////////////////
	//
	// PUBLIC METHOD : addTab( title , contents )
	//
	///////////////////////////////////////////////
	this.addTab = function(title,contents){
		
		_tabs[ _tabCount ] = document.createElementNS(NS.xhtml,"div");
		_tabs[ _tabCount ].setAttribute("class","tab");
		_tabs[ _tabCount ].addEventListener("click",_selectTab,false);
		var titleTextNode = document.createTextNode(title);
		_tabs[ _tabCount ].appendChild(titleTextNode);
		
		_tabCanvases[ _tabCount ] = document.createElementNS(NS.xhtml,"div");
		_tabCanvases[ _tabCount ].setAttribute("class","tabCanvas");
		//
		// Set direction if necessary:
		//
		if(typeof LC != "undefined"){
			if(LC.getDirection() == "rtl") _tabCanvases[ _tabCount ].style.direction="rtl";
		}
		
		
		// 
		if(isString(contents)){
			_tabCanvases[ _tabCount ].innerHTML = contents;
		}else if(contents){
			_tabCanvases[ _tabCount ].appendChild(contents);
		}
		
		//
		// Set width, height of tabs:
		//
		
		_tabs[ _tabCount ].style.width  = _tabWidth  + "px";
		_tabs[ _tabCount ].style.height = _tabHeight + "px";
		//
		// Set tabCanvas "top" position:
		//
		_tabCanvases[ _tabCount ].style.top= ( _tabHeight + _summedBorderThickness )+"px";
		
		//
		// Set tab position within container:
		//
		switch( _tabPosition ){
		case ON_TOP:
		case ON_BOTTOM:
			//_tabs[ _tabCount ].style.left = ((_tabCount-1) * _tabWidth ) + "px";
			break;
		case ON_LEFT:
		case ON_RIGHT:
			//_tabs[ _tabCount ].style.top  = ((_tabCount-1) * _tabHeight) + "px";
			break;
		}
		
		//
		// Finally we set the ids using the actual tab
		// ordinal because the selectTab and _selectTab methods expect
		// to get actual ordinals, not zero-offset indices.
		// Also note that we start the id off with an ordinal so that
		// we can just use parseInt() to get the numeric ordinal portion ...
		//
		var ordinal = _tabCount+1;
		_tabs[ _tabCount ].id = ordinal+"T-"+_id;         // TAB ID
		_tabCanvases[ _tabCount ].id = ordinal+"C-"+_id;  // CANVAS ID
		
		//
		// Because the arrays are zero-offset, we don't
		// increment the counter until here at the end ...
		//
		_tabCount++;
		
	}
	
	
	///////////////////////////////////////////////
	//
	// PUBLIC METHOD : finish()
	//
	// ==> Call after adding all tabs in order to 
	//     actually add the xhtml element nodes to
	//     the xhtml tab container.
	//
	// ==> Optionally specify which tab to display
	//     first.
	///////////////////////////////////////////////
	this.finish = function(selected){
		
		var i;
		for(i=0;i<_tabCount;i++){
			// Add tabs to tab container which is called tabBar:
			_tabBar.appendChild( _tabs[ i ] );
		}
		for(i=0;i<_tabCount;i++){
			// Add canvases to tab container:
			_thisTabContainer.appendChild( _tabCanvases[ i ] );
		}
		
		//
		// tabs are inside of tabBar appended at end so it is on top:
		//
		_thisTabContainer.appendChild(_tabBar);
		
		//
		// Append the tab tape at the very end so that it appears
		// to sit on top of the tab and tabCanvas:
 		//
		//_thisTabContainer.appendChild(_tabTape);
		
		//
		// Set up the selected tab for display:
		//
		if(!selected) selected=1;
		_self.selectTab(selected);
		
		//
		// Finally add the tab container to the parent node:
		//
		// ... unless parent node is null :
		//
		if(isNull(_parentNode)) return;
		//
		_parentNode.appendChild(_thisTabContainer);
		
	}
	
	//
	// PUBLIC getNode() method:
	//
	this.getNode = function(){
		
		return _thisTabContainer;
		
	}
	
	//
	// getTabNode
	//
	this.getTabNode = function(nth){
		
		--nth;
		if(nth<0 || nth> _tabCount-1) return false;
		
		return _tabCanvases[nth];
		
	}
	
}
