/* SpryTabbedPanels.js - Revision: Spry Preview Release 1.4 */





// Copyright (c) 2006. Adobe Systems Incorporated.


// All rights reserved.


//


// Redistribution and use in source and binary forms, with or without


// modification, are permitted provided that the following conditions are met:


//


//   * Redistributions of source code must retain the above copyright notice,


//     this list of conditions and the following disclaimer.


//   * Redistributions in binary form must reproduce the above copyright notice,


//     this list of conditions and the following disclaimer in the documentation


//     and/or other materials provided with the distribution.


//   * Neither the name of Adobe Systems Incorporated nor the names of its


//     contributors may be used to endorse or promote products derived from this


//     software without specific prior written permission.


//


// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"


// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE


// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE


// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE


// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR


// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF


// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS


// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN


// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)


// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE


// POSSIBILITY OF SUCH DAMAGE.





var Spry;


if (!Spry) Spry = {};


if (!Spry.Widget) Spry.Widget = {};





Spry.Widget.TabbedPanels = function(element, opts)


{


	this.element = this.getElement(element);


	this.defaultTab = 0; // Show the first panel by default.


	this.bindings = [];


	this.tabSelectedClass = "TabbedPanelsTabSelected";


	this.tabHoverClass = "TabbedPanelsTabHover";


	this.tabFocusedClass = "TabbedPanelsTabFocused";


	this.panelVisibleClass = "TabbedPanelsContentVisible";


	this.focusElement = null;


	this.hasFocus = false;


	this.currentTabIndex = 0;


	this.enableKeyboardNavigation = true;





	Spry.Widget.TabbedPanels.setOptions(this, opts);





	// If the defaultTab is expressed as a number/index, convert


	// it to an element.





	if (typeof (this.defaultTab) == "number")


	{


		if (this.defaultTab < 0)


			this.defaultTab = 0;


		else


		{


			var count = this.getTabbedPanelCount();


			if (this.defaultTab >= count)


				this.defaultTab = (count > 1) ? (count - 1) : 0;


		}





		this.defaultTab = this.getTabs()[this.defaultTab];


	}





	// The defaultTab property is supposed to be the tab element for the tab content


	// to show by default. The caller is allowed to pass in the element itself or the


	// element's id, so we need to convert the current value to an element if necessary.





	if (this.defaultTab)


		this.defaultTab = this.getElement(this.defaultTab);





	this.attachBehaviors();


};





Spry.Widget.TabbedPanels.prototype.getElement = function(ele)


{


	if (ele && typeof ele == "string")


		return document.getElementById(ele);


	return ele;


}





Spry.Widget.TabbedPanels.prototype.getElementChildren = function(element)


{


	var children = [];


	var child = element.firstChild;


	while (child)


	{


		if (child.nodeType == 1 /* Node.ELEMENT_NODE */)


			children.push(child);


		child = child.nextSibling;


	}


	return children;


};





Spry.Widget.TabbedPanels.prototype.addClassName = function(ele, className)


{


	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))


		return;


	ele.className += (ele.className ? " " : "") + className;


};





Spry.Widget.TabbedPanels.prototype.removeClassName = function(ele, className)


{


	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))


		return;


	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");


};





Spry.Widget.TabbedPanels.setOptions = function(obj, optionsObj, ignoreUndefinedProps)


{


	if (!optionsObj)


		return;


	for (var optionName in optionsObj)


	{


		if (ignoreUndefinedProps && optionsObj[optionName] == undefined)


			continue;


		obj[optionName] = optionsObj[optionName];


	}


};





Spry.Widget.TabbedPanels.prototype.getTabGroup = function()


{


	if (this.element)


	{


		var children = this.getElementChildren(this.element);


		if (children.length)


			return children[0];


	}


	return null;


};





Spry.Widget.TabbedPanels.prototype.getTabs = function()


{


	var tabs = [];


	var tg = this.getTabGroup();


	if (tg)


		tabs = this.getElementChildren(tg);


	return tabs;


};





Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function()


{


	if (this.element)


	{


		var children = this.getElementChildren(this.element);


		if (children.length > 1)


			return children[1];


	}


	return null;


};





Spry.Widget.TabbedPanels.prototype.getContentPanels = function()


{


	var panels = [];


	var pg = this.getContentPanelGroup();


	if (pg)


		panels = this.getElementChildren(pg);


	return panels;


};





Spry.Widget.TabbedPanels.prototype.getIndex = function(ele, arr)


{


	ele = this.getElement(ele);


	if (ele && arr && arr.length)


	{


		for (var i = 0; i < arr.length; i++)


		{


			if (ele == arr[i])


				return i;


		}


	}


	return -1;


};





Spry.Widget.TabbedPanels.prototype.getTabIndex = function(ele)


{


	var i = this.getIndex(ele, this.getTabs());


	if (i < 0)


		i = this.getIndex(ele, this.getContentPanels());


	return i;


};





Spry.Widget.TabbedPanels.prototype.getCurrentTabIndex = function()


{


	return this.currentTabIndex;


};





Spry.Widget.TabbedPanels.prototype.getTabbedPanelCount = function(ele)


{


	return Math.min(this.getTabs().length, this.getContentPanels().length);


};





Spry.Widget.TabbedPanels.addEventListener = function(element, eventType, handler, capture)


{


	try


	{


		if (element.addEventListener)


			element.addEventListener(eventType, handler, capture);


		else if (element.attachEvent)


			element.attachEvent("on" + eventType, handler);


	}


	catch (e) {}


};





Spry.Widget.TabbedPanels.prototype.onTabClick = function(e, tab)


{


	this.showPanel(tab);


};





Spry.Widget.TabbedPanels.prototype.onTabMouseOver = function(e, tab)


{


	this.addClassName(tab, this.tabHoverClass);


};





Spry.Widget.TabbedPanels.prototype.onTabMouseOut = function(e, tab)


{


	this.removeClassName(tab, this.tabHoverClass);


};





Spry.Widget.TabbedPanels.prototype.onTabFocus = function(e, tab)


{


	this.hasFocus = true;


	this.addClassName(this.element, this.tabFocusedClass);


};





Spry.Widget.TabbedPanels.prototype.onTabBlur = function(e, tab)


{


	this.hasFocus = false;


	this.removeClassName(this.element, this.tabFocusedClass);


};





Spry.Widget.TabbedPanels.ENTER_KEY = 13;


Spry.Widget.TabbedPanels.SPACE_KEY = 32;





Spry.Widget.TabbedPanels.prototype.onTabKeyDown = function(e, tab)


{


	var key = e.keyCode;


	if (!this.hasFocus || (key != Spry.Widget.TabbedPanels.ENTER_KEY && key != Spry.Widget.TabbedPanels.SPACE_KEY))


		return true;





	this.showPanel(tab);





	if (e.stopPropagation)


		e.stopPropagation();


	if (e.preventDefault)


		e.preventDefault();





	return false;


};





Spry.Widget.TabbedPanels.prototype.preorderTraversal = function(root, func)


{


	var stopTraversal = false;


	if (root)


	{


		stopTraversal = func(root);


		if (root.hasChildNodes())


		{


			var child = root.firstChild;


			while (!stopTraversal && child)


			{


				stopTraversal = this.preorderTraversal(child, func);


				try { child = child.nextSibling; } catch (e) { child = null; }


			}


		}


	}


	return stopTraversal;


};





Spry.Widget.TabbedPanels.prototype.addPanelEventListeners = function(tab, panel)


{


	var self = this;


	Spry.Widget.TabbedPanels.addEventListener(tab, "click", function(e) { return self.onTabClick(e, tab); }, false);


	Spry.Widget.TabbedPanels.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(e, tab); }, false);


	Spry.Widget.TabbedPanels.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(e, tab); }, false);





	if (this.enableKeyboardNavigation)


	{


		// XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't


		// rely on adding the tabindex attribute if it is missing to enable keyboard navigation


		// by default.





		// Find the first element within the tab container that has a tabindex or the first


		// anchor tag.


		


		var tabIndexEle = null;


		var tabAnchorEle = null;





		this.preorderTraversal(tab, function(node) {


			if (node.nodeType == 1 /* NODE.ELEMENT_NODE */)


			{


				var tabIndexAttr = tab.attributes.getNamedItem("tabindex");


				if (tabIndexAttr)


				{


					tabIndexEle = node;


					return true;


				}


				if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")


					tabAnchorEle = node;


			}


			return false;


		});





		if (tabIndexEle)


			this.focusElement = tabIndexEle;


		else if (tabAnchorEle)


			this.focusElement = tabAnchorEle;





		if (this.focusElement)


		{


			Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "focus", function(e) { return self.onTabFocus(e, tab); }, false);


			Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "blur", function(e) { return self.onTabBlur(e, tab); }, false);


			Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "keydown", function(e) { return self.onTabKeyDown(e, tab); }, false);


		}


	}


};





Spry.Widget.TabbedPanels.prototype.showPanel = function(elementOrIndex)


{


	var tpIndex = -1;


	


	if (typeof elementOrIndex == "number")


		tpIndex = elementOrIndex;


	else // Must be the element for the tab or content panel.


		tpIndex = this.getTabIndex(elementOrIndex);


	


	if (!tpIndex < 0 || tpIndex >= this.getTabbedPanelCount())


		return;





	var tabs = this.getTabs();


	var panels = this.getContentPanels();





	var numTabbedPanels = Math.max(tabs.length, panels.length);





	for (var i = 0; i < numTabbedPanels; i++)


	{


		if (i != tpIndex)


		{


			if (tabs[i])


				this.removeClassName(tabs[i], this.tabSelectedClass);


			if (panels[i])


			{


				this.removeClassName(panels[i], this.panelVisibleClass);


				panels[i].style.display = "none";


			}


		}


	}





	this.addClassName(tabs[tpIndex], this.tabSelectedClass);


	this.addClassName(panels[tpIndex], this.panelVisibleClass);


	panels[tpIndex].style.display = "block";





	this.currentTabIndex = tpIndex;


};





Spry.Widget.TabbedPanels.prototype.attachBehaviors = function(element)


{


	var tabs = this.getTabs();


	var panels = this.getContentPanels();


	var panelCount = this.getTabbedPanelCount();





	for (var i = 0; i < panelCount; i++)


		this.addPanelEventListeners(tabs[i], panels[i]);





	this.showPanel(this.defaultTab);


};



