var ver = navigator.appVersion,
	isNS = Boolean(navigator.productSub),
	isIE = ver.indexOf("MSIE ") != -1 ? 1 : 0
	isOTHER = (!isNS && !isIE) ? 1 : 0;

function wierdBoolAttribGetter (el, sAttrib)
{
	var oAttrib = el.getAttributeNode (sAttrib);

	if (oAttrib == null)
		return false;
	else
	if (typeof oAttrib == 'object')
		if (isIE)
			return oAttrib.value == 'true';
		else
			return true;
	else
		return oAttrib == false ? false : true;	
}
	
function myInsertAfter (el, elAppend)
{
	if (el.nextSibling)
		el.parentNode.insertBefore (elAppend, el.nextSibling);
	else
		el.parentNode.appendChild (elAppend);
}

function TabCtrl (config, bBuildNow)
{
	this.vTabs = new Array ();
	this.m_hsTabs = new Object();
	
	if (config == undefined)
		config = new Object();
		
	this.nCurrent = config.selected;
	this.m_elContainer = config.element;		
	this.m_clsTabSunken = (config.sunken_tab_class || 'TabCtrl_Sunken');
	this.m_clsTabNormal = (config.tab_class || 'TabCtrl_Tab');
	this.m_clsTabDisabled = (config.disabled_tab_class || 'TabCtrl_Disabled');
	this.m_clsTabPanel = (config.panel_class || 'TabCtrl_Panel');
	
	if (this.m_elContainer && bBuildNow)
		this.build();
}

TabCtrl.prototype.build = function ()
{
	var elIter = this.m_elContainer.firstChild, c = 0, elNext;
	
    this.nMaxHeight = 0
    this.nCurrent = -1;
    while (elIter)
	{
		if (elIter.nodeType == 1)
			if (elIter.nodeName == 'A')
			{
				var elA = elIter, elBody, oTab, bCurrent;
				
				if (c == 0)
					this.elStart = elA;
					
				do 
				{
					elIter = elIter.nextSibling;
				} while (elIter && elIter.nodeType != 1);
				elBody = elIter;

				elNext = elIter.nextSibling;		

			 	bCurrent = (this.nCurrent == c || (typeof this.nCurrent == 'string' && this.nCurrent == elA.getAttribute ('name')));

		 		if (elBody.offsetHeight > this.nMaxHeight)
			 		this.nMaxHeight = elBody.offsetHeight;
				
			 	oTab = new TabCtrlTab(this, elA, elBody, bCurrent, this.vTabs.length)
				this.vTabs.push (oTab);
				this.m_hsTabs[oTab.sName] = this.vTabs.length - 1;
				
				c++;
			} else
				throw new Error ('Unexpected \'' + elIter.nodeName + '\' tag encountered while looking for a \'A\' tag');
		else
			elNext = elIter.nextSibling;
			
		elIter = elNext;
	}

	if (this.nCurrent < 0)
		this.selectTab (0);
}
// Deprecated, use the element member of the config object
TabCtrl.prototype.initFromStart = function (elStart, nTabs, nSel)
{
	var elIter = elStart, elNext, elBody, bCurrent, oTab;

	if (!elIter || !elIter.nextSibling)
		throw new Error ("The specified starting element was not found");

    this.nMaxHeight = 0
    this.nCurrent = -1;
    this.elStart = elStart;
	for (var c = 0; c < nTabs; c++)
	{
		elNext = elIter;
		do elNext = elNext.nextSibling; while (elNext.nodeType != 1);
		elBody = elNext;
		do elNext = elNext.nextSibling; while (elNext && elNext.nodeType != 1);

	 	if (nSel == c || (typeof nSel == 'string' && nSel == elIter.getAttribute ('name')))
	 	{
		 	bCurrent = true;
		 	this.nCurrent = c;
		} else
		 	bCurrent = false;

	 	if (elBody.offsetHeight > this.nMaxHeight)
	 		this.nMaxHeight = elBody.offsetHeight;

		this.vTabs[this.vTabs.length] = oTab = new TabCtrlTab(this, elIter, elBody, bCurrent, this.vTabs.length);
		this.m_hsTabs[oTab.sName] = this.vTabs.length - 1;
		elIter = elNext;
	}

	if (this.nCurrent < 0)
		this.selectTab (0);
}
TabCtrl.prototype.getElementById = function (sID, nTab)
{
	if (nTab == undefined)
	{
		var vv = new Array ();
		
		for (var c = 0; c < this.vTabs.length; c++)	
		{
			var el = this.vTabs[c].getElementById (sID);
			
			if (undefined != el)
				return el;
		}
		return undefined;
	}
	else
		return this.vTabs[nTab].getElementById (sID);	
}
TabCtrl.prototype.getElementsByTagName = function (sTagName, nTab)
{
	if (nTab == undefined)
	{
		var vv = new Array ();
		
		for (var c = 0; c < this.vTabs.length; c++)	
		{
			var v = this.vTabs[c].elBody.getElementsByTagName (sTagName);
			
			for (var i = 0; i < v.length; i++)
				vv[vv.length] = v[i];
		}
		return vv;
	}
	else
		return this.vTabs[nTab].elBody.getElementsByTagName (sTagName);
}
TabCtrl.prototype.selectTab = function (oTab)
{
	var nTab;
	
	if (typeof oTab == 'string')
		nTab = this.m_hsTabs[oTab];
	else
		nTab = oTab;
		
	if (nTab == undefined)
		throw new Error ('Tab not found \'' + oTab + '\'')
		
 	if (this.nCurrent == nTab)
 		return; 
 		
 	if (this.vTabs[nTab].disabled)
 		return;
 		
 	if (this.onPreSelectTab)
 		if (!this.onPreSelectTab(nTab))
 			return;

 	if (this.nCurrent >= 0)
 	{
 		if (isIE)
 			this.vTabs[this.nCurrent].saveCheckboxStates();
 		
 		this.vTabs[this.nCurrent].elCaption.className = this.vTabs[this.nCurrent].disabled ? this.m_clsTabDisabled : this.m_clsTabSunken;
 		this.vTabs[nTab].elCaption.className = this.m_clsTabNormal;

		if (isIE && this.vTabs[this.nCurrent].elBody.runtimeStyle)
		{
			this.vTabs[this.nCurrent].elBody.runtimeStyle.display = 'none';
			this.vTabs[nTab].elBody.runtimeStyle.display = '';
		}
		else
			this.vTabs[this.nCurrent].elBody.parentNode.replaceChild(this.vTabs[nTab].elBody, this.vTabs[this.nCurrent].elBody);
		
		if (isIE)
			this.vTabs[nTab].restoreCheckboxStates();
	} else
	{
 		this.vTabs[nTab].elCaption.className = this.m_clsTabNormal;
		if (isIE && this.vTabs[nTab].elBody.runtimeStyle)
			this.vTabs[nTab].elBody.runtimeStyle.display = '';
		else
			myInsertAfter(this.lastTab().elCaption, this.vTabs[nTab].elBody);
	}

	if (this.vTabs[nTab].elBody.offsetHeight < this.nMaxHeight)
		this.vTabs[nTab].elBody.style.posHeight = this.nMaxHeight;
	this.vTabs[nTab].elBody.style.minHeight = this.nMaxHeight + 'px';

	this.nCurrent = nTab;

 	if (this.onPostSelectTab)
 		this.onPostSelectTab(nTab);
}
TabCtrl.prototype.tabs = function (c) { return this.vTabs[c]; }
TabCtrl.prototype.lastTab = function () { return this.vTabs[this.vTabs.length - 1]; }

function TabCtrlTab (oTabCtrl, elCap, elBody, bCurrent, nIndex)
{
	var elCapNew = document.createElement ('SPAN'),
		elA = document.createElement ('A');
		
	this.disabled = wierdBoolAttribGetter (elCap, 'DISABLED');
		
	elA.innerHTML = elCap.innerHTML;
	elA.accessKey = elCap.accessKey ? elCap.accessKey : elCap.getAttribute('ACCESSKEY');
	elA.oThisTab = elCapNew.oThisTab = this;
	elA.href = 'JavaScript: void(0)';
	elCapNew.appendChild (elA);
	if (elCapNew.mergeAttributes)
		elCapNew.mergeAttributes (elCap);
	else
		elCapNew.setAttribute ('style', elCap.getAttribute('STYLE'));
		
	elCapNew.removeAttribute ('DISABLED', 0);

	elA.onclick = function ()
	{
		this.oThisTab.oTabCtrl.selectTab (this.oThisTab.nTabIndex);
	}	
	
	this.sName = elCap.getAttribute ('name');

	this.nTabIndex = nIndex;
 	this.oTabCtrl = oTabCtrl;
 	if (oTabCtrl.elStart == elCap)
 	{
 		this.elCaption = elCapNew;
		elCap.parentNode.replaceChild (elCapNew, elCap);
 	}
	else
	{
		this.elCaption = elCapNew;
		elCap.parentNode.removeChild (elCap);
		myInsertAfter(oTabCtrl.lastTab().elCaption, elCapNew);
 	}
 	
	elBody.className = this.oTabCtrl.m_clsTabPanel;
 	this.elBody = elBody;
 	if (bCurrent)
 	{
 		this.elCaption.className = this.oTabCtrl.m_clsTabNormal;
	}
	else if (this.disabled)
	{
 		this.elCaption.className = this.oTabCtrl.m_clsTabDisabled;
		if (isIE && this.elBody.runtimeStyle)
			this.elBody.runtimeStyle.display = 'none';
		else
			this.elBody = elBody.parentNode.removeChild (elBody);
	}
	else
	{
 		this.elCaption.className = this.oTabCtrl.m_clsTabSunken;
		if (isIE && this.elBody.runtimeStyle)
			this.elBody.runtimeStyle.display = 'none';
		else
			this.elBody = elBody.parentNode.removeChild (elBody);
	}
}
TabCtrlTab.prototype.getElementByIdA = function (sID, vNodes)
{
	for (var c = 0; c < vNodes.length; c++)
		if (vNodes[c].id == sID)
			return vNodes[c];
		else
		if (vNodes[c].hasChildNodes)
		{
			var el = this.getElementByIdA (sID, vNodes[c].childNodes);
			if (undefined != el)
				return el;
		}
}
TabCtrlTab.prototype.getElementById = function (sID)
{
	return this.getElementByIdA (sID, this.elBody.childNodes);
}
TabCtrlTab.prototype.setEnabled = function (b)
{
	if (this.elCaption.className != this.oTabCtrl.m_clsTabNormal)
		this.elCaption.className = (b ? this.oTabCtrl.m_clsTabSunken : this.oTabCtrl.m_clsTabDisabled);
		
	this.disabled = !b;
}
TabCtrlTab.prototype.saveCheckboxStates = function ()
{
	var v = this.elBody.getElementsByTagName ('INPUT');
	
	this.m_vCheckboxStates = new Array ();
	
	for (var c = 0; c < v.length; c++)
		if (v[c].type == 'checkbox' || v[c].type == 'radio')
		{
			var o = new Object ();
			
			o.input = v[c];
			o.checked = v[c].checked;
			this.m_vCheckboxStates[this.m_vCheckboxStates.length] = o;
		}
}
TabCtrlTab.prototype.restoreCheckboxStates = function ()
{
	if (this.m_vCheckboxStates)
		for (var c = 0; c < this.m_vCheckboxStates.length; c++)
			this.m_vCheckboxStates[c].input.checked = this.m_vCheckboxStates[c].checked;
}