/****************************

 JavaScript for DHTML Colapsing Navigation
 Version:
 	0.3 Beta 1, Aug 25, 2005
 Copyright:
 	2005, Brian Sage, http://sagehome.com/brian. Not for use without _written_
	permission. If you want to use it, ask, but don't rip off my work.

 Compatability:
	DOCTYPE compliance: HTML 4.01 Strict.
 	HTML structure works in all browsers.
	DHTML works in browsers that return true the following:
		if (document.getElementsByTagName && document.createElement && document.insertBefore)
	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+,
		see lines 100 through 108 for this dirty hack.

 Use:
	<script type="text/javascript" src="nav_collapsing.js"></script>
 	Note: This file must be included after all <ul.nav_collapsing> tags in
		document have been closed.
	
 	Document must contain a <ul class="nav_collapsing"> with the basic HTML structure:
		<ul class="nav_collapsing">
			<li><a>Nav Item 1</a></li>
			<li><a>Nav Item 2</a>
				<ul>
					<li><a class="active">Daughter Nav Item 1</a></li>
				</ul>
			</li>
			<li><a>Nav Item 3</a></li>
		</ul>
	
	Transforms the basic structure above into:
		<ul class="nav_collapsing">
			<li><a><img class="navNode" onclick="colnavActions.mouseclick(e)">Nav Item 1</a></li>
			<li><a><img class="navNode" onclick="colnavActions.mouseclick(e)">Nav Item 2</a>
				<ul>
					<li><a><img class="navNode" onclick="colnavActions.mouseclick(e)">Daughter Nav Item 1</a></li>
				</ul>
			</li>
			<li><a><img class="navNode" onclick="colnavActions.mouseclick(e)">Nav Item 3</a></li>
		</ul>
	
	Basic structure bay be modified anyway you see fit, as long as the
		parenting order of tags remains the same:
		<div><ul class="nav_collapsing">
			<li><img /><div><a href="#"><p><span><img /><img /></span></p></a></div>
				<span><div><ul>
					<li><p><a><img /></a></p></li>
				</ul></div></span>
			</li>
		</ul></div>
	

 Returns: n/a
****************************/


/****************************
 Global variables
****************************/
if (!documentRoot) var documentRoot = '/';
if (!graphicsRoot) var graphicsRoot = documentRoot + '_graphics/';
if (!dbo) var dbo = new Array();


// Required Collapsing Nav Parameters:
var colnavs = new Array();
var colnavActions = new Array();

var colnavParams = new Array();
colnavParams.className = 'nav_collapsing';
colnavParams.nodeImgs = new Array();

colnavParams.nodeImgs.noneState = new Image();
colnavParams.nodeImgs.noneState.src = graphicsRoot + 'nav_node_none.gif';
colnavParams.nodeImgs.noneState.className = 'navNode';
colnavParams.nodeImgs.noneState.title = 'Click arrows to show and hide child pages.';
colnavParams.nodeImgs.noneState.alt = '';

colnavParams.nodeImgs.openState = new Image();
colnavParams.nodeImgs.openState.src = graphicsRoot + 'nav_node_open.gif';

colnavParams.nodeImgs.closedState = new Image();
colnavParams.nodeImgs.closedState.src = graphicsRoot + 'nav_node_closed.gif';

colnavParams.nodeImgs.activeState = new Image();
colnavParams.nodeImgs.activeState.className = 'active';


// Event functions:
colnavActions.mouseclick = function(e, calledFromFunc)
{
	dbo.value = 'colnavActions.mouseclick(e, calledFromFunc)\n	e=' + e + '\n	calledFromFunc=' + calledFromFunc +'\n';
	var targ = (1 == calledFromFunc) ? e : solveForE(e);

	// get an array of parent tag references by tag name
	var parentNodesByTagName = getParentNodesByTagName(targ, 'LI');

	// if there is a parent <li>...
	dbo.value += ("parentNodesByTagName.length == " + parentNodesByTagName.length + "\n");
	if (parentNodesByTagName.length > 0)
	{
		// Check for sibling <ul>s, because some clicked nav nodes will not have daughters
		if (parentNodesByTagName[0].getElementsByTagName('ul').length > 0)
		{
			// switch the node image
			colnavActions.changeNodeImg (targ, 'toggle');
			// switch the daughter <ul> visibility
			colnavActions.changeElementDisplay ( parentNodesByTagName[0].getElementsByTagName('ul').item(0), 'toggle');
		}
	}

	// Return false for all image clicks, so the link isn't fired
	return false;
}

// Worker bee functions:
// Usage: colnavActions.changeNodeImg(targ, ['open'|'close'|'toggle']);
colnavActions.changeNodeImg = function(targ, doThis)
{
	// take care of miscelaneous doThises (assuming the default state is closed or null)...
	if ( (doThis != 'open') && (doThis != 'close') )
	{
		doThis = (targ.src.indexOf(colnavParams.nodeImgs.openState.src) != -1) ? 'close' : 'open';
	}

	// ...then do the action
	targ.src = (doThis == 'open') ? colnavParams.nodeImgs.openState.src : colnavParams.nodeImgs.closedState.src;
}

// Usage: colnavActions.changeElementDisplay(targ, ['show'|'hide'|'swap']);
colnavActions.changeElementDisplay = function(targ, doThis)
{
	// take care of miscelaneous doThises (assuming the default state is hidden)...
	if ( (doThis != 'show') && (doThis != 'hide') )
	{
		doThis = (targ.style.display == 'block') ? 'hide' : 'show';
	}

	// ...then do the action
	targ.style.display = (doThis == 'show') ? 'block' : 'none';
}

// Variable creation/manipulation functions:
// Usage: getParentNodesByTagName( starting document element reference, 'HTML tag (uppercase required)')
// Returns: Array of parent node references where nodeName == argument tag
function getParentNodesByTagName(targ, tag)
{
	var parentNodesByTagName = new Array();
	var loopPoint = targ;
	while (loopPoint.nodeName != 'BODY')
	{
		if (loopPoint.nodeName == tag) parentNodesByTagName.push(loopPoint);
		loopPoint = loopPoint.parentNode;
	}
	
	return parentNodesByTagName;
}

// Usage: solveForE( e )
// Returns: var targ, as different browsers can handle it
function solveForE(e)
{
	var targ;

	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

	return targ;
}


// Initialize colnavs in document:
// Make an array of all colnavs in the document for easy reference
if (document.getElementsByTagName && document.createElement && document.insertBefore)
{
	dbo.value += 'searching for colnavs:\n';
	for (var i = 0; i < document.getElementsByTagName('ul').length; i++)
	{
		if (document.getElementsByTagName('ul').item(i).className == colnavParams.className)
		{
			dbo.value += '	colnav found\n';
			colnavs.push( document.getElementsByTagName('ul').item(i) );
		}
	}
	dbo.value += '	total colnavs found:' + colnavs.length + '\n';
}

// Parse through each colnav and do something
for (var i = 0; i < colnavs.length; i++)
{
	dbo.value += 'setting parameters in colnav['+i+']\n';
	dbo.value += '	searching for <a>s: ' + colnavs[i].getElementsByTagName("a").length + ' found\n';
	
	// set the colnav to invisible while making changes
	colnavs[i].style.visibility = 'hidden';
	dbo.value += '	colnav['+i+'] visibility set to '+colnavs[i].style.visibility+'\n';
	
	// for each <a>, add an img.navNode for collapsing features
	for (var j = 0; j < colnavs[i].getElementsByTagName("a").length; j++)
	{
		// set the parameters for the node image object
		colnavParams.nodeImg = document.createElement('img');
		colnavParams.nodeImg.src = colnavParams.nodeImgs.noneState.src;
		colnavParams.nodeImg.className = colnavParams.nodeImgs.noneState.className;
		colnavParams.nodeImg.title = colnavParams.nodeImgs.noneState.title;
		colnavParams.nodeImg.alt = colnavParams.nodeImgs.noneState.alt;
		
		// set document event handlers for the node image object
		colnavParams.nodeImg.onclick = function (e, calledFromFunc)
		{
			colnavActions.mouseclick(e, calledFromFunc);
			// return the mouse click event as false, so the href doesn't fire
			return false;
		}

		// place the node image object within the current <a>
		colnavs[i].getElementsByTagName("a")[j].insertBefore( colnavParams.nodeImg, colnavs[i].getElementsByTagName("a")[j].childNodes[0] );
	}

	// set the state of colnavs to closed:
	//   set the state of <ul.nav_collapsing><ul>s to display: none
	for (var j = 0; j < colnavs[i].getElementsByTagName("ul").length; j++)
	{
		colnavs[i].getElementsByTagName("ul")[j].style.display = 'none';
	}

	//   set the <img src>s within <li>s with daughter <ul>s to closed
	for (var j = 0; j < colnavs[i].getElementsByTagName("img").length; j++)
	{
		if (colnavs[i].getElementsByTagName("img")[j].className == colnavParams.nodeImgs.noneState.className)
		{
			var parentNodesByTagName = getParentNodesByTagName(colnavs[i].getElementsByTagName("img")[j], 'LI');
			if (parentNodesByTagName[0].getElementsByTagName("ul").length)
			{
				colnavActions.changeNodeImg( colnavs[i].getElementsByTagName("img")[j], 'close');
			}
		}
	}

	//   set the path from <a.active>, back to <ul.nav_collapsing> to open
	for (var j = 0; j < colnavs[i].getElementsByTagName("a").length; j++)
	{
		if (colnavs[i].getElementsByTagName("a")[j].className == colnavParams.nodeImgs.activeState.className)
		{
			dbo.value += '	colnavs['+i+'].getElementsByTagName("a")['+j+'].className=' + colnavs[i].getElementsByTagName("a")[j].className + '\n';
			// set from here back to <ul.nav_collapsing> open
			var parentULNodes = getParentNodesByTagName(colnavs[i].getElementsByTagName("a")[j], 'UL');
			var parentLINodes = getParentNodesByTagName(colnavs[i].getElementsByTagName("a")[j], 'LI');
			for (var k = 0; k < parentULNodes.length; k++)
			{
				parentULNodes[k].style.display = 'block';
				if (k > 0) colnavActions.changeNodeImg( parentLINodes[k].getElementsByTagName("a")[0].getElementsByTagName("img")[0], 'open');
			}
			
			// also set daughter <ul> to open, if there is one.
			if (parentLINodes[0].getElementsByTagName("ul").length > 0)
			{
				parentLINodes[0].getElementsByTagName("ul")[0].style.display = 'block';
				colnavActions.changeNodeImg( parentLINodes[0].getElementsByTagName("a")[0].getElementsByTagName("img")[0], 'open');
			}
		}
	}

	//   set the colnav back to visible once finished making changes
	colnavs[i].style.visibility = 'visible';
	dbo.value += '	colnav['+i+'] visibility set to '+colnavs[i].style.visibility+'\n';
}





/****************************
 Loaded Announce
****************************/
dbo.value += ("nav_collapsing.js loaded!\n");