/*
License:
This script is developed by Rasmus Rummel http://www.webmodelling.com
This script is free for use under the condition that this license note is not removed
Derivative work on this script needs to preserve this license note
Work embedding this script may not do so without this license note are forwarded to any browser running this script
*/

/*
Parameters:

pTabStripID : MUST
pTabSelectEvent : OPTIONAL ("click" | "mouseover") - if "click" then you need to click the tab to select it, while if "mouseover" the tab will be selected upon mouseover
pIndexOfStartTab : OPTIONAL (integer pointing to the zero indexed number of tabs) - eg. 2 will default open tab number 3
pTabHeadersPosition : OPTIONAL ("top_left" | "top_middle" | "top_right" | "left_top" | "left_middle" | "left_bottom" | "bottom_left" | "bottom_middle" | "bottom_right" | "right_bottom" | "right_middle" | "right_top")
pNumberOfColumns : OPTIONAL ([integer]) - default for pTabHeadersPostion = top_ or bottom_ is to place all tabHeaders in 1 row, however here you can specify how many columns (tabHeaders) to show in each row. Default for pTabHeadersPosition = left_ or right_ is to place each tabHeader in its own row, however here you can specify how many columns (tabHeaders) you want to have in each row
pCssTabHeadersContainer : OPTIONAL - css class to set on the TD tabHeader container (that hosts the TABLE that layout the tabHeaders)
pCssTabHeaderSelected : OPTIONAL - css class to set on a DIV tabHeader then the tab is selected
pCssTabHeaderMouseover : OPTIONAL - css class to set on a DIV tabHeader then the mouse hovers
pCssTabHeaderMouseout : OPTIONAL - css class to set on a DIV tabHeader then the mouse does not hover
pCssTabCanvas : OPTIONAL - css class to set on a DIV tabCanvas
pCustomActionBeforeTabActivation : OPTIONAL (a Javascript function reference) - a custom function that will be invoked inside the tab activation ("click" or "mouseover") eventhandler but BEFORE the rest of the eventhandler code.
pCustomActionAfterTabActivation : OPTIONAL (a Javascript function reference) - a custom function that will be invoked inside the tab activation ("click" or "mouseover") eventhandler but AFTER the rest of the eventhandler code.
pCustomActionOnTabMouseover : OPTIONAL (a Javascript function reference) - a custom function that will be invoked inside the tab mouseover eventhandler AFTER the default mouseover code have executed
pCustomActionOnTabMouseout : OPTIONAL (a Javascript function reference) - a custom function that will be invoked inside the tab mouseout eventhandler AFTER the default mouseout code have executed

Note1 (custom handlers for secondary events):
The custom eventhandlers:
	pCustomActionBeforeTabActivation
	pCustomActionAfterTabActivation
	pCustomActionOnTabMouseover
	pCustomActionOnTabMouseout
, all have the same 5 arguments in the arguments array:
	tabStripID
	tabHeader DIV object (the one that are about to be activated)
	tabCanvas DIV object (the one that are about to be activated)
	tabIndex (index of the tab that are about to be activated)
	tabCount (number of tabs)
Example:
function myCustomActionBeforeTabActivation(){
	var tabStripID = arguments[0];
	var tabHeaderToActivate = arguments[1];
	var tabCanvasToActivate = arguments[2];
	var tabIndexToActivate = arguments[3];
	var tabCount = arguments[4];
}
wm_tabStrip("tabStripID", null, null, null, null, null, null, null, myCustomActionBeforeTabActivation);

Note2 (custom click handler):
It is possible to replace the default eventhandler with a custom eventhandler for the tabHeader click event using:
2.1) WORKS: <div onclick="customClick()">header text</div>
2.2) NOT WORK : <div id="myHeaderID">header text</div><script>document.getElementById("myHeaderID").onclick = customClick;</script> -- does not work because the ID of the tabHeader is reset by wm_tabStrip (reset to tabStripID+"tabHeader"+tabIndex).
2.3) WORKS: <script>document.getElementById(tabStripID+"tabHeader"+tabIndex).onclick = customClick;</script>
2.4) NOT WORK : <script>document.getElementById(tabStripID+"tabHeader"+tabIndex).attachEvent("onclick", customClick);//or for FF using addEventListener</script> -- does not work because Javascript cannot find any delegate attached this way ((tabStripID+"tabHeader"+tabIndex).onclick is null).
Be aware that if you replace the default eventhandler with a custom eventhandler for the click event of a tabHeader:
2.5) the default click eventhandler will be disabled.
2.6) pCustomActionBeforeTabActivation & pCustomActionAfterTabActivation will be disabled (pCustomActionOnTabMouseover & pCustomActionOnTabMouseout will still fire)
2.7) it will only work for pTabSelectEvent = "click". Adding an eventhandler to the mouseover event will not replace any of the default mouseover eventhandlers in any context. Also the result of adding a custom mouseover eventhandler to a tabHeader is unknown & untested.

Ideas:
Enable tabs as links and remove the canvas
Enable a floating helptext functionality for the tab (it could be a custom tag <helptext class="..">...</helptext>, so the user could define a class or it could be a div with class helptext <div class="helptext">...</div>, so that such a div is treated like helptext).
Enable dynamic changing of layout (if nothing else it would be good for demo purposes)

There is one flaw of the control, that one tab cannot expand over another tab (many professional tabstrips can do that). The problem is that I contain the tab divs within a table cell, so the divs cannot slide over each other. (my tabStrip though can easily layout tabs on all edges because I am using a table to do the layout)
*/
var wm_tabStrip_globals = new function(){
	this.css_tabHeaders_container = "wm_tabHeaders_container"; //config
	this.css_tabHeader_selected = "wm_tabHeader_selected"; //config
	this.css_tabHeader_mouseover = "wm_tabHeader_mouseover"; //config
	this.css_tabHeader_mouseout = "wm_tabHeader_mouseout"; //config
	this.indexOfStartTab = 0; //config
	this.css_tabCanvas = "wm_tabCanvas"; //config
	this.tabSelectEvent = "click"; //config (supports only "click" or "mouseover")
	this.tabHeadersPosition = "top_left"; //config (supports 3 different positions on each edge = 12 different positions)
	this.numberOfColumns = 0; //config (zero means as many columns as the tabStrip have tabs - so zero means 1 row. If you have 6 tabs and you set numberOfColumns=2 then you will get 3 rows)

	//Do not edit any runtime values
	var runtimes = {}
	this.getRuntime = function(pTabStripID){
		if (runtimes[pTabStripID] == null){
			var runtime = {"tabs":[],"tabHeaders":[],"tabCanvases":[]}
			runtimes[pTabStripID] = runtime;
		}
		return runtimes[pTabStripID];
	}
}

function wm_tabStrip(pTabStripID, pTabSelectEvent, pIndexOfStartTab, pTabHeadersPosition, pNumberOfColumns, pCssTabHeadersContainer, pCssTabHeaderSelected, pCssTabHeaderMouseover, pCssTabHeaderMouseout, pCssTabCanvas, pCustomActionBeforeTabActivation, pCustomActionAfterTabActivation, pCustomActionOnTabMouseover, pCustomActionOnTabMouseout){
	
	var eventHandlerFactory = function(pElm, pAction){
		var tabHeader = pElm;
		var tabIndex = pElm.tabIndex;
//		var tabCanvas = runtime.tabCanvases[tabIndex]; //Jeg fatter nada - why is tabCanvas undefined here at event firing time then tabIndex is not and runtime is not?? (the eventhandler reference should point to the factory closure and local variables within the factory should therefore be available at eventhandler execution time - which also tabHeader clearly is)

		var eventHandler;
		if (pAction == "hoverTabHeader"){
			//this action is always attached to a mouseover event
			eventHandler = function(){
				var tabCanvas = runtime.tabCanvases[tabIndex];
				if (pCustomActionOnTabMouseover){pCustomActionOnTabMouseover(pTabStripID, tabHeader, tabCanvas, tabIndex, runtime.tabHeaders.length);}

				if (tabHeader.className == tabHeader.individualCssClass + css_tabHeader_selected){return;} //css_tabHeader_selected & runtime are available within the outer closure - wm_tabStrip (I am exeuting the eventhandlers within a nested closure - so you could say I have 2 Activation objects prefixed the execution context and all locals on the Activation objects are available (I wonder what duplet properties I am getting eg. .arguments))
				tabHeader.className = tabHeader.individualCssClass + css_tabHeader_mouseover;
				tabCanvas.className = tabCanvas.className;//IE bug : if I nest the tabStrip inside a TD (which will be common use), IE will remove the tabCanvas upon setting tabHeader.className, however setting tabCanvas.className will make IE display the tabCanvas again (it is a very strange error that I don't fully understand)
			}
		}
		else if (pAction == "unHoverTabHeader"){
			//this action is always attached to a mouseout event
			eventHandler = function(){
				var tabCanvas = runtime.tabCanvases[tabIndex];
				if (pCustomActionOnTabMouseout){pCustomActionOnTabMouseout(pTabStripID, tabHeader, tabCanvas, tabIndex, runtime.tabHeaders.length);}
				
				if (tabHeader.className == tabHeader.individualCssClass + css_tabHeader_selected){return;}
				tabHeader.className = tabHeader.individualCssClass + css_tabHeader_mouseout;
				tabCanvas.className = tabCanvas.className;
			}
		}
		else if (pAction == "openCanvas"){
			//this action can be attached to either a click or a mouseover event
			eventHandler = function(){
				var tabIndex = pElm.tabIndex;
				var tabHeaderToSelect = pElm;
				var tabCanvasToOpen = runtime.tabCanvases[tabIndex];
			
				if (pCustomActionBeforeTabActivation){pCustomActionBeforeTabActivation(pTabStripID, tabHeaderToSelect, tabCanvasToOpen, tabIndex, runtime.tabHeaders.length);}
			
				for (var t = 0; t < runtime.tabCanvases.length; t++){
					var tabHeader = runtime.tabHeaders[t];
					var tabCanvas = runtime.tabCanvases[t];
					tabHeader.className = tabHeader.individualCssClass + css_tabHeader_mouseout;
					tabCanvas.style.display = "none";
				}
				
				tabHeaderToSelect.className = tabHeaderToSelect.individualCssClass + css_tabHeader_selected;
				tabCanvasToOpen.style.display = "block";

				if (pCustomActionAfterTabActivation){pCustomActionAfterTabActivation(pTabStripID, tabHeaderToSelect, tabCanvasToOpen, tabIndex, runtime.tabHeaders.length);}
			}
		}
		
		return eventHandler;
	}

	this.addEvent = function(pTarget, pEventType, pEventHandler){
		if (pTarget.addEventListener){
				pTarget.addEventListener(pEventType, pEventHandler, false);
		}
		else if (pTarget.attachEvent){
			pTarget.attachEvent("on" + pEventType, pEventHandler);
		}
	}

	var tabSelectEvent = (pTabSelectEvent == null) ? wm_tabStrip_globals.tabSelectEvent : pTabSelectEvent;
	var indexOfStartTab = (pIndexOfStartTab == null) ? wm_tabStrip_globals.indexOfStartTab : pIndexOfStartTab;
	var tabHeadersPosition = (pTabHeadersPosition == null) ? wm_tabStrip_globals.tabHeadersPosition : pTabHeadersPosition;
	var css_tabHeader_selected = (pCssTabHeaderSelected == null) ? wm_tabStrip_globals.css_tabHeader_selected : pCssTabHeaderSelected;
	var css_tabHeader_mouseover = (pCssTabHeaderMouseover == null) ? wm_tabStrip_globals.css_tabHeader_mouseover : pCssTabHeaderMouseover;
	var css_tabHeader_mouseout = (pCssTabHeaderMouseout == null) ? wm_tabStrip_globals.css_tabHeader_mouseout : pCssTabHeaderMouseout;
	var css_tabCanvas = (pCssTabCanvas == null) ? wm_tabStrip_globals.css_tabCanvas : pCssTabCanvas;
	var css_tabHeaders_container = (pCssTabHeadersContainer == null) ? wm_tabStrip_globals.css_tabHeaders_container : pCssTabHeadersContainer;
	var numberOfColumns = (pNumberOfColumns == null) ? wm_tabStrip_globals.numberOfColumns : pNumberOfColumns;

	var tabStrip = document.getElementById(pTabStripID);
	tabStrip.style.position = "relative";
	tabStrip.style.width = (tabStrip.style.width) ? tabStrip.style.width : "0px";//0px will reduce with to content without an overflow scrollbar

	var runtime = wm_tabStrip_globals.getRuntime(pTabStripID);

	//Retrieving the header and canvas divs
	var tabIndex = -1;
	for (var t = 0; t < tabStrip.childNodes.length; t++){
		var tab = tabStrip.childNodes[t];
		if (tab.tagName == "DIV"){
			tabIndex++;//cannot use 't' as the tab index, because in FF childNodes contains also textnodes for the spaces between elements, so all these spaces will increment 't' in FF
			runtime.tabs.push(tab);
			for (var c = 0; c < tab.childNodes.length; c++){
				var child = tab.childNodes[c];
				var individualCssClass = (child.className) ? child.className + " " : "";
				child.individualCssClass = individualCssClass;
				if (child.tagName == "DIV"){
					if (runtime.tabHeaders.length < runtime.tabs.length){
						runtime.tabHeaders.push(child);
						child.className = (tabIndex == indexOfStartTab) ? individualCssClass + css_tabHeader_selected : individualCssClass + css_tabHeader_mouseout;
						child.id = pTabStripID + "tabHeader" + tabIndex;
						child.style.display = "block";
						child.style.position = "relative";
						child.tabIndex = tabIndex;//I cannot transfer tabIndex to the eventhandlers, because the eventhandlers run within a closure (this function execution context) and so tabIndex will be the final value then this function returns, not the value tabIndex have then the eventhandler is attached (but the value tabIndex have then the event is fired)
						addEvent(child, "mouseover", eventHandlerFactory(child, "hoverTabHeader"));
						addEvent(child, "mouseout", eventHandlerFactory(child, "unHoverTabHeader"));
						if (!(tabSelectEvent == "click" && child.onclick)){addEvent(child, tabSelectEvent, eventHandlerFactory(child, "openCanvas"));}
						//tabHeader style.position = "relative" cannot be set here because IE will lock the screen position of the tabHeader to the container of the tabHeader at the moment the position is set - however later I will change container and the position should of course be relative to that container at browser paint time, therefore I need to set the position last in the script (IE flaw)
						child.activateTab = eventHandlerFactory(child, "openCanvas");//here I just use the same function as the function that serves as eventhandler for the mouseover or click event 
					}
					else{
						runtime.tabCanvases.push(child);
						child.id = pTabStripID + "tabCanvas" + tabIndex;
						child.className = individualCssClass + css_tabCanvas;
						child.style.position = "relative";
						child.style.display = (tabIndex == indexOfStartTab) ? "block" : "none";
					}
				}
			}
		}
	}

	//removing the original formatting of divs
	for (var t = tabStrip.childNodes.length - 1; t >= 0; t--){
		tabStrip.removeChild(tabStrip.childNodes[t]);
	}
	
	//setting tabStrip globals
	tabStrip.length = runtime.tabHeaders.length;

	//creating the layout
	var edge = tabHeadersPosition.split('_')[0];
	var edgeAlign = tabHeadersPosition.split('_')[1];

	var tblLayout = document.createElement("TABLE");tabStrip.appendChild(tblLayout);
	tblLayout.cellPadding = 0;
	tblLayout.cellSpacing = 0;
	tblLayout.border = 0;
	tblLayout.style.width = "100%";
	tblLayout.style.height = "100%";
	var tbodyLayout = document.createElement("TBODY");tblLayout.appendChild(tbodyLayout);
	if (edge == "top" || edge == "bottom"){
		var trLayout_header = document.createElement("TR");
		var trLayout_canvas = document.createElement("TR");
		if (edge == "top"){
			tbodyLayout.appendChild(trLayout_header);//headers on top
			tbodyLayout.appendChild(trLayout_canvas);
		}
		else if (edge == "bottom"){
			tbodyLayout.appendChild(trLayout_canvas);
			tbodyLayout.appendChild(trLayout_header);//headers at bottom
		}

		var tdLayout_header = document.createElement("TD");trLayout_header.appendChild(tdLayout_header);
		tdLayout_header.className = css_tabHeaders_container;
		tdLayout_header.style.padding = "0px";
		tdLayout_header.align = (edgeAlign == "middle") ? "center" : edgeAlign;
		var tdLayout_canvas = document.createElement("TD");trLayout_canvas.appendChild(tdLayout_canvas);
		tdLayout_canvas.style.padding = "0px";

		var tblHeader = document.createElement("TABLE");tdLayout_header.appendChild(tblHeader);
		tblHeader.cellPadding = 0;
		tblHeader.cellSpacing = 0;
		tblHeader.border = 0;
		var tbodyHeader = document.createElement("TBODY");tblHeader.appendChild(tbodyHeader);
		var trHeader = null;
		if (numberOfColumns == 0){//default - only 1 row contains all tabHeaders
			trHeader = document.createElement("TR");tbodyHeader.appendChild(trHeader);
		}
		for (var t = 0; t < runtime.tabs.length; t++){
			if (numberOfColumns > 0){
				if ((t % numberOfColumns) == 0){
					trHeader = document.createElement("TR");tbodyHeader.appendChild(trHeader);
				}
			}
			var tdHeader = document.createElement("TD");trHeader.appendChild(tdHeader);
			tdHeader.style.padding = "0px";
			tdHeader.setAttribute("valign", "bottom");
			tdHeader.vAlign = "bottom";
			var tabHeader = runtime.tabHeaders[t];
			var tabCanvas = runtime.tabCanvases[t];

			tdHeader.appendChild(tabHeader);
			tdLayout_canvas.appendChild(tabCanvas)
		}
	}
	else if (edge == "left" || edge == "right"){
		var trLayout = document.createElement("TR");tbodyLayout.appendChild(trLayout);
		var tdLayout_header = document.createElement("TD");
		tdLayout_header.className = css_tabHeaders_container;
		tdLayout_header.style.padding = "0px";
		var tdLayout_canvas = document.createElement("TD");
		tdLayout_canvas.style.padding = "0px";
		if (edge == "left"){
			trLayout.appendChild(tdLayout_header);//headers column first
			trLayout.appendChild(tdLayout_canvas);
		}
		else if (edge == "right"){
			trLayout.appendChild(tdLayout_canvas);
			trLayout.appendChild(tdLayout_header);//headers column last
		}
		tdLayout_header.vAlign = edgeAlign;
		tdLayout_canvas.style.width = "100%";
		tdLayout_canvas.style.height = "100%";
		var tblHeader = document.createElement("TABLE");tdLayout_header.appendChild(tblHeader);
		tblHeader.cellPadding = 0;
		tblHeader.cellSpacing = 0;
		tblHeader.border = 0;
		var trHeader = null;//
		var tbodyHeader = document.createElement("TBODY");tblHeader.appendChild(tbodyHeader);
		for (var t = 0; t < runtime.tabs.length; t++){
			if (numberOfColumns == 0){//default - a new row for each tabHeader
				trHeader = document.createElement("TR");tbodyHeader.appendChild(trHeader);
			}
			else{
				if ((t % numberOfColumns) == 0){
					trHeader = document.createElement("TR");tbodyHeader.appendChild(trHeader);
				}
			}
			var tdHeader = document.createElement("TD");trHeader.appendChild(tdHeader);
			tdHeader.style.padding = "0px";
			tdHeader.setAttribute("valign", "bottom");
			tdHeader.vAlign = "bottom";
			var tabHeader = runtime.tabHeaders[t];
			var tabCanvas = runtime.tabCanvases[t];

			tdHeader.appendChild(tabHeader);
			tdLayout_canvas.appendChild(tabCanvas)
		}
	}

	if (tabStrip.style.height){
		/*
		Unfortunately FF calculates 100% height of a relative div within a relative div without respect to siblings.
		FF will give the inner div the same height as the outer div even if the inner div have siblings taking up some of the space of the outer div.
		IE will give the inner div whatever height is left after other flow siblings are positioned.

		Because of this flaw in FF I cannot just set the height of the canvas to 100% but instead I need to
		calculate the height in pixels as a residual of tabStrip height subtracted header height.
		*/
		var tabStrip_height = parseInt(tabStrip.style.height, 10);
		var canvas_residual_height = tabStrip_height - trHeader.offsetHeight;
		for (var c = 0; c < runtime.tabCanvases.length; c++){
			if (edge == "top" || edge == "bottom"){
				runtime.tabHeaders[c].style.position = "relative";//setting the css position property after removing the tabHeader div from its original container and after placing the tabHeader div in it's new container will make IE place the tabHeader div correctly (FF handles positioning correct no matter then the positioning happens relative to swapping the parent container).
				runtime.tabCanvases[c].style.height = canvas_residual_height + "px";//FF needs the "px" (which is also the correct syntax)
			}
			else{
				runtime.tabCanvases[c].style.height = tabStrip_height + "px";
			}
		}
	}
	else {
		//In case of edge == left || edge == "right", it would give meaning to calculate the canvas height even if the tabStrip does not
		//have a height because the headers may stack heigher than the canvas content.
	}
}



/********************************* API ****************************************/
var wm_tabStrip_APISupport = new function(){
	this.scroll = function(pElm){
		if (pElm){
			var scrollLeft = (pElm.scrollLeft) ? pElm.scrollLeft : 0;
			var scrollTop = (pElm.scrollTop) ? pElm.scrollTop : 0;
			return {"X":scrollLeft,"Y":scrollTop};
		}
//		else if (document.documentElement && document.documentElement.scrollTop){
		else if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)){
			return {"X":document.documentElement.scrollLeft,"Y":document.documentElement.scrollTop};
		}
		else if (document.body){
			return {"X":document.body.scrollLeft,"Y":document.body.scrollTop};
		}
		else if (window.pageXOffset){
			return {"X":window.pageXOffset,"Y":window.pageYOffset};
		}
		else{
			return {"X":0,"Y":0};
		}
	}
	
	this.coordinates = function(pElm){
		var elm = pElm;
		var pageOffsetX = viewportOffsetX = elm.offsetLeft;
		var pageOffsetY = viewportOffsetY = elm.offsetTop;
		while (elm = elm.offsetParent){
			pageOffsetX += elm.offsetLeft;
			pageOffsetY += elm.offsetTop;
			viewportOffsetX += elm.offsetLeft - this.scroll(elm).X;
			viewportOffsetY += elm.offsetTop - this.scroll(elm).Y;
		}

		var coords = {}
		coords.viewport = {"X":viewportOffsetX,"Y":viewportOffsetY};
		coords.document = {"X":pageOffsetX,"Y":pageOffsetY};
		
		return coords;
	}
}

function wm_tabStrip_getTabHeaderTop_viewport(pTabStripID, pTabIndex){
	var tabHeader = document.getElementById(pTabStripID + "tabHeader" + pTabIndex);
	return wm_tabStrip_APISupport.coordinates(tabHeader).viewport.Y;
}

function wm_tabStrip_getTabHeaderLeft_viewport(pTabStripID, pTabIndex){
	var tabHeader = document.getElementById(pTabStripID + "tabHeader" + pTabIndex);
	return wm_tabStrip_APISupport.coordinates(tabHeader).viewport.X;
}

function wm_tabStrip_getTabHeaderRight_viewport(pTabStripID, pTabIndex){
	var tabHeader = document.getElementById(pTabStripID + "tabHeader" + pTabIndex);
	return wm_tabStrip_getTabHeaderLeft_viewport(pTabStripID, pTabIndex) + tabHeader.offsetWidth;
}

function wm_tabStrip_getTabHeaderBottom_viewport(pTabStripID, pTabIndex){
	var tabHeader = document.getElementById(pTabStripID + "tabHeader" + pTabIndex);
	return wm_tabStrip_getTabHeaderTop_viewport(pTabStripID, pTabIndex) + tabHeader.offsetWidth;
}

function wm_tabStrip_activateTab(pTabStripID, pTabIndex){
	//note that you don't need this function to activate a specific tab on page load - this can be achieved directly in wm_tabStrip argument list as : pIndexOfStartTab
	//this function could be used eg. with a timer setting up a slide show each tab being a slide
	var tabHeader = document.getElementById(pTabStripID + "tabHeader" + pTabIndex);
	tabHeader.activateTab();
}

//function wm_tabStrip_repaint(pTabStripID, pTabSelectEvent, pIndexOfStartTab, pTabHeadersPosition, pNumberOfColumns, pCssTabHeaderSelected, pCssTabHeaderMouseover, pCssTabHeaderMouseout, pCssTabCanvas, pCustomActionBeforeTabActivation, pCustomActionAfterTabActivation, pCustomActionOnTabMouseover, pCustomActionOnTabMouseout){
//	//all the arguments of wm_tabStrip
//	//this is not going to be that easy because the original HTML markup is not existing on DOM anymore
//	
//	var tabStrip = document.getElementById(pTabStripID);
//}

function wm_tabStrip_tabLength(pTabStripID){
	var tabStrip = document.getElementById(pTabStripID);
	return tabStrip.length;
}

