function HoveringMenus(elTop)
{
	var self = this;
	if (typeof elTop == 'string')
		elTop = document.getElementById(elTop);

	if (typeof elTop == 'undefined' || elTop == null || typeof elTop.firstChild == 'undefined' || elTop.firstChild == null)
		return;

	for(var elItem = elTop.firstChild; elItem; elItem = elItem.nextSibling)
	{
		if (typeof elItem.tagName == 'undefined'|| elItem.tagName.toLowerCase() != 'li' || !elItem.className.match(/haschildren/))
			continue;
		
		if (elItem.addEventListener)
		{
			elItem.addEventListener('focus', function(evt) { self.FocusHandler(evt); }, false);
			elItem.addEventListener('blur', function(evt) { self.BlurHandler(evt); }, false);
			elItem.addEventListener('mouseover', function(evt) { self.MouseOverHandler(evt); }, false);
			elItem.addEventListener('mouseout', function(evt) { self.MouseOutHandler(evt); }, false);
		}
		else
		{
			(function(elItemBind) {
				elItemBind.attachEvent('onfocus', function() { evt = window.event; evt.target = evt.srcElement; evt.currentTarget = elItemBind; self.FocusHandler(evt); });
				elItemBind.attachEvent('onblur', function() { evt = window.event; evt.target = evt.srcElement; evt.currentTarget = elItemBind; self.BlurHandler(evt); });
				elItemBind.attachEvent('onmouseover', function() { evt = window.event; evt.target = evt.srcElement; evt.currentTarget = elItemBind; self.MouseOverHandler(evt); });
				elItemBind.attachEvent('onmouseout', function() { evt = window.event; evt.target = evt.srcElement; evt.currentTarget = elItemBind; self.MouseOutHandler(evt); });
			})(elItem);
		}
	}
}

HoveringMenus.prototype =
{
	OPEN_TIMEOUT: 100,		// number of ms the user needs to hover on a menu item before its submenu opens
	CLOSE_TIMEOUT: 200,		// number of ms the user needs to leave the menu item or submenu before the submenu closes

	timeoutOpen: null,		// timer that fires the opening of a submenu
	timeoutClosed: null,	// timer that fires the closing of a submenu

	elCurrentlyOpen: null,	// currently open submenu
	elToOpen: null,
	elToClose: null,

	FocusHandler: function(evt)
	{
		this.MouseOverHandler(evt);
	},
	BlurHandler: function(evt)
	{
		this.MouseOutHandler(evt);
	},
	MouseOverHandler: function(evt)
	{
		var target = evt.currentTarget;
		//console.log("over", target);

		if (this.timeoutOpen && this.elToOpen != target) { //console.log("over clearing open");
			window.clearTimeout(this.timeoutOpen);}

		if (this.timeoutClosed && this.elToClose == target) {//console.log("over clearing close");
			window.clearTimeout(this.timeoutClosed);}

		this.elToOpen = target;

		var self = this;
		this.timeoutOpen = window.setTimeout(function()
		{
			//console.log("open fired", target);
			self.timeoutOpen = null;

			if (self.elCurrentlyOpen != self.elToOpen && self.elCurrentlyOpen != null)
			{
				//console.log(self.elCurrentlyOpen, self.elToOpen, target);
				self.Close(self.elCurrentlyOpen);	
			}
			self.Open(target);

			self.elToOpen = null;
			self.elCurrentlyOpen = target;
		}, this.OPEN_TIMEOUT);
	},
	MouseOutHandler: function(evt)
	{
		var target = evt.currentTarget;
		//console.log("out", target);
		//console.log("not returned");

		this.elToClose = target;

		var self = this;
		this.timeoutClosed = window.setTimeout(function()
		{
			//console.log("close fired", target);
			self.timeoutClosed = null;
			self.elToClose = null;
			if (target == self.elToOpen) 
				return;
			//console.log("not returning");
			self.Close(target);
			self.elCurrentlyOpen = null;
		}, this.CLOSE_TIMEOUT);
	},
	Open: function(el)
	{
		if (!el.className.match(/hover/))
			el.className += " hover";
	},
	Close: function(el)
	{
		el.className = el.className.replace(/( hover)+/, '');
	}
}
