function printLn(str)
{
	var print_div = document.getElementById('content_div');
	print_div.appendChild(document.createTextNode(str));
	print_div.appendChild(document.createElement('br'));
}


function menuSystem(element, prop, level) // ul 
{
	element = typeof(element) == 'string' ? document.getElementById(element) : (element != null ? element : document.createElement('ul'));

	// public functions
	element.hide    = function(quick) { hide(prop.fadeOutDelay, prop.fadeOutLength, quick); };
	element.show    = function(quick) { show(prop.fadeInDelay,  prop.fadeInLength,  quick); };
	element.unclick = function() { if(clicked) clicked.unclick(); }
	element.tryLink = tryLink;
	
	// public events
	element.onSelect = prop.onSelect ? prop.onSelect : function(link) { return true; }; // will just behave like a normal link

	var className = element.className;
	var def = { fadeInLength:100, fadeOutLength:100, fadeQuickLength:0, fadeInDelay:0, fadeQuickDelay:0, fadeOutDelay:200, fadeInterval:10, minOpacity:0, maxOpacity:100 };
	if(prop == null)
		prop = {};
	for(var key in def)
		if(prop[key] === undefined)
			prop[key] = def[key];

	var menus = [], current = null, clicked = null, delayInTimer = null, delayOutTimer = null, fadeInInterval = null, fadeOutInterval = null, opacityCur = 0;
	var canFade = (navigator.userAgent.match(/firefox|opera|chrome/i) != null); // whether or not the browser can handle fades
	
	var cs = element.childNodes;
	for(var n = 0; n < cs.length; n++)
		if(cs[n].nodeName.toUpperCase() == 'LI')
			addMenuItem(cs[n]);

	return element;
	
	
	function tryLink(link)
	{
		for(var n = 0; n < menus.length; n++)
			if(menus[n].tryLink(link) == false)
				return false;
	}
	
	function addMenuItem(li)
	{
		var item = menuItem(li, prop, level);
		if(item.isCurrent())
			clicked = item;
		menus.push(item);
		
		item.onHide = function(quick)
		{
		};
		item.onSelect = function(link) 
		{
			if(item != clicked)
				element.unclick();
			
			clicked = item;
			return element.onSelect(link); 
		};
		item.onShow   = function(quick) 
		{ 
			if(current && current != item)
				current.hide();
			current = item;
		};
	}

	function clearTimers()
	{
		if(delayInTimer != null)
		{
			window.clearTimeout(delayInTimer);
			delayInTimer = null;
		}
		if(delayOutTimer != null)
		{
			window.clearTimeout(delayOutTimer);
			delayOutTimer = null;
		}
		if(fadeInInterval != null)
		{
			window.clearInterval(fadeInInterval);
			fadeInInterval = null;
		}
		if(fadeOutInterval != null)
		{
			window.clearInterval(fadeOutInterval);
			fadeOutInterval = null;
		}
	}
	
	
	function show(delay, length, quick)
	{
		if(delayOutTimer != null)
		{
			window.clearTimeout(delayOutTimer);    
			delayOutTimer = null;
		}

		if(quick)
			showIn();
		else if(delayInTimer == null)
		{
			if(canFade && prop.fadeInLength)
			{
				delayInTimer = window.setTimeout(startFadeIn, delay);
			}
			else delayInTimer = window.setTimeout(showIn, prop.fadeInDelay);
		}
		
		function showIn() // non-fade
		{
			clearTimers();
			element.className = 'displayed';
		}
		
		function startFadeIn()
		{
			clearTimers();
			var change = (prop.maxOpacity - prop.minOpacity) / (length / prop.fadeInterval);
			
			setOpacity(opacityCur);
			element.className = 'displayed';
			fadeInInterval = window.setInterval(runFadeIn, prop.fadeInterval);
			
			function runFadeIn() 
			{
				opacityCur += change;
				setOpacity(opacityCur);
				if(opacityCur >= prop.maxOpacity)
				{
					window.clearInterval(fadeInInterval);
				}
			}
		}
	}
	
	function hide(delay, length, quick)
	{
		window.clearTimeout(delayInTimer); delayInTimer = null;
		
		if(quick)
			showOut();
		else if(delayOutTimer == null)
		{
			if(canFade && length > 0)
				delayOutTimer = window.setTimeout(startFadeOut, delay);
			else delayOutTimer = window.setTimeout(showOut, delay);
		}
		
		function showOut() // non-fade
		{
			clearTimers();
			element.className = '';
		}
		
		function startFadeOut()
		{
			var change = (prop.maxOpacity - prop.minOpacity) / (length / prop.fadeInterval);
			clearTimers();

			fadeOutInterval = window.setInterval(runFadeOut, prop.fadeInterval);
			function runFadeOut() 
			{
				opacityCur -= change;
				setOpacity(opacityCur);
				if (opacityCur <= prop.minOpacity) 
				{
					element.className = '';
					window.clearInterval(fadeOutInterval);
				}
			}
		}
	}

	function setOpacity(opacityCur)
	{
		if (opacityCur > prop.maxOpacity)
			opacityCur = prop.maxOpacity;
		else if(opacityCur < prop.minOpacity)
			opacityCur = prop.minOpacity;
			
		element.style['opacity']      = opacityCur / 100;
		element.style['-moz-opacity'] = opacityCur / 100;
		element.style['filter']       = 'alpha(opacity='+opacityCur+')';
	}
}


function menuItem(element, prop, level) // li
{
	// public methods
	element.hide      = function() { hide(true); }; // called when another menu is displayed
	element.unclick   = unclick;
	element.isCurrent = function() { return isCurrent; };
	element.tryLink  = tryLink;
	
	// public events
	element.onSelect = function(link)  {};
	element.onHide   = function(quick) {};
	element.onShow   = function(quick) {};
	
	var menu = null, link = {};
	
	var cs = element.childNodes;
	for(var n = 0; n < cs.length; n++)
	{
		var nodeName = cs[n].nodeName.toUpperCase();
		if(nodeName == 'UL')
		{
			menu = menuSystem(cs[n], prop, level + 1);
			menu.onSelect = subMenuClicked;
		}
		else if(nodeName == 'A')
			link = cs[n];
	}
	
	var isCurrent = link.className == 'current';
	
	// private events
	element.onmouseover = function() { show(false); };
	element.onmouseout  = function() { hide(false); };
	if(link.onclick == undefined) // this line disables clicking on items that have a submenu, since they will have an onclick handler already
		link.onclick = onclick;
	link.hashStr = link.href.match(/\.(?:com|net|org|us)\/([^\?&]*)/)[1];

	function tryLink(a)
	{
		if(link.href == a.href)
			return link.onclick();
		else if(menu)
			return menu.tryLink(a);
		else return true;
	}
	
	function onclick()
	{ 
		isCurrent = true;
		hide(true); // closes this menu
		try { link.blur(); } catch(e) { }
		if(menu)
			menu.unclick();
		return element.onSelect(link);
	}
	function subMenuClicked(link)
	{
		isCurrent = true; 
		hide(true); // closes parent menus
		return element.onSelect(link); // every menu hidden
	}
	function unclick()
	{
		isCurrent = false;
		link.className = '';
		if(menu)
			menu.unclick();
	}
	
	function show(quick)
	{
		link.className = 'current';
		if(menu)
			menu.show(quick);
		element.onShow();
	}
	function hide(quick)
	{
		link.className = isCurrent ? 'current' : '';
		if(menu)
			menu.hide(quick);
		element.onHide();
	}
	
	return element;
}