
/****************************************************************
 * Globals
 ****************************************************************
 */
var aCachedREs	= new Array();
var aoTabs		= new Array();
var fOldOnLoad	= window.onload;

/****************************************************************
 * Regular Expression Caching
 ****************************************************************
 */
function classCacheRE(sClass) {
	if(!aCachedREs[ sClass ]) {
		//aCachedREs[ sClass ] = new RegExp('^\\s*((\\S+\\s+)*)('+ sClass +')((\\s+\\S+)*)\\s*$');
		aCachedREs[ sClass ] = new RegExp('^\\s*(.*)\\b('+ sClass +')\\b(.*)\\s*$');
	}
	return( aCachedREs[ sClass ] );
}

/****************************************************************
 * Match an object for a CSS class
 ****************************************************************
 */
function classMatch(oObject, sClass) {
	if(oObject && oObject.className) {
		return(classCacheRE(sClass).exec(oObject.className));
	}
	return(false);
}

/****************************************************************
 * CSS Class Addition / Removal
 ****************************************************************
 */
function classAdd(oObject, sClass) {
	if(oObject && !classMatch(oObject, sClass)) {
		// Prepend the new class to the result of removing any initial whitespace
		oObject.className = sClass + oObject.className.replace(/^\s*(.*)$/, " $1");
	}
}

function classDel(oObject, sClass) {
	var aMatches = classMatch(oObject, sClass);
	if(aMatches) {
		// Combine and remove whitespace
		oObject.className = new String(aMatches[1] + aMatches[ aMatches.length - 1 ]).replace(/^\s*(.*)\s*$/, "$1");
	}
}

function classExchange(oObject, sOldClass, sNewClass) {
	classDel(oObject, sOldClass);
	classAdd(oObject, sNewClass);
}

/****************************************************************
 * Array.push() Prototypes
 * Add any missing ability to push something onto the end of an array
 ****************************************************************
 */
if(!Array.prototype.push) {
	Array.prototype.push = function( mNewEntry ) {
		this[ this.length++ ] = mNewEntry;
	}
}

/****************************************************************
 * On load, hide all subsequent tabs and all the headings
 ****************************************************************
 */
window.onload = function() {
	if(document.getElementsByTagName) {

		// Accumulate a list of all level-3 headings
		var aoHeadings = document.getElementsByTagName('H3');
		for(var iHeading = 0; iHeading < aoHeadings.length; iHeading++) {
			var oHeading = aoHeadings[ iHeading ];

			// Hide tab-titles
			if(classMatch(oHeading, 'tab_title')) {
				classAdd(oHeading, 'hidden');
			}
		}

		// Accumulate a list of all divs
		var aoDivs = document.getElementsByTagName('DIV');
		for(var iDiv = 0; iDiv < aoDivs.length; iDiv++) {
			var oDiv = aoDivs[ iDiv ];

			// Look for tabs
			if(classMatch(oDiv, 'tab_body')) {

				// Look for a matching heading
				oDiv.oTabHeading = document.getElementById(oDiv.id +'_heading')

				// Add the tab to the list
				aoTabs.push(oDiv);

				// If it's the first tab, turn the heading on
				if(aoTabs.length == 1) {
					classAdd(oDiv.oTabHeading,	'tab_heading_on');

				// Otherwise, hide the tab
				} else {
					classAdd(oDiv,				'hidden');
				}
			}
		}
	}

//	alert(aoHeadings.length 	+' heading(s) found\n'+
//		  aoTabs.length			+' tab(s) found');

	// Call any existing on-load function
	if(fOldOnLoad) {
		fOldOnLoad();
	}
}

/****************************************************************
 * Tab-tastic
 ****************************************************************
 */
function showTab(elementID) {

	// Process all the tabs
	for(var iTab = 0; iTab < aoTabs.length; iTab++) {
		var oTab = aoTabs[ iTab ];

		// Show or hide the tab and highlight the heading
		if(oTab.id == elementID) {
			classAdd(oTab.oTabHeading,	'tab_heading_on');
			classDel(oTab,				'hidden');
		} else {
			classDel(oTab.oTabHeading,	'tab_heading_on');
			classAdd(oTab,				'hidden');
		}
	}

	// Return false, to stop event-propagation (ie link following)
	return(false);
}
