function startBJCtabs()
{
	// Get an array of all the SPAN elements in the document
	var spanNodes = document.getElementsByTagName("span");

	// For each SPAN element in the document...
	for (var i=0; i < spanNodes.length; i++)
	{
		// If it is of class BJCtabs, create a BJCtabSet for it
		if (spanNodes[i].className == "BJCtabs")
		{
			// If we don't yet have an array for BJCtabSets, create one
			if (!window.document.BJCtabs)
				window.document.BJCtabs = new Array();
			// Create the new BJCtabSet
			var index = window.document.BJCtabs.length;
			window.document.BJCtabs[index] = new BJCtabSet(spanNodes[i], index);
		}
	}
}

function BJCtabSet(spanNode, index)
{
	// Set the default parameters
	this.setDefaultBJCtabParameters = setDefaultBJCtabParameters;
	this.setDefaultBJCtabParameters(index);

	// Read the parameters from the SPAN tag
	this.readParameters = readBJCtabParameters;
	this.readParameters(spanNode);

	// Setup BJCtabImagesLoaded method
	this.BJCtabImagesLoaded = BJCtabImagesLoaded;

	// Read in the appropriate images, and create ties to the DIV elements if they exist
	this.setupImagesAndDivs = setupBJCtabImagesAndDivs;
	this.setupImagesAndDivs();

	// Build a document fragment for the tab set
	this.buildDocumentFragment = buildBJCdocumentFragment;
	var docFragment = this.buildDocumentFragment();

	// Replace the SPAN element with the new BJCtabSet document fragment
	spanNode.parentNode.replaceChild(docFragment,spanNode);

	// Switch all the images for the tabs based on the state of each tab
	this.setAllImages = BJCsetAllImages;
	this.setAllImages();

	// Set a timeout to display the tabs in a second just in case there is a missing image
	this.timeout = self.setTimeout('completeBJCtabs(' + this.index + ')', 1000);
}

function setDefaultBJCtabParameters(index)
{
	var tabSet = this;

	// Set an index to this tabSet's position in the BJCtabs array
	tabSet.index = index;

	// Set a few base parameter values
	tabSet.maxImageHeight = 0;
	tabSet.maxTabRowLength = 0;

	// Create imageSuffixes object and temporary pointer to it
	tabSet.imageSuffixes = new Object();
	var suffixes = tabSet.imageSuffixes;

	// Setup default imageSuffixes.  These may be overwritten by the parameters in the SPAN
	suffixes.active = ".gif";
	suffixes.selected = "_on.gif";
	suffixes.inactive = ".gif";
	suffixes.over = "_on.gif";

	// Setup default endcap
	tabSet.endcap = "verticalLine.gif";

	// Setup default id.  This may be overwritten by the parameters in the SPAN
	tabSet.idStr = "tabs";

	// Setup default class.  This may be overwritten by the parameters in the SPAN
	tabSet.className = "tabs";

	// Setup default image path.  This may be overwritten by the parameters in the SPAN
	tabSet.imagePath = "/uploadedimages/BJC_HealthCare/Common_Elements/Tabs/";

	// Setup spacer image
	tabSet.spacerImageName = "spacer.gif";

	// Setup default div and image prefixes.  These may be overwritten by the parameters in the SPAN
	tabSet.divPrefix = "tab_pg_";
	tabSet.imagePrefix = "tab_";

	// Set the default width for the tabSet to auto
	tabSet.width = "auto";
}

function readBJCtabParameters(spanNode)
{
	var tabSet = this;

	// Step through the array of child elements for this SPAN element
	var spanChildNodes = spanNode.childNodes;
	for (var i=0; i < spanChildNodes.length; i++)
	{
		// We are only interested in Text Nodes
		if (spanChildNodes[i].nodeType == 3)
		{
			// Get the data of the Text Node and check to see if it contains a colon
			var text = spanChildNodes[i].data;
			var colonPos = text.indexOf(':');
			if (colonPos > 0)
			{
				// Parse the parameter name and value
				var paramName = paramCleanup(text.substr(0,colonPos));
				var paramValue = text.substring(colonPos+1,text.length);
				if (paramValue.length > 0)
				{
					// If we have a parameter value, clean it up and deal with it
					parseBJCtabParameters(tabSet, paramName, paramCleanup(paramValue));
				}
			}
		}
	}
}

function paramCleanup(paramValue)
{
	// Eliminate extra spaces
	var temp = paramValue.replace(/\s+/g,' ');
	// Eliminate spaces after commas
	temp = temp.replace(/,\s+/g,',');
	// Trim leading and trailing blanks
	temp = temp.replace(/^\s*|\s*$/g,"");
	return temp;
}

function parseBJCtabParameters(tabSet, paramName, paramValue)
{
	switch (paramName.toLowerCase())
	{
		// New row of tabs
		case 'tabs':
			// Create tabs object for this tabSet if it doesn't yet exist
			if (!tabSet.tabs)
				tabSet.tabs = new Object();

			// Create tabLayout array for this tabSet if it doesn't yet exist
			if (!tabSet.tabLayout)
				tabSet.tabLayout = new Array();

			// Create new row in the tabLayout Array and create the array for the tabs
			var layoutRow = tabSet.tabLayout.length;
			tabSet.tabLayout[layoutRow] = new Array();

			// Create tabRowLength array for this tabSet if it doesn't yet exist
			if (!tabSet.tabRowLength)
				tabSet.tabRowLength = new Array();

			// Set tabRowLength for this row to zero
			tabSet.tabRowLength[layoutRow] = 0;

			// Parse the individual tab names
			var tabNames = paramValue.split(',');
			for (var j=0; j < tabNames.length; j++)
			{
				var name = tabNames[j];
				if (name.length > 2)
				{
					// If the name of this tab duplicates an existing tab, come up with an alternate name
					if (tabSet.tabs[name])
					{
						var k = 0;
						while (tabSet.tabs[name+k])
							{ k++; }
						name = name + k;
					}
					// Create tab object and setup temporary pointer
					tabSet.tabs[name] = new Object();
					var tab = tabSet.tabs[name];
					// Set name for the Tab
					tab.name = tabNames[j];
					// Set pointer back to the tabSet
					tab.tabSet = tabSet;
					// Place pointer into the tabLayout arrays
					var cell = tabSet.tabLayout[layoutRow].length;
					tabSet.tabLayout[layoutRow][cell] = tab;
				}
			}
			break;

		// Load image Suffix parameters
		case 'imagesuffixes':
			// Parse the individual suffixes
			var suffixList = paramValue.split(',');

			// Set all suffix parameters - if all four weren't supplied, default back to previous parameter
			suffixes.inactive = suffixList[0];
			suffixes.active = suffixList[0];
			suffixes.selected = suffixList[0];
			suffixes.over = suffixList[0];
			if ((suffixList.length > 1) && (suffixList[1].length > 0 ))
			{ 
				suffixes.active = suffixList[1];
				suffixes.selected = suffixList[1];
				suffixes.over = suffixList[1];
			}
			if ((suffixList.length > 2) && (suffixList[2].length > 0 ))
			{ 
				suffixes.selected = suffixList[2];
				suffixes.over = suffixList[2];
			}
			if ((suffixList.length > 3) && (suffixList[3].length > 0 ))
			{ 
				suffixes.over = suffixList[3];
			}
			break;

		// Set id parameter
		case 'id':
			tabSet.idStr = paramValue;
			break;

		// Set class parameter
		case 'class':
			tabSet.className = paramValue;
			break;

		// Set width parameter
		case 'width':
			if (isNaN(paramValue))
			{
				loc = paramValue.indexOf('px');
				if (loc > 0)
				{
					val = paramValue.substr(0,loc);
					if (! isNaN(val))
					{
						tabSet.widthMeasure = 'px';
						tabSet.width = val;
					}									
				}
				loc = paramValue.indexOf('%');
				if (loc > 0)
				{
					val = paramValue.substr(0,loc);
					if (! isNaN(val))
					{
						tabSet.widthMeasure = '%';
						tabSet.width = val;
					}									
				}
				if (paramValue == 'style')
					tabSet.width = 'style';
			}
			else
			{
				tabSet.width = paramValue;
				if (paramValue <= 100)
					tabSet.widthMeasure = '%';
				else
					tabSet.widthMeasure = 'px';
			}
			break;

		// Set all other parameters
		default:
			tabSet[paramName] = paramValue;
			break;
	}
}

function setupBJCtabImagesAndDivs()
{
	var tabSet = this;

	// Set constants for tabStates
	tabSet.tabStates = new Object();
	var state = tabSet.tabStates;
	state.inactive = 0;
	state.active = 1;
	state.selected = 2;

	// Get an array of all DIV elements
	var divs = document.getElementsByTagName("div");

	// If an intro parameter was set, assign the div for the intro
	if (tabSet.introDiv)
	{
		// Build intro element
		tabSet.intro = new Object();
		tabSet.intro.name = tabSet.introDiv;
		tabSet.intro.tabSet = tabSet;

		// Assign div to the intro element
		assignBJCDivs(tabSet.intro, divs);
	}

	// For each tab in the tabSet...
	for (var tabName in tabSet.tabs)
	{
		var tab = tabSet.tabs[tabName];

		// Set the switchState method for the tab
		tab.switchState = BJCswitchTabState;

		// Set the loadImages methods for the image and call it
		tab.loadTabImages = BJCloadTabImages;
		tab.loadTabImages();

		// Default the tab to inactive
		tab.state = state.inactive;

		// Assign divs to the tab
		assignBJCDivs(tab, divs);
	}

	// If an intro Div exists, skip the default tab setting
	if ((tabSet.intro) && (tabSet.intro.div))
		tabSet.intro.state = state.selected;
	else
	{
		// If a defaultTab parameter was set, and there is a tab with that name that isn't inactive then
		//      set this tab to selected
		if ((tabSet.defaultTab) && (tabSet.tabs[tabSet.defaultTab]) && (tabSet.tabs[tabSet.defaultTab].state != state.inactive))
				tabSet.tabs[tabSet.defaultTab].state = state.selected;
		else
		{
			tabSet.defaultTab = "";
			for (var tabName in tabSet.tabs)
			{
				var tab = tabSet.tabs[tabName];
				if ((tabSet.defaultTab == "") && (tab.state != state.inactive))
				{
					tabSet.defaultTab = tab.name;
					tab.state = state.selected;
				}
			}
		}				
	}
}

function assignBJCDivs(elem, divs)
{
	var tabSet = elem.tabSet;
	var state = tabSet.tabStates;

	// Step through all the DIV elements
	for (i=1; i < divs.length; i++)
	{
		// If we haven't assigned a DIV to this tab, and the names match, 
		//      and this DIV hasn't already been assigned to another tab then
		//      assign it to this tab, mark the DIV as taken, and set the tab to active
		var div = divs[i];
		if ((!elem.div) && (div.id == tabSet.divPrefix+elem.name) && (!div.taken))
		{
			elem.div = div;
			div.taken = true;
			elem.state = state.active;
		}
	}
}

function buildBJCdocumentFragment()
{
	var tabSet = this;

	// Create an empty document fragment
	var docFragment = document.createDocumentFragment(); 

	// Create a DIV element
	var div = document.createElement("div");
	// If an id parameter was passed, set the id for the DIV
	if (tabSet.idStr)
		div.setAttribute("id", tabSet.idStr);
	// If a class parameter was passed, set the class for the DIV
	if (tabSet.className)
		div.className = tabSet.className;
	// Hide the DIV
	div.style.display = "none";
	// Set a pointer from the tabSet to its DIV
	tabSet.div = div;
	// Add the DIV to the document fragment
	docFragment.appendChild(div);

	// For each row in the tabLayout...
	for (i=0; i < tabSet.tabLayout.length; i++)
	{
		// Create a TABLE element
		var table = document.createElement("table");
		// If a class parameter was passed, set the class for the TABLE
		if (tabSet.className)
			table.className = tabSet.className+"_table";
		// Add the TABLE to the DIV
		div.appendChild(table);
		// Create a pointer to the table
		tabSet.table = table;

		// Create a TBODY element and add it to the TABLE
		var tbody = document.createElement("tbody");
		table.appendChild(tbody);

		// Create a TR element and add it to TBODY
		var row = document.createElement("tr");
		tbody.appendChild(row);

		// Create a TD element and add it to the TR
		var cell = document.createElement("td");
		row.appendChild(cell);

		// For each tab in this row...
		for (var j=0; j < tabSet.tabLayout[i].length; j++)
		{
			var tab = tabSet.tabLayout[i][j];
			// Create an IMG element and add it to the TD cell
			var img = document.createElement("img");
			cell.appendChild(img);

			// Add the image to the Tab object and give it a pointer back to the Tab
			tab.image = img;
			img.tab = tab;
			img.tabSet = tabSet;

			// Setup the onload event for the image
			img.onload = imageLoadedEvent;

			// Set the event handlers for the image
			img.onclick = BJCprocessClick;
			img.onmouseover = BJCprocessOver;
			img.onmouseout = BJCprocessOut;

			// If these tabs are in the last row...
			if (i == tabSet.tabLayout.length-1)
			{
				// Set the notSelected class for all images in the last row
				img.className = tabSet.className + "_lastRow_notSelected";
				// Set a pointer to the last tab
				tabSet.lastTab = tab;
			}
		}

		// If this is the last row...
		if (i == tabSet.tabLayout.length-1)
		{
			// Create another TD element for the last cell in last row
			var cell2 = document.createElement("td");
			row.appendChild(cell2);
			if (tabSet.className)
				cell2.className = tabSet.className+"_table_lastCell";

			var img = document.createElement("img");
			cell2.appendChild(img);
			img.style.verticalAlign = "bottom";
			img.style.width = '0px';
			img.style.height = '0px';
			img.className = tabSet.className+"_lastRow_notSelected";
			tabSet.spacerImage = img;
			img.tabSet = tabSet;
			img.src = tabSet.imagePath + tabSet.spacerImageName;

			// Set a pointer to the last cell
			tabSet.lastCell = cell2;
		}
		// Otherwise, set colSpan for cell
		else
			cell.colSpan="2";

		// Add the endcap image at the end of the row
		var img = document.createElement("img");
		img.tabSet = tabSet;
		tabSet.endcapImg = img;
		img.onload = imageLoadedEvent;
		img.src = tabSet.imagePath + tabSet.imagePrefix + tabSet.endcap;
		cell.appendChild(img);		
	}

	// Create a DIV for all the content DIVs and append it to the tabSet DIV
	var contentDiv = document.createElement("div");
	div.appendChild(contentDiv);
	tabSet.contentDiv = contentDiv;
	// If a class parameter was passed, set the class for this DIV
	if (tabSet.className)
		contentDiv.className = tabSet.className+"_contentDiv";

	// Step through the tabs...
	for (var tabName in tabSet.tabs)
	{
		// If this tab has a div, move it so that it is within our content DIV
		if (tabSet.tabs[tabName].div)
			contentDiv.appendChild(tabSet.tabs[tabName].div);
	}

	// If there is an intro Div add it to the our contentDiv
	if ((tabSet.intro) && (tabSet.intro.div))
		contentDiv.appendChild(tabSet.intro.div);

	// Add a spacer image to use as a width reference
	var img = document.createElement("img");
	img.tabSet = tabSet;
	img.src = tabSet.imagePath + tabSet.spacerImageName;
	img.height = '1px';
	img.width = '100%';
	div.appendChild(img);		
	tabSet.referenceImage = img;

	// Return the document fragment	
	return docFragment;
}

function BJCloadTabImages()
{
	// Set pointers
	var tab = this;
	var tabSet = tab.tabSet;
	// Step through all of the suffixes
	for (var suffix in tabSet.imageSuffixes)
	{
		// Create an image for this suffix and set it to the appropriate graphic
		tab[suffix] = new Image();
		tab[suffix].tab = tab;
		tab[suffix].tabSet = tabSet;
		tab[suffix].src = tabSet.imagePath + tabSet.imagePrefix + tab.name + tabSet.imageSuffixes[suffix];
	}
}

function imageLoadedEvent()
{
	var tabSet = this.tabSet;

	if (tabSet.BJCtabImagesLoaded())
		completeBJCtabs(tabSet.index);
}

function BJCtabImagesLoaded()
{
	var tabSet = this;

	// Check to see if the endcap image has loaded
	if ((tabSet.endcapImg) && (!tabSet.endcapImg.complete))
		return false;

	// For each tab in the tabSet...
	for (var tabName in tabSet.tabs)
	{
		var tab = tabSet.tabs[tabName];

		// Check to see if the image has completed loading
		if ((tab.image) && (!tab.image.complete))
			return false;
	}
	return true;
}

function completeBJCtabs(index)
{
	// Get a pointer to the tabSet based on its index
	tabSet = window.document.BJCtabs[index];

	// If there is a timeout, clear it
	if ((tabSet.timeout) && (tabSet.timeout != 0))
	{
		self.clearTimeout(tabSet.timeout);
		tabSet.timeout = 0;
	}
		
	// If there are images still Loading, try to complete again in 5 seconds
	// otherwise, clear the timeout
	if (!tabSet.BJCtabImagesLoaded())
		tabSet.timeout = self.setTimeout('completeBJCtabs(' + tabSet.index + ')', 5000);

	// Display the tabSet and then adjust widths as needed
	tabSet.div.style.display = "";

	// Start by setting the spacer image to the width of it's cell
	tabSet.spacerImage.style.width = tabSet.lastCell.offsetWidth + 'px';

	// Set the height of the space image
	tabSet.spacerImage.style.height = tabSet.lastTab.image.height + 'px';

	// If the width is set to auto, set the width of the contentDiv to match the width of the tabs table
	if (tabSet.width == 'auto')
		BJCsetElementWidth(tabSet.contentDiv, tabSet.table.offsetWidth);
	else
	{
		// If width was set by percentage or pixels, set the width of the contentDiv to match
		if ((tabSet.widthMeasure) && (tabSet.widthMeasure == '%'))
			BJCsetElementWidth(tabSet.contentDiv, (tabSet.div.offsetWidth/100*tabSet.width));
		if ((tabSet.widthMeasure) && (tabSet.widthMeasure == 'px'))
			BJCsetElementWidth(tabSet.contentDiv, tabSet.width);

		// Check the width of the contentDiv compared to the width of the tabs table
		wid = tabSet.contentDiv.offsetWidth - (tabSet.table.offsetWidth - tabSet.spacerImage.width);

		// If the contentDiv is narrower than the tabs table, widen the contentDiv
		// Otherwise, set the width of the spacerImage to widen the table to match the width of the ContentDiv
		if (wid < 0)
			BJCsetElementWidth(tabSet.contentDiv, tabSet.contentDiv.offsetWidth - wid);
		else
			tabSet.spacerImage.style.width = wid + 'px';
	}
}

function BJCsetElementWidth(elem,wid)
{
	// Track the width of the element before setting the width
	var origwid = elem.style.width;

	// Track the width of the entire tabSet div
	var origDivWidth = tabSet.div.offsetWidth;

	// Set the width of the element
	elem.style.width = wid+'px';

	// Check the resulting width
	var currwid = elem.offsetWidth;

	// If there is a difference between the desired width and the resulting width, adjust to the width of the tabs
	if (currwid != wid)
	{
		var adjustedWidth = (wid - (currwid - wid));
		if (adjustedWidth > 0)
		{
			elem.style.width = adjustedWidth + 'px';

			// If setting this width and adjusting it threw off the width of the outer div, adjust
			var currDivWidth = tabSet.div.offsetWidth;
			if (currDivWidth > origDivWidth)
			{
				tabSet.div.style.width = adjustedWidth + 'px';
			}
		}
	}
}

function BJCsetAllImages()
{
	var state = this.tabStates;

	// If the intro is selected, display it, otherwise hide it
	if ((this.intro) && (this.intro.div))
		if (this.intro.state == state.selected)
		{
			this.intro.div.style.display = "";
			this.intro.state = state.inactive;
		}
		else
			this.intro.div.style.display = "none";

	// For each tab in the tabSet
	for (var tabName in this.tabs)
	{
		var tab = this.tabs[tabName];
		// Check the state of the tab...
		switch(tab.state)
		{
			case state.inactive:
				// Set the inactive graphic
				tab.image.src = tab.inactive.src;
				if (tab.image.className)
					tab.image.className = this.className+"_lastRow_notSelected";
				break;
			case state.active:
				// Set the active graphic and hide the DIV
				tab.image.src = tab.active.src;
				if (tab.image.className)
					tab.image.className = this.className+"_lastRow_notSelected";
				tab.div.style.display = "none";
				break;
			case state.selected:
				// Set the selected graphic and reveal the DIV
				tab.image.src = tab.selected.src;
				if (tab.image.className)
					tab.image.className = this.className+"_lastRow_selected";
				tab.div.style.display = "";
				break;
			default:
				// For any other case, set the active graphic and hide the DIV
				tab.image.src = tab.active.src;
				if (tab.image.className)
					tab.image.className = this.className+"_lastRow_notSelected";
				tab.div.style.display = "none";
				break;
		}
	}
}

function BJCswitchTabState(newState)
{
	// If we are already in this state, do nothing
	if (this.state != newState)
	{
		var state = this.tabSet.tabStates;
		// If the new state is selected...
		if (newState == state.selected)
		{
			// Step through all the tabs and switch them from selected to active
			for (var tabName in this.tabSet.tabs)
			{
				var tab = this.tabSet.tabs[tabName];
				if (tab.state == state.selected)
					{ tab.state = state.active; }
			}
		}
		// Set the new state for this tab
		this.state = newState;
	}
}

function BJCprocessClick()
{
	var state = this.tab.tabSet.tabStates;
	// If the tab was active...
	if (this.tab.state == state.active)
	{
		// Change the state to selected
		this.tab.switchState(state.selected);
		// Set to normal cursor
		this.style.cursor = "";
	}
	// Set all Images
	this.tab.tabSet.setAllImages();
}

function BJCprocessOver()
{
	var state = this.tab.tabSet.tabStates;
	// If the tab was active...
	if (this.tab.state == state.active)
	{
		// Change to over image
		this.src = this.tab.over.src;
		// Change to hand cursor
		this.style.cursor = "pointer";
	}
	else if (this.tab.state == state.selected)
	{
		// Set to normal cursor
		this.style.cursor = "";
	}
}

function BJCprocessOut()
{
	var state = this.tab.tabSet.tabStates;
	// If the tab was active...
	if (this.tab.state == state.active)
	{
		// Change to the active image
		this.src = this.tab.active.src;
		// Set to normal cursor
		this.style.cursor = "";
	}
}
