function getOffset(element, offset)
{
	if (!offset)
		offset = {left: 0, top: 0};
	
	do {
		offset.left += parseInt(element.offsetLeft, 10);
		offset.top += parseInt(element.offsetTop, 10);
	} while (element = element.offsetParent);
	
	return offset;
}

function hasClassName(element, className)
{
	if (className == '')
		return false;
		
	var classNames = element.className.split(' ');
	for (var i = 0; i < classNames.length; i++)
	{
		if (classNames[i] == className)
			return true;
	}
	return false;
}

function addClassName(element, className)
{
	if (!hasClassName(element, className))
	{
		element.className += (element.className ? ' ' : '') + className;
	}
}

function removeClassName(element, className)
{
	var classNames = element.className.split(' ');
	var newClassNames = '';
	for (var i = 0; i < classNames.length; i++)
	{
		if (classNames[i] != className)
		{
			if (newClassNames.length > 0)
			{
				newClassNames += ' ';
			}
			newClassNames += classNames[i];
		}
	}
	element.className = newClassNames;
}

function addHandler(target, eventName, handlerName, handler)
{
    if (handler)
        target[handlerName] = handler;
    
    if (target.addEventListener) {
        target.addEventListener(eventName, function(e) { target[handlerName](e); }, false);
    } else if (target.attachEvent) {
        target.attachEvent('on' + eventName, function(e) { target[handlerName](e); });
    } else {
        var origHandler = target['on' + eventName];
        if (origHandler) {
            target['on' + eventName] = function(e) { origHandler(e); target[handlerName](e); };
        } else {
            target['on' + eventName] = target[handlerName];
        }
    }
}

function ScoutMenu(elementId, options)
{
	this.isIE50 = (navigator.userAgent.indexOf('MSIE 5.0') > 0);
	this.element = window.document.getElementById(elementId);
	this.offset = {left: 0, top: 0};
	this.emptySubMenu = null;
	this.controlObscurer = null;
	this.options = new ScoutMenuOptions();
	if (options)
	{
		for (prop in options)
		{
			this.options[prop] = options[prop];
		}
	}
	this.topLevelItems = [];
	this.lastSelectedTopLevelItem = -1;
	this.hideTimeout = false;
}

ScoutMenu.prototype = {
	getOptions: function() { return this.options; },
	
	initialize: function() {
			if (!this.element)
				return;
			this.offset = getOffset(this.element);
			this.initializeSpecialItems();
			this.addHandlers();
			if (this.options.initialTopMenuItem >= 0 && this.options.initialTopMenuItem < this.topLevelItems.length)
			{
				this.topLevelItems[this.options.initialTopMenuItem].scoutMenu_highlightItem(null);
			}
		},

	initializeSpecialItems: function() {
			if (this.options.specialItemsClassName)
			{
				var emptySubmenuFound = (this.options.emptySubmenuClassName == '');
				var controlObscurerFound = (this.isIE50 || this.options.controlObscurerClassName == '');
				
				for (var i = 0; i < this.element.childNodes.length && (!emptySubmenuFound || !controlObscurerFound); i++)
				{
					var child = this.element.childNodes[i];
					if (child.nodeType == 1 && hasClassName(child, this.options.specialItemsClassName))
					{
						for (var j = 0; j < child.childNodes.length && (!emptySubmenuFound || !controlObscurerFound); j++)
						{
							var specialNode = child.childNodes[j];
							if (specialNode.nodeType == 1)
							{
								if (!controlObscurerFound && hasClassName(specialNode, 'control-obscurer'))
								{
									this.element.insertBefore(specialNode, child);

									this.controlObscurer = specialNode;
									
									controlObscurerFound = true;
									j--;							
								}
							}
						}
						this.element.removeChild(child);
					}
				}
			}
		},
		
	addHandlers: function() {
			var itemIndex = 0;
			for (var i = 0; i < this.element.childNodes.length; i++)
			{
				var child = this.element.childNodes[i];
				if (child.nodeType == 1 && child.nodeName == 'LI' && !hasClassName(child, this.options.specialItemsClassName))
				{
					if (itemIndex == 0 && this.isIE50 && this.emptySubMenu)
					{
						this.emptySubMenu.style.top = (parseInt(this.emptySubMenu.style.top) + child.offsetHeight) + 'px';
					}
					this.topLevelItems[itemIndex] = child;
					var me = this;
					child.scoutMenu_isRightMenu = hasClassName(child, this.options.rightMenuClassName);
					child.scoutMenu_itemIndex = itemIndex;
					child.scoutMenu_highlightItem = function(event) { me.mouseOver(event, this.scoutMenu_itemIndex); };
					child.scoutMenu_unhighlightItem = function(event, resetting) {
							if (!me.options.showOtherSubmenus)
							{
								if (!resetting || (me.options.initialTopMenuItem != this.scoutMenu_itemIndex))
								{
									if (this.scoutMenu_isRightMenu)
										removeClassName(this, me.options.rightMenuHighlightClassName);
									else
										removeClassName(this, me.options.highlightClassName);
								}
							}
							else
							{
								if (!resetting || (me.options.initialTopMenuItem != this.scoutMenu_itemIndex))
								{
									if (this.scoutMenu_isRightMenu)
										removeClassName(this, me.options.rightMenuActiveClassName);
									else
										removeClassName(this, me.options.activeClassName);
								}
							}
							if (me.options.showOtherSubmenus && this.scoutMenu_subMenu && (!resetting || (this.scoutMenu_itemIndex != me.options.initialTopMenuItem)))
							{
								this.scoutMenu_subMenu.style.visibility = '';
							}
						}
					addHandler(child, 'mouseover', 'scoutMenu_highlightItem');
					addHandler(child, 'mouseout', 'scoutMenu_mouseOut', function(evt) { me.mouseOut(evt, this.scoutMenu_itemIndex); });

					this.addSubmenuHandlers(child);
					itemIndex++;
				}
			}
		},
		
	addSubmenuHandlers: function(element) {
			var childUL = null;

			for (var i = 0; i < element.childNodes.length; i++)
			{
				var child = element.childNodes[i];
				if (child.nodeType == 1 && child.nodeName == 'UL')
				{
					if (!childUL)
						childUL = child;
					else
					{
						childUL = null;
						break;
					}
				}
			}
			if (childUL)
			{
				element.scoutMenu_subMenu = childUL;
				childUL.style.left = (parseInt(childUL.offsetLeft, 10) + this.offset.left) + 'px';
				childUL.style.top = (parseInt(childUL.offsetTop, 10) + this.offset.top + 1 + (this.isIE50 ? element.offsetHeight : 0)) + 'px';
				var isFirstChild = true;
				for (var i = 0; i < childUL.childNodes.length; i++)
				{
					var child = childUL.childNodes[i];
					if (child.nodeType == 1 && child.nodeName == 'LI')
					{
						child.scoutMenu_isRightMenu = element.scoutMenu_isRightMenu;
						if (this.options.separator)
						{
							if (!isFirstChild)
							{
								var sepElem = document.createElement('SPAN');
								sepElem.appendChild(document.createTextNode(this.options.separator));
								sepElem.className = this.options.separatorClassName;
								child.parentNode.insertBefore(sepElem, child);
								i++;
							}
							else
							{
								isFirstChild = false;
							}
						}
						var me = this;
						child.scoutMenu_highlightItem = function(event) {
								if (this.scoutMenu_isRightMenu)
								{
									if (this.scoutMenu_subMenu)
										addClassName(this, me.options.rightSubmenuActiveWithPopupClassName);
									else
										addClassName(this, me.options.rightSubmenuActiveClassName);
								}
								else
								{
									if (this.scoutMenu_subMenu)
										addClassName(this, me.options.submenuActiveWithPopupClassName);
									else
										addClassName(this, me.options.submenuActiveClassName);
								}
								me.showPopupMenu(this);
							};
						child.scoutMenu_unhighlightItem = function(event) {
								if (this.scoutMenu_isRightMenu)
								{
									if (this.scoutMenu_subMenu)
										removeClassName(this, me.options.rightSubmenuActiveWithPopupClassName);
									else
										removeClassName(this, me.options.rightSubmenuActiveClassName);
								}
								else
								{
									if (this.scoutMenu_subMenu)
										removeClassName(this, me.options.submenuActiveWithPopupClassName);
									else
										removeClassName(this, me.options.submenuActiveClassName);
								}
								me.hidePopupMenu(this);
							};
						addHandler(child, 'mouseover', 'scoutMenu_highlightItem');
						addHandler(child, 'mouseout', 'scoutMenu_unhighlightItem');
						
						this.addPopupMenuHandlers(child)
					}
				}
			}
		},
		
	addPopupMenuHandlers: function(element) {
			var childUL = null;

			for (var i = 0; i < element.childNodes.length; i++)
			{
				var child = element.childNodes[i];
				if (child.nodeType == 1 && child.nodeName == 'UL')
				{
					if (!childUL)
						childUL = child;
					else
					{
						childUL = null;
						break;
					}
				}
			}
			if (childUL)
			{
				element.scoutMenu_subMenu = childUL;
				var offset = getOffset(element);
				childUL.style.left = (offset.left + parseInt(childUL.offsetLeft) - 2) + 'px';
				childUL.style.top = (element.offsetHeight+1) + 'px';
			}
		},
		
	mouseOver: function(event, itemIndex) {
			if (this.hideTimeout)
			{
				clearTimeout(this.hideTimeout);
				this.hideTimeout = false;
			}

			if (this.lastSelectedTopLevelItem == itemIndex)
				return;
				
			if (this.lastSelectedTopLevelItem >= 0)
			{
				this.topLevelItems[this.lastSelectedTopLevelItem].scoutMenu_unhighlightItem(event);
			}
			var item = this.topLevelItems[itemIndex];
			if (!this.options.showOtherSubmenus && this.options.initialTopMenuItem != itemIndex)
			{
				if (item.scoutMenu_isRightMenu)
					addClassName(item, this.options.rightMenuHighlightClassName);
				else
					addClassName(item, this.options.highlightClassName);
			}
			else
			{
				if (item.scoutMenu_isRightMenu)
					addClassName(item, this.options.rightMenuActiveClassName);
				else
				{				
					var showActive = false;					
					if(item.lastChild != null)
					{	
						var subItem = item.lastChild; 
						if(subItem.nodeName.toLowerCase() == "ul")
						{																				
							if(subItem.childNodes.length > 1)
							{
								showActive = true;
							}
							else if(subItem.childNodes.length == 1 && subItem.firstChild.nodeName != "#text")
							{
								showActive = true;
							}
						}
					}
					
					if(showActive)
					{
						addClassName(item, this.options.activeClassName);						
					}					
				}
			}
			this.lastSelectedTopLevelItem = itemIndex;
			
			if ((this.options.showOtherSubmenus || (this.options.initialTopMenuItem == itemIndex)) && item.scoutMenu_subMenu)
			{
				item.scoutMenu_subMenu.style.visibility = 'visible';
			}
		},
		
	mouseOut: function(event, itemIndex) {
			if (this.hideTimeout)
				return;
			
			var me = this;
			if (this.options.showOtherSubmenus)
				this.hideTimeout = setTimeout(function() { me.resetMenu(); }, this.options.hideTime ? this.options.hideTime : 100);
			else
				this.resetMenu();
		},
		
	resetMenu: function() {
			if (this.lastSelectedTopLevelItem >= 0)
			{
				this.topLevelItems[this.lastSelectedTopLevelItem].scoutMenu_unhighlightItem(null, true);
			}
			if (this.options.initialTopMenuItem >= 0)
			{
				this.topLevelItems[this.options.initialTopMenuItem].scoutMenu_highlightItem();
			}
		},
		
	showPopupMenu: function(element) {
			if (element.scoutMenu_subMenu)
			{
				element.scoutMenu_subMenu.style.visibility = 'visible';
				if (this.controlObscurer)
				{
					var offset = getOffset(element.scoutMenu_subMenu);
					this.controlObscurer.style.left = (offset.left) + 'px';
					this.controlObscurer.style.top = (offset.top) + 'px';
					this.controlObscurer.style.width = (element.scoutMenu_subMenu.offsetWidth) + 'px';
					this.controlObscurer.style.height = (element.scoutMenu_subMenu.offsetHeight) + 'px';
					this.controlObscurer.style.display = 'block';
				}
			}
		},
	
	hidePopupMenu: function(element) {
			if (element.scoutMenu_subMenu)
			{
				element.scoutMenu_subMenu.style.visibility = 'hidden';
				if (this.controlObscurer)
				{
					this.controlObscurer.style.display = 'none';
				}
			}
		}
}

function ScoutMenuOptions()
{
	this.hideTime = 3000;
	this.initialTopMenuItem = 0;
	this.separator = '|';
	this.separatorClassName = 'scoutmenu-separator';
	this.showOtherSubmenus = false;
	this.specialItemsClassName = 'special-items';
	this.emptySubmenuClassName = 'empty-submenu';
	this.controlObscurerClassName = 'control-obscurer';
	this.highlightClassName = 'highlight';
	this.activeClassName = 'active';
	this.rightMenuClassName = 'rightmenu';
	this.rightMenuHighlightClassName = 'rightmenu-highlight';
	this.rightMenuActiveClassName = 'rightmenu-active';
	this.submenuActiveClassName = 'subactive';
	this.submenuActiveWithPopupClassName = 'subactive-withpopup';
	this.rightSubmenuActiveClassName = 'rightmenu-subactive';
	this.rightSubmenuActiveWithPopupClassName = 'rightmenu-subactive-withpopup';
}

(function($) {
  $(document).ready(function() {
    if ($.browser.msie && parseInt($.browser.version) <= 6) {
      if ($('body select').length > 0) {
        $('ul.scoutmenu li ul li').bind('mouseover', function() {
          var ieUL = $(this).find('ul')[0];
          if (ieUL) {
            var ieMat = document.createElement('iframe');
            ieMat.style.width = ieUL.offsetWidth + "px";
            ieMat.style.height = ieUL.offsetHeight + "px";
            ieUL.insertBefore(ieMat, ieUL.firstChild);
          }
        }).bind('mouseout', function() {
          $(this).find('iframe').remove();
        });
      }
    }
  });
} (jQuery));