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

	_init: function() {
		var self = this;
		
		// set the scope
		if(this.options.scope)
			this.element.addClass(this.options.scope);

		// 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); 
				}
			});
			$(this).hide().parent().css({position:'relative', zIndex : 100000 - 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 menu = $(this).css({position:'relative', zIndex : 100000 - 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.options.over != null) {
			this.options.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.options.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.options.out != null) {
			this.options.out.call(menu.find('div:first'));
		}
	},
	_onMenuOutCallback : function(menu) {
		var el = menu.find('ul:first');
		
		this.options.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.options.out != null) {
			this.options.out.call(menu.find('div:first'));
		}
		this.hiding = false;
	},
	destroy: function() {
		$.widget.prototype.destroy.apply(this, arguments);
	}
});

$.extend($.ui.menu, {
	version: "1.0.0",
	defaults: {
		scope : '',
		shadow : true,
		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);
			},
		menuOutDelay : 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);
