/*
 * Cascading Nav for Strict Doctypes
 * Copyright 2005, Brian Sage, http://sagehome.com/brian
 * Not for use without written permission. If you want to use the code you can ask, but don't rip off my work.
 *
 * DOCTYPE compliance: HTML 4.01 Strict.
 * Compatability:
 *   HTML structure works in all browsers.
 *   DHTML works in DOM-compatable only.
 *   NOTE: Special event handler exceptions are included for diferences in FFox 1.0, IE6, and Safari 1.0, but they all work--including Opera 7.
 *
 * Usage: Put this in your document, and that's it. JS does the rest. It even supports multiple UL.top_nav_cascading on the same page.
 
	<ul class="top_nav_cascading">
		<li><a href="#"><img src="../../../_includes/o.gif" alt="">Home Page</a>
		<li><a href="#"><img src="../../../_includes/o.gif" alt="">Customer Service</a>
			<ul>
				<li><a href="#"><img src="../../../_includes/o.gif" alt="">Current Customers</a>
			</ul>
		</li>
	</ul>

 *
 * Debug: Put the following in the document for handy-dandy debug output:
 
	<form name="debug" id="debug" action="#">
	<p><textarea cols="23" rows="12" name="debugoutput" id="debugoutput"></textarea></p>
	</form>

 *
 */
 
/********************************
 Define some global variables
 that make all these crazy
 things work
********************************/
/*
var documentRoot = './';
var graphicsRoot = documentRoot + '_graphics/';
*/

var casnavOpenArray = new Array();
var casnavNodeImg = new Image();
casnavNodeImg.src = graphicsRoot + 'arrow_right.gif';
var dbo;



// Makes all <UL.nav> structures in the document clickable and "expand" to display full tree to <a.acive>
function casnavInit()
{
	if (document.getElementsByTagName && document.getElementById)
	{

		if (document.getElementById('debugoutput'))
		{
			dbo = document.getElementById('debugoutput'); // debug output
		}
		else
		{
			dbo = new Array();
		}

		// set the onclick cascading action for '.nav's
		// loop throught all <UL>s in the document to find '.nav's
		for (var i = 0; i < document.getElementsByTagName('UL').length; i++) 
		{
			var el = document.getElementsByTagName('UL').item(i);
			if (el.className == 'top_nav_cascading')
			{
				//dbo.value += ("found UL tag with className == top_nav_cascading\n");
				el.onmouseover = casnavOver;
					//dbo.value += ("	UL.top_nav_cascading onmouseover = casnavOver\n");
				el.onmouseout = casnavOut;
					//dbo.value += ("	UL.top_nav_cascading onmouseout = casnavOut\n");
			}
		}

		// switch  background graphics of <A> tags that are in UL.top_nav_cascading LI tags with daughters
		//dbo.value += ("found "+document.getElementsByTagName('A').length+" A tags\n");
		for (var i = 0; i < document.getElementsByTagName('A').length; i++)
		{
			var el = document.getElementsByTagName('A').item(i);
			if (el.parentNode.childNodes.length >= 3)
			{
				if (el.parentNode.childNodes[2].nodeName == 'UL')
				{
					//dbo.value += "	Found matching node structure at A tag #"+ i +"\n";

					//dbo.value += "	vvvvvvv Testing for className == 'top_nav_cascading' somewhere in parent string."+"\n";
					if (testAllParentsFor(el, "className == 'top_nav_cascading'"))
					{
						//dbo.value += "		UL.top_nav_cascading TRUE"+"\n";
						//dbo.value += "		If not a top level link...";
						if (el.parentNode.parentNode.className != 'top_nav_cascading')
						{
							//dbo.value += " switch className to 'casnav_hasdaughter'\n";
							el.className = 'casnav_hasdaughter';
						}
						else
						{
							//dbo.value += " Bah, forget it!\n";
						}
					}
					else
					{
						//dbo.value += "		UL.top_nav_cascading FALSE"+"\n";
					}
					//dbo.value += "	^^^^^^^ Finished testing for in parent string."+"\n";
				}
			}


			var el = null;
		}
	}
}
window.onload = casnavInit;




function testAllParentsFor()
{
	if (arguments.length >= 1)
	{
		var el = arguments[0];
		dbo.value += "testAllParentsFor( ";
		for (var i = 0; i < arguments.length; i++)
		{
			dbo.value += arguments[i] +", ";
		}
		dbo.value += ")\n";

		
		var theParentTag = el.parentNode;
		while ((theParentTag.nodeName == 'LI') || (theParentTag.nodeName == 'UL'))
		{
			dbo.value += "theParentTag.nodeName = " + theParentTag.nodeName + "\n";
			if ((theParentTag.nodeName == 'UL') && (theParentTag.className == 'top_nav_cascading'))
			{
				dbo.value += "UL.top_nav_cascading found!"+"\n";
				return true;
			}
			theParentTag = theParentTag.parentNode;
		}


		return false;
	}
	else
	{
		return false;
	}
}


var casnavOverObject = null;
function casnavOver(e, calledFromFunc)
{
	dbo.value = "casnavOver()\n";
	
	// kill the master timer on mouse over.
	clearTimeout(casnavOutTimeout);
	
	// BEGIN create the var targ for handling the argument|obejct e
	var targ;
	if (1 == calledFromFunc) // if this was called from a function...
	{	// ...make var targ out of passed object
		dbo.value += ("	calledFromFunc == " + calledFromFunc + "\n"); // Debug output: We're inside!
		targ = e;
	}
	else
	{	// ...make var targ out of different browser event handling models
		dbo.value += ("	calledFromFunc == " + calledFromFunc + "\n"); // Debug output: We're inside!
		if (!e) var e = window.event;                  // for IE's event model
		if (e.target) targ = e.target;                 // for W3C/Moz Event model
		else if (e.srcElement) targ = e.srcElement;    // also for IE's event model
		if (targ.nodeType == 3)                        // defeat Safari bug (thanks, quirksmode.org)
		targ = targ.parentNode;                        // realize the target node, itself
	}
	dbo.value += "targ.nodeName = " + targ.nodeName + "\n";


	// Manipulate an array of which branches are open, so the closings can be tracked.

	// 	How deep is the current mouse over?
		var theParentTag = targ.parentNode;
		var theParentTagCounter = 0;
		var whileEsc = 0;
		while (((theParentTag.nodeName == 'LI') || (theParentTag.nodeName == 'UL')) && (whileEsc != 1))
		{
			if ((theParentTag.nodeName == 'UL') && (theParentTag.className == 'top_nav_cascading'))
			{
				whileEsc = 1;
			}
			if (theParentTag.nodeName == 'UL')
			{
				dbo.value += "count="+theParentTagCounter+"\n";
				theParentTagCounter++;
			}
			theParentTag = theParentTag.parentNode;
		}
		dbo.value += "mouse over at level " + (theParentTagCounter - 1) + "\n";

	
		// If the mouse-over is, indeed an A tag, and the level is shallower than the open array length...
		dbo.value += "Open array length = " + casnavOpenArray.length + "\n";
		if ( (casnavOpenArray.length >= theParentTagCounter) && (targ.tagName == 'A') )
		{
			// ... and the current mouse over is not active ...
			if ( (targ.parentNode.childNodes[2] != casnavOpenArray[ (theParentTagCounter - 1) ]))
			{
				// ...close any deeper levels.
				for (var i = casnavOpenArray.length; i >= (theParentTagCounter-1); i--)
				{
					dbo.value += "casnavOpenArray.length = " + casnavOpenArray.length + ", theParentTagCounter = " + theParentTagCounter + "\n";
					changeElementVisibility( casnavOpenArray[i], 'hide');
				}
			}
		}
	

	//	If there is a child UL...
	if ((targ.nodeName == 'A') && (targ.parentNode.childNodes.length >= 3))
	{
		if (targ.parentNode.childNodes[2].nodeName == 'UL')
		{
			//	open the current mouse-over child UL...
			changeElementVisibility( targ.parentNode.childNodes[2], 'show');

			//	...and set the array to the current location.
			casnavOpenArray[ (theParentTagCounter - 1) ] = targ.parentNode.childNodes[2];
			
		}
	}
	
	dboArray( casnavOpenArray );
	return true;
}



var casnavOutTimeout = null;
function casnavOut(e, calledFromFunc)
{
	dbo.value += "casnavOut()\n";
	
	// BEGIN create the var targ for handling the argument|obejct e
	var targ;
	if (1 == calledFromFunc)
	{
		targ = e;
	}
	else
	{
		if (!e) var e = window.event;                  // for IE's event model
		if (e.target) targ = e.target;                 // for W3C/Moz Event model
		else if (e.srcElement) targ = e.srcElement;    // also for IE's event model
		if (targ.nodeType == 3)                        // defeat Safari bug (thanks, quirksmode.org)
		targ = targ.parentNode;                        // realize the target node, itself
	}
	

	if ((targ.nodeName == 'A') && (targ.parentNode.childNodes.length >= 3))
	{
		if (targ.parentNode.childNodes[2].nodeName == 'UL')
		{
			// set a timer that will hide the current nav Open Array.
		}
	}
	
	// Now that I think about it, the above doesn't matter, so we're just gonna set the array killer timer if this function gets called.
	casnavOutTimeout = setTimeout('casnavCloseall()', 500);

	return true;
}




function casnavCloseall()
{
	dbo.value = "casnavCloseall() :\n";
	for (var i = (casnavOpenArray.length - 1); i >= 0; i--)
	{
		changeElementVisibility( casnavOpenArray[i], 'hide');
		dbo.value += "	closed level " + i + "\n";
	}
}




// Usage: changeElementVisibility(targ, ['show'|'hide'|'swap']);
function changeElementVisibility(targ, doThis)
{
	if ( (document.getElementById) && (targ != null) )
	{
		// take care of miscelaneous doThises... (1)
		if ( (doThis != 'show') && (doThis != 'hide') )
		{
			doThis = (targ.style.visibility == 'visible') ? 'hide' : 'show';
		}

		// (1) ...then do the action
		targ.style.visibility = (doThis == 'show') ? 'visible' : 'hidden';
	}
}




function dboArray( gimmeAnArray )
{
	dbo.value += "dboArray() :\n";
	dbo.value += "	gimmeAnArray[" + gimmeAnArray[0] + "]";
	for (var i = 1; i < gimmeAnArray.length; i++)
	{
		dbo.value += ".gimmeAnArray[" + gimmeAnArray[i] + "]";
	}
	dbo.value += "\n";
}

