function getEl(passed_id)
{
	//if no passed_id has no value return true if the getEl() function is supported and false if not
	if(typeof passed_id === 'undefined') return document.getElementById  ? true : document.all && navigator.appVersion.indexOf('MSIE 4') < 0 ? true : false;
	
	//if passed_id has a value return the element with ID passed_id else return the null pointer
	return document.getElementById ? document.getElementById(passed_id) : document.all && navigator.appVersion.indexOf('MSIE 4') < 0 ? document.all[passed_id] : null;
}

var slide_menus = new Array();
function onclick_menu(menu, menu_tagName, button_className, menu_className)
//PRE:	'menu' must be either the ID of an element that is completely loaded or an element object.
//POST:	Sub menus will be hidden and onclick events will be added to previousSiblings of hidden sub menus.
//		A sub menu is any child element with the same tag as 'menu'.
//		A button is a sub menu's first previousSibling that is an element.
//BROWSER SUPPORT: Works in IE5+, NS6+ and Opera 7.11
//		NS6.0 classNames are not updating
//		IE4 and NS4 don't support the script but there is no unexpected behaviors like thrown errors
{
	if(top.junkyPieceOfPoopie || !getEl() || !document.getElementsByTagName) return;
//	if(navigator.platform == 'MacPPC' && navigator.appVersion.indexOf('MSIE')) return;
	
	menu = typeof menu === 'string' ? getEl(menu) : menu;
	if(!menu) {
		alert('onclick_menu() reports:\n\The menu parameter is invalid! It must be an element that has already successfully loaded.');
		return;
	}
	
	menu_tagName = menu_tagName ? menu_tagName : menu.nodeName;
	
	//if an element deemed button does not already have a className this will be set
	button_className = button_className ? button_className : 'onclick_menu_button';
	
	//if an element deemed button does not already have a className this will be set
	menu_className = menu_className ? menu_className : 'onclick_menu';
	
	//set child menus (any element with the same nodeName as the root menu)
	var kids = menu.getElementsByTagName(menu_tagName);
	
	//prepare and build child menus and child buttons
	//a child menu is any child element of a menu with the same nodeName as the menu it's a child of.
	//a child button is the previousSibling of a child menu.
	//every child menu must have a child button that points at it
	var button;
	var parentMenu;
	var openAtCompletion = new Array();
	var href = location.pathname.split('#')[0].split('?')[0];
		href = 'href="?' + href.match(/[^\/]+$/);
	for(var i = kids.length-1; i >= 0; --i)
	{
		//sets menus that will be opened at completion
		if(kids[i].innerHTML.search(href) > -1) {
			openAtCompletion[openAtCompletion.length] = kids[i];
		}
		
		//hide kids
		kids[i].style.display = 'block';
		kids[i].height = kids[i].offsetHeight;
		kids[i].style.display = 'none';
		
		//we need to find the button used to access the new menu
		//it could have any nodeName EXCEPT for that of button.menu.nodeName
		//ths script assumes that it is the previous sibling of the current child
			//but we must be certain it's an element(nodeType = 1)
		button = kids[i].previousSibling;
		while(button.nodeType > 1) { //read until an element is found
			button = is_pure_ie() ? button.parentNode : button.previousSibling;
		}
		
		if(button.parentNode === menu) {
			parentMenu = null;
		}
		else {
			parentMenu = button.parentNode;
		}
		
		//LI+IE special case because IE's DOM SUCKS!!!!!!!!!
		if(button.nodeName === 'LI' && is_pure_ie()) {
			//if the first child is an element make it the button
			if(button.childNodes[0].nodeType === 1) {
				button = button.childNodes[0];
			}
			//otherwise assume that it's a textnode and replace it with an element
			else {
				var SPAN = document.createElement('SPAN');
				SPAN.innerHTML = button.childNodes[0].nodeValue;
				button.insertBefore(SPAN, button.childNodes[0]);
				button.childNodes[1].nodeValue = '';
				button = SPAN;
			}
		}
		
		//set the className of the new button
		//so that a developer can use css to indicate visually that it has a sub menu
		button.className = button.className ? button.className : button_className;
		
		//create a reference to menu for the event and define the style
		button.style.cursor = 's-resize';
		button.menu = kids[i];
		button.menu.parentMenu = parentMenu;
		button.menu.style.overflow = 'hidden';
		button.menu.style.height = '1px';
		button.menu.slide_menus_index = slide_menus.length;
		slide_menus[button.menu.slide_menus_index] = button.menu;
		
		//expands or contracts depending upon current state (rate is inverted at every event)
		button.onclick = function()
		{
			clearTimeout(this.menu.over_timer);
			slide(this.menu, this.menu.height);
		}
		//will not expand the menu unless the user sits over the button for 1 second
		button.onmouseover = function() {
			this.menu.rate = -this.menu.rate;
			this.menu.over_timer = setTimeout('slide('+ this.menu.slide_menus_index +', '+ this.menu.height +')', 2000);
		}
		//clears the overtimer which prevents it from expanding
		button.onmouseout = function() {
			clearTimeout(this.menu.over_timer);
			this.menu.rate = -this.menu.rate;
		}
	}
	
	for(var i = 0; i < openAtCompletion.length; ++i) {
		slide(openAtCompletion[i], openAtCompletion[i].height);
	}
	
	function is_pure_ie()
	//I hate how Opera pretends to be IE but not as much as how much I totally loathe sites that support IE only!
	//That's especially true when they talk about standards compliance as if they know what the hell they're talking about.
	//Either they're lazy or stupid. I'm guessing both :-P
	{
		return navigator.userAgent.indexOf('MSIE') > -1 && navigator.platform != 'MacPPC' && navigator.userAgent.indexOf('Opera') < 0;
	}
}
var slide_menu = null;
function slide(menu, height)
{
	//if menu is a number it must be an index for the slide_menus array
	if(typeof menu == 'number') {
		menu = slide_menus[menu];
	}
	
	//if menu.rate isn't already set, set it
	menu.rate = menu.rate ? menu.rate : 2;
	
	//menu.parentMenu is used for updating menu.height when a descendant menu of it is either opened or closed
	var parentMenu = menu.parentMenu ? menu.parentMenu : null;
	
	//vars
	var style = menu.style;
	var cur_height = parseInt(style.height) ? parseInt(style.height) : height;
	
	//menu slide incrementing (btw: slide time is constant at 10ms)
	var new_height = cur_height + parseInt(0.1*height)*menu.rate; //linear with normalized times (all menus take the same amount of time to open and close no matter how long they are. pretty sweet ;)
//	var new_height = cur_height + menu.rate; //linear
//	var new_height = style.display === 'none' ? height : 1; style.display = 'block'; style.height = new_height + 'px'; //instant open and close
//	var new_height = cur_height + cur_height*menu.rate; //exponential. kinda interesting but not very useful
	
	if(new_height >= height)
	//new height will be greater than max height so just make the new height equal to max height
	{
		style.height = 'auto';
		menu.height = menu.offsetHeight;
		menu.rate = -Math.abs(menu.rate);
		
		while(parentMenu) {
			parentMenu.height = parentMenu.offsetHeight;
			parentMenu = parentMenu.parentMenu;
		}
	}
	else if(new_height <= 1)
	//new height will be less than 1px so just make the new height equal to 1px and hide
	{
		style.height = '1px';
		style.display = 'none';
		menu.rate = Math.abs(menu.rate);
		
		while(parentMenu) {
			parentMenu.height = parentMenu.offsetHeight;
			parentMenu = parentMenu.parentMenu;
		}
	}
	else
	//new height if valid so increment and call me again
	{
		style.display = 'block';
		style.height = new_height + 'px';
		slide_menu = menu;
		clearTimeout(menu.timer);
		menu.slide_timer = setTimeout('slide('+ menu.slide_menus_index +',' +  height + ')', 50);
	}
}
