/*
 * jQuery UI Menu 1.0.1
 *
 * Created by Negru Nicolae Marian (marian.negru@gmail.com)
 * Modified by Edward Leigh (edward@visualconnections.com)
 *
 * Depends:
 *   ui.core.js
 */
$.fn.reverse = Array.prototype.reverse;
(function($) {
$.widget("ui.menu", {

	version: "1.0.0",
	options: {
		scope : '',
		shadow : true,
		menuOutDelay : 150
	},
	
	_create: function() {
		var self = this;
		
		// set the scope
		if(this.options.scope)
			this.element.addClass(this.options.scope);
			
		// insert left end cap
		this.element.wrapInner('<div class="ui-menu-left">');

		// prepare menu. Set classes
		var mainMenus = this.element.find('ul:first').addClass('ui-menu').children();
		mainMenus.addClass('ui-menu-item-box');
		
		// set menu items
		mainMenus.find('a:first').addClass('ui-menu-item');

		this.element.show();
		
		// find elements with child menus
		$('li > ul', this.element).each(function() {
			var list = $(this);
			// set classes on submenus
			list.addClass('ui-submenu').children().addClass('ui-submenu-item-box')
				.find('a:first').addClass('ui-submenu-item');
		});

		var dropDowns = $('li > ul', this.element).reverse().each(function() {
				var list = $(this).css({position:'absolute', top:'0px', left:'0px'});
				//list.width(list.width()).height(list.height())
				list.parent().data('hasMenu', true);
		});

		// add the hover on submenu element
		dropDowns.each(function(i){
			var list = $(this);
			var w = list.width();
			list.children().each(function() {
				var link = $(this).find('a:first');

				if(link.length > 0) {
					// set li width heigth
					var h = link.outerHeight();
					$(this).width(w).height(h);

					$('<div class="ui-submenu-item-box-hover"></div>').prependTo(this).css({position:'absolute', top:'0px', left:'0px'}).width(w).height(h).hide();
					// set link width and height
					//var wi = link.width();
					// here add more for width on IE and mac xxxx
					var wi = w - (parseInt(link.css('padding-left'), 10) || 0) - (parseInt(link.css('padding-right'), 10) || 0);
					link.css({position:'absolute', top:'0px', left:'0px'}).width(wi).height(h); 
				}
			});
			var baseIndex = $(this).css('zIndex');
			$(this).hide().parent().css({position:'relative', zIndex : baseIndex - i}); // z-index is a fix for IE
		});
		// add the hover on menu element
		mainMenus.each(function(){
				var link = $(this).find('a:first');

				if(link.length > 0) {
					// set li width heigth
					var w = link.outerWidth(true);
					var h = link.outerHeight(true);
					$(this).width(w).height(h);
					$('<div class="ui-menu-item-box-hover"></div>').prependTo(this).css({position:'absolute', top:'0px', left:'0px'}).width(w).height(h).hide();
					// set link width and height
					w = link.width();
					h = link.height();
					link.css({position:'absolute', top:'0px', left:'0px'}).width(w).height(h);
				}
		});

		// bind events
		$('li', this.element).each(function(i){
			var baseIndex = $(this).css('zIndex');
			var menu = $(this).css({position:'relative', zIndex : baseIndex - i});// z-index is a fix for IE
			menu.hover(
				$.context(self).callback(self._onMenuOver, menu),
				$.context(self).callback(self._onMenuOut, menu));
		});

		// add dropdown shadow
		if(this.options.shadow) {
			dropDowns.each(function(){
				var ul = $(this);
				$('<div></div>').appendTo(ul.parent()).addClass('ui-submenu-shadow').css({position:'absolute', display:'none'}).width(ul.outerWidth()).height(ul.outerHeight() - 3);
			});
		}
	},
	
	_onMenuOver : function(menu) {
		// stop the hide thread first
		this._stopHideThread(menu);
		
		if(this.over != null) {
			this.over.call(menu.find('div:first'));
		}
		
		if(menu.data('hasMenu')) {
			
			menu.find('a:first').addClass('ui-menu-open');
			var el = menu.find('ul:first');
			
			if(this.hiding) {
				this._onMenuOverCallback(el,menu);
			}
			if(el.data('menu-over-timer') == null)
				el.data('menu-over-timer', 
					  setTimeout($.context(this).callback(this._onMenuOverCallback, el,menu), this.options.menuOutDelay));
		}
	},
	
	_onMenuOverCallback : function(el,menu) {
		this.showSubMenu.apply(el);
			
		var t = parseInt(el.css('top'));
		var l = parseInt(el.css('left'));
		$('.ui-submenu-shadow', menu).show().css({top:(t + 5) + 'px', left:(l + 2) + 'px'});
		var timer = el.data('menu-over-timer');
		if(timer) {
			el.removeData('menu-over-timer');
			clearTimeout(timer);
		}
	},
	_stopHideThread : function(menu) {
		var hideThread = menu.data('menu-timer');
		if(hideThread != null)
		{
			clearTimeout(hideThread);
			hideThread = null;
		}
		this.hiding = false;
	},
	_onMenuOut : function(menu) {
		if(menu.data('hasMenu')) {
			this._stopHideThread(menu);
			this.hiding = true;
			menu.data('menu-timer', 
					  setTimeout($.context(this).callback(this._onMenuOutCallback, menu), this.options.menuOutDelay));
		}
		else if(this.out != null) {
			this.out.call(menu.find('div:first'));
		}
	},
	_onMenuOutCallback : function(menu) {
		var el = menu.find('ul:first');
		
		this.hideSubMenu.apply(el);
		$('.ui-submenu-shadow', menu).hide();
		
		// remove the hover effect
		var menuLink = menu.find('a:first').removeClass('ui-menu-open');
		var data = menuLink.data('menu-data');
		if(data)
			data.out.call(menuLink);
			
		// hover menu
		if(this.out != null) {
			this.out.call(menu.find('div:first'));
		}
		this.hiding = false;
	},
	
	destroy: function() {
		$.Widget.prototype.destroy.apply(this, arguments);
	},
	
	showSubMenu: function() {
		var menu = this.parent();
		
		if(!menu.hasClass('ui-menu-item-box'))
			this.css({top:'0px', left:(menu.outerWidth() + 1) + 'px'});
		else
			this.css({top:(menu.outerHeight() - 1) + 'px', left:'-1px'});

		this.fadeIn(150, function() {
			if (jQuery.browser.msie)
				this.style.removeAttribute('filter');
		});
	},
	
	hideSubMenu: function() {
		this.fadeOut(150);
	},
	
	over: function() {
		// on hover
		this.fadeIn(150, function() {
			if (jQuery.browser.msie)
				this.style.removeAttribute('filter');
		});
	},
	
	out: function() {
		// off hover
		this.fadeOut(150);
	}
	
});

// $.context
$.extend(
{
	context: function (context)
	{
		var co = 
		{
			callback: function ()
			{
				/*var args = null;
				if(typeof arguments == 'Array')
					args = arguments.slice(1, arguments.length);*/
				var method = arguments[0];
				var args = [];
				for(var i = 1; i < arguments.length; i++) {
					args.push(arguments[i]);
				}
				if (typeof method == 'string') method = context[method];
					var cb = function () { method.apply(context, args ? args.concat(arguments) : arguments); }
					return cb;
				}
			};
			return co;
		}
	});
})(jQuery);

