/*
	Based on Travis Beckham, 06/02/03, javascript.internet.com
	Good reference on DOM: www.w3schools.com/htmldom/default.asp
*/

// node functions //
/*
	* The entire document is a document node
	* Every HTML tag is an element node
	* The text in the HTML elements are text nodes
	* Every HTML attribute is an attribute node
	* Comments are comment nodes

	* In a node tree, the top node is called the root
	* Every node, except the root, has exactly one parent node
	* A node can have any number of children
	* A leaf is a node with no children
	* Siblings are nodes with the same parent
*/

/*
<div class="expandingMenuCategory">
	<ul id="menu">
		Economics and Cost Accounting
		<li id="module001">What It Costs to Deliver Care
			<ol id="001a">
				<li>
					<table width="480" border="0" cellspacing="0" cellpadding="0">
						<tr>
							<td><img class="edu" src="images/img_physicians.jpg" alt="Physicians" height="101" width="160" border="0">
								<b>Description:</b> Health care requires large up-front investments in physical, financial, human resource, and intellectual capital. As such, fixed costs are high, meaning that a large fraction of the health system's expenses are sunk and do not vary with the level of patient activity. This module explains how we measure costs in such environments. Our cost measures include fixed, variable, marginal, and opportunity costs. Using real data from a variety of health care settings, we show how these different cost measures inform and guide better clinical decisions.<br><br>
								<b>Objectives:</b> Participants learn basic economic measures of cost, and how to apply them to health care.<br><br>
							</td>
						</tr>
					</table>
				</li>
			</ol>
		</li>

Hierarchy: <div> <ul> text_element <li> text_element <ol> <li> <table> <tr> <td>
*/

/***** SETUP *****/

//activeMenu is the currently active link
var activeMenu = null;
var lastActiveElement = null;

//if the variable Node does not exist, create it
if (!window.Node)
{
	//alert ('Node Created');
	//object literal (key/value pairs)
	var Node = {ELEMENT_NODE : 1, TEXT_NODE : 3};
	//alert ('node0 = ' + Node['ELEMENT_NODE']);
	//alert ('node1 = ' + Node['TEXT_NODE']);
}


/***** BUILD THE MENU ANCHORS *****/

//start here
if (document.createElement)
{
	//when the page loads, execute initMenu()
	window.onload = initMenu;
}

function initMenu()
{
	//build the menu system
	var menus, menu, text, a, i;
	//array of the menu items that will explode
	//'menu' is the parent; children are the <li> elements
	menus = getChildrenByElement(document.getElementById('menu'));
	//i = 1 to kludge for IE, so first category does not get turned into a menu item
	//either way (i = 0) works in FoxPro
	for(i = 1; i < menus.length; i++)
	{
		//alert ('65');
		menu = menus[i];
		//get the text associated with the menu item
		text = getFirstChildByText(menu);
		//if (i < 3) alert ('text = ' + text.data);
		//create an anchor tag around the text associated with the menu item
		a = document.createElement('a');
		menu.replaceChild(a, text);
		a.appendChild(text);
		a.href = '#';
		//where the magic happens -- sets up the onclick event
		a.onclick = showMenu;
		//this I do not understand
		a.onfocus = function(){this.blur()};
	}
	//then we are done, and we wait for an onclick of one of the anchors (showMenu function)
}

function checkNode(node, filter)
{
	//return true if filter is null (should be 'ELEMENT_NODE' or 'TEXT_NODE'), not sure why this would be
	//or if the numeric node type is the same as the value of that Node literal (1, or 3) based on the filter key 
	//or if the text node type is the same as the name of the filter
	return (filter == null || node.nodeType == Node[filter] || node.nodeName.toUpperCase() == filter.toUpperCase());
}

function getChildrenByElement(node)
{
	//node is the name of the menu system
	var filter = 'ELEMENT_NODE';
	var result = new Array();
	//the childNodes property returns a NodeList of child nodes for the specified node
	var children = node.childNodes;
	for (var i = 0; i < children.length; i++)
	{
		//if current child node (an <li>, one of the menu items) passes, then
		//
		if (checkNode(children[i], filter))
		{
			//put the menu items into the result array
			result[result.length] = children[i];
		}
	}
	return result;
}

function getFirstChildByText(node)
{
	var filter = 'TEXT_NODE';
	var child;
	var children = node.childNodes;
	for(var i = 0; i < children.length; i++)
	{
		child = children[i];
		if (checkNode(child, filter))
		{
			return child;
		}
	}
	return null;
}


/***** EXPLODING FUNCTIONS *****/

//when a link is clicked
function showMenu()
{
	//if there is already an open menu item
	//will bypass this when the first menu item is clicked
	if (activeMenu)
	{
		//alert ('activeMenu = ' + activeMenu);
		//result: activeMenu = http://www.mdcontent.com/content/course_list.html#
		//alert ('activeMenu.className = ' + activeMenu.className);
		//result: active
		//so clear the current (soon to be previous) active menu item (change classname from active to empty string)
		activeMenu.className = '';
		//close the block immediately following the active menu item (the <ol> I assume,
		//otherwise it would be the next LI, which would not make sense)
		getNextSiblingByElement(activeMenu).style.display = 'none';
	}

	//if the currently open menu item is re-clicked
	if (this == activeMenu)
	{
		//completely clear the active menu item
		activeMenu = null;
	}
	//a different menu item was clicked
	else
	{

		//alert ('objMenuItem.innerHTML = ' + this.innerHTML);
		//alert ('objMenuItem.nodeName = ' + this.nodeName);
		//alert ('objMenuItem.nodeValue = ' + this.nodeValue);
		//alert ('objMenuItem.parentNode = ' + this.parentNode);

		//make this item active
		this.className = 'active';
		//open the block immediately following the active menu item (the <ol>)
		getNextSiblingByElement(this).style.display = 'block';
		//set activeMenu to the current object
		activeMenu = this;
	}
	return false;
}

function getNextSiblingByElement(node)
{
	//this gets the <OL> associated with the node <LI> passed in
	var filter = 'ELEMENT_NODE';
	//the nextSibling property returns the node immediately following a node (in the same tree level).
	//apparently an LI under an OL is a sibling???
	//for index starting at the next sibling
	//index going until it's not null
	//incrementing by going to the next nextSibling
	//in other words, check that the <OL> following the <LI> is not null, and check its type
	for (var sibling = node.nextSibling; sibling != null; sibling = sibling.nextSibling)
	{
		if (checkNode(sibling, filter))
		{
			return sibling;
		}
	}
	return null;
}

//finally, my function, to open an element from my link
function openElementFromLink(elementID)
{
	//element id is the actual ID of the <LI>, the same object used about in a.onclick
	//there may or may not be an activeMenu, so check it, and close it
	if (activeMenu)
	{
		activeMenu.className = '';
		getNextSiblingByElement(activeMenu).style.display = 'none';
	}

	//we need to get "this" -- actually the anchor tag after the LI element
	objMenuItem = document.getElementById(elementID).firstChild;

	//alert ('elementID = ' + elementID);
	//alert ('objMenuItem.innerHTML = ' + objMenuItem.innerHTML);
	//alert ('objMenuItem.nodeName = ' + objMenuItem.nodeName);
	//alert ('objMenuItem.nodeValue = ' + objMenuItem.nodeValue);
	//alert ('objMenuItem.parentNode = ' + objMenuItem.parentNode);

	//make this item active
	objMenuItem.className = 'active';
	getNextSiblingByElement(objMenuItem).style.display = 'block';

	//set activeMenu to the current object
	activeMenu = objMenuItem;
}