function recurseAndVisitAncestry(element, visitFunc, col)
{
	if (element == null)
	{
		return '';
	}
	else if (visitFunc(element))
	{
		return element;
	}
	else
	{
		return recurseAndVisitAncestry(element.parentNode, visitFunc,
			(col || '*') + " > " + element.tagName);
	}
}

function findNameInAncestry(element)
{
	return ((recurseAndVisitAncestry(element, function (e) 
			{ return e.hasAttribute('name'); })).getAttribute('name') 
		|| '');
}

function findAncestorWithClass(element, classname)
{
	return (recurseAndVisitAncestry(element, 
		function (e) { return Element.hasClassName(e, classname); }) || null);
}

function findAncestorWithName(element, name)
{
	return (recurseAndVisitAncestry(element, 
		function (e) { return (e.hasAttribute('name') 
			&& e.getAttribute('name') == name); }) 
		|| null);
}

var topLevelCtrl;
function setTopLevelCtrlRef(panelControl)
{
	topLevelCtrl = panelControl;
}

function showLauncher()
{
	new Effect.Appear('launcher', {duration: 0.5});
}

function closeLauncher()
{
	new Effect.Fade('launcher', {duration: 0.5});
}

function showConsole()
{
	new Effect.Appear('console', {duration: 0.5});
}

function closeConsole()
{
	new Effect.Fade('console', {duration: 0.5});
}

function initializeLauncherButton(func)
{
	Event.observe($('launcher_b'), 'mouseover', function (e)
	{
		(Event.element(e || window.event)).style.backgroundPosition 
			= '-30px 0';
	}, false);
	
	Event.observe($('launcher_b'), 'mousedown', function (e)
	{
		(Event.element(e || window.event)).style.backgroundPosition 
			= '-60px 0';
	}, false);
	
	Event.observe($('launcher_b'), 'mouseup', function (e)
	{
		(Event.element(e || window.event)).style.backgroundPosition 
			= '-30px 0';
	}, false);
	
	Event.observe($('launcher_b'), 'mouseout', function (e)
	{
		(Event.element(e || window.event)).style.backgroundPosition 
			= '0 0';
	}, false);

	Event.observe($('launcher_b'), 'click', func, false);
}

function initializeWidgets()
{
	var styling = function (e, mode)
	{
		switch (mode)
		{
			case 'mouseover':
				e.style.borderColor = 'blue';
				e.style.backgroundPosition = '-20px 0';
				break;
				
			case 'mousedown':
				e.style.borderColor = 'white';
				e.style.backgroundPosition = '-40px 0';
				break;
				
			case 'mouseup':
				e.style.borderColor = 'black';
				e.style.backgroundPosition = '-20px 0';
				break;
				
			case 'mouseout':
				e.style.borderColor = 'black';
				e.style.backgroundPosition = '0 0';
				break;
		}
	};
	
	var getEventHook = function (mode, styleFunc)
	{
		return function (e)
		{
			styleFunc(findAncestorWithClass(Event.element(e || window.event), 
				'widget'), mode);
		};
	};
		
	($A(document.getElementsByClassName('widget'))).each(function (n)
	{
		Event.observe(n, 'mouseover', getEventHook('mouseover', styling), false);
		Event.observe(n, 'mousedown', getEventHook('mousedown', styling), false);
		Event.observe(n, 'mouseup', getEventHook('mouseup', styling), false);
		Event.observe(n, 'mouseout', getEventHook('mouseout', styling), false);
	});
}