/* (c) 2005 CaribMedia */

/*
 * @name 	isTag
 * @description simply checks if an element is a tag or a text
 *				IE sees tags+text, FF sees only tags
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function isTag(node)
{
	return (node.nodeType == 1)
}

/*
 * @name fold
 * @description folds/unfolds part of a page (tile)
 * @param skip 	- the number of elements to skip after
 *				- in fact, skip is the Nth child from the parent
 * @author Michiel van der Blonk
 * @date July 11, 2005
 * @updated Oct 18, 2005
*/
function fold(el, skip)
{
	// the block to hide should be the first child after
	// the show-hide button
	var tile, node, parent;

	// find the element
	parent = el.parentNode;
	if (parent.hasChildNodes())
	{
		// init node
		node = parent.childNodes[0];
		size = parent.childNodes.length;
		nCountElements = 0;
		nCountTags = 0
		// if there are any elements, continue
		if (size > 0)
		{
			// loop until bounds
			while (nCountTags < skip && nCountElements<size)
			{
				node = parent.childNodes[nCountElements];
				nCountElements++;
				// count the tags
				if (isTag(node))
					nCountTags++;
			}
			tile = node;
		}
		else
			alert('error: list cannot display');
	}
	else
		alert('error: list cannot display');
	// now show/hide the element
	var isHidden;
	isHidden = tile.className.match(/hide/)!=null;

	if (!isHidden)
	{
		tile.className += " hide";
		el.className += " collapsed";
	}
	else
	{
		tile.className = tile.className.replace(" hide","");
		el.className = el.className.replace(" collapsed","");
		// also for elements with a single class name
		tile.className = tile.className.replace("hide","");
		el.className = el.className.replace("collapsed","");
	}

	return false;
}


/*
 * @name 	collapse
 * @description collapses all elements in a list by calling fold()
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function collapse(listId)
{
	var list = document.getElementById(listId);
	var foldIcons = list.getElementsByTagName("span");
	for (var i=0; i<foldIcons.length; i++)
		if ( foldIcons[i].className.match(/fold/)!=null )
			fold(foldIcons[i], 3);
}


/*
 * @name 	expand
 * @description expands an item by walking up the tree
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function expand(objElement)
{
// THIS IS NOT WORKING YET.
// WE NEED TO ACTUALLY _FOLD_ HERE, SINCE THE + NEEDS TO BE SHOWN

	activeElement = objElement;
	do
	{
		if (activeElement.tagName == "UL")
		{
			tile.className = tile.className.replace(" hide","");
			el.className = el.className.replace(" collapsed","");
			// also for elements with a single class name
			tile.className = tile.className.replace("hide","");
			el.className = el.className.replace("collapsed","");
		}
		activeElement = activeElement.parentNode;
	} while (activeElement.tagName!="DIV" && activeElement.tagName!="BODY")
}

/*
 * @name 	showHide
 * @description hides an element effectively by adding the 'hide' class
 * @precond	the class named 'hide' should exist in the css
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function showHide(id)
{
	var isHidden;
	tile = document.getElementById(id);
	showHideObject(tile);
}

/*
 * @name 	showHide
 * @description hides an element effectively by adding the 'hide' class
 * @precond	the class named 'hide' should exist in the css
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function showHideObject(objElement)
{
	var isHidden;
	tile = objElement;
	// check for existence of tile element
	if (!tile)
		return;
	isHidden = tile.className.match(/hide/)!=null;

	if (isHidden)
	{
		tile.className = tile.className.replace(" hide","");
		// also for elements with a single class name
		tile.className = tile.className.replace("hide","");
	}
	else
		tile.className += " hide";
}

/*
 * @name 	debug
 * @description shows debug info in a 'debug' box in html
 * @precond	the element named 'debug' should exist in the css
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function debug(s)
{
	debugBox = document.getElementById('debug');
	if (debugBox)
		debugBox.innerHTML += s + "<br>";
}

/*
 * @name 	findOwner
 * @description finds the parent DIV
 * @param	evt - the event
 * @author 	PPK (www.quirksmode.org)
 * @date 	Oct 18, 2005
*/
function findOwner(element)
{
	node = element;
    while (node)
    {
        if (isTag(node) && node.nodeName == "DIV")
                return node;
        node = node.parentNode;
    }
    return null;
}

/*
 * @name 	autoFold
 * @description sets a timer to automatically hide the list
 * @param	selectId - the id of the faux-select
 * @param	listId - the id of the UL
 * @param	target - the element that triggered the event
 * @param	delay - nr of seconds to wait before closing
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function autoFold(selectId, listId, target, delay)
{
	// prevent bubbles
	if (window.event)
		window.event.cancelBubble = true;
	// if this is not the list return
	if (target.id!=listId)
		return;
	var isHidden;
	list = document.getElementById(listId);
	selectBox = document.getElementById(selectId);
	isListVisible = list.className.match(/hide/)==null;
	if (isListVisible)
		window.setTimeout("fold(selectBox, 2)", delay*1000);
}

/*
 * @name 	getTarget
 * @description cross browser code for finding out an event target
 * @param	e - the event
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function getTarget(e)
{
	// in IE the event param is null
	if (!e)
		var e = window.event;
	// IE has srcElement attr
	if (e.srcElement)
		target = e.srcElement;
	// FF/NN has target attr
	if (e.target)
		target = e.target;
	return target;
}

/*
 * @name 	initSelectList
 * @param	selectId	 -	the id of the faux-select box
 * @param	listId		- the id of the actual list (expanding div)
 * @param	action		- either 'select' (default) or 'submit'
 * @param	formId		- the form that contains the select box
 * @param	fieldId		- the hidden field which is used to submit the value
 * @param	autoHide	- hide the list after 2 seconds
 * @param	currentNode	- display the current node as the selected item
 * @param   onAction    - javascript function string to call in addition to 
 *                        standard select/submit actions
 * @description shows debug info in a 'debug' box in html
 * @precond	the element named 'debug' should exist in the css
 * @author 	Michiel van der Blonk
 * @date 	Oct 18, 2005
*/
function initSelectList(selectId, listId, action, formId, fieldId, autoHide, currentNode, onAction)
{

	// set default action
	if (!action)
		action = 'select';
	// get elements
	selectBox = document.getElementById(selectId);
	list = document.getElementById(listId);

	// when someone clicks anywhere on the document
	// outside of the list we close it (the list)
	// list.onclick = function() {event.cancelBubble = true;return false;}
	document.onclick=function(e)
	{
		// init
		t = getTarget(e);
		owner = findOwner(t);
		// if this element is a child of the list
		// then don't close the list
		if (owner && owner.id==listId)
			return;
		// otherwise, if the list is currently open
		// then close it now
		if (t.id!=listId && t.id!=selectId )
			if (!list.className.match(/hide/))
				fold(selectBox, 2);
	}
/*
	// THIS IS NOT WORKING CORRECTLY YET

	// automatically hide after two seconds
	if (autoHide)
		list.onmouseout = function (e) {
			target = getTarget(e);
			autoFold(selectId, listId, target, 2);
		};
		list.onblur = function (e) {
			target = getTarget(e);
			autoFold(selectId, listId, target, 0);
		};
*/
	// find the list, collapse all elements
	collapse(listId);
	// hide the list
	fold(selectBox, 2);

	try
	{
		// create select/submit actions for all anchors in the list
		var items = list.getElementsByTagName("a");
		for (var i=0; i<items.length; i++)
		{
			// define the submitting function
			fSubmit = function()
					{
						selectBox.innerHTML = this.innerHTML;
						fold(selectBox, 2);
						form = document.getElementById(formId);
						field = document.getElementById(fieldId);
						field.value = this.getAttribute('rel');
						if (onAction != null) eval(onAction);
						form.submit();
						return false;
					}
			// define the select-only function
			fSelect = function()
					{
						selectBox.innerHTML = this.innerHTML;
						fold(selectBox, 2);
						form = document.getElementById(formId);
						field = document.getElementById(fieldId);
						field.value = this.getAttribute('rel');
						if (onAction != null) eval(onAction);
						return false;
					}

			// in case of submit attach function
			if (action=='submit') {
				items[i].onclick= fSubmit;
				if (items[i].getAttribute('rel') == currentNode)
				{
					selectBox.innerHTML = items[i].innerHTML;
					activeElement = items[i].parentNode.parentNode;
					// expand all UL's up the tree from the current node
					//expand(activeElement);
				}
			}				
			// in case of select attach function
			// and select current node
			else
			{
				items[i].onclick= fSelect;
				if (items[i].getAttribute('rel') == currentNode)
				{
					selectBox.innerHTML = items[i].innerHTML;
					activeElement = items[i].parentNode.parentNode;
					// expand all UL's up the tree from the current node
					//expand(activeElement);
				}
			}
		}
	}
	catch(e)
	{
		alert(e);
	}
}
