/**
 * @author alexander.farkas
 */
(function($){
var isLocal = ( (location.protocol.indexOf('file') === 0) || location.href.indexOf('://127.0.0.1') !== -1 || location.href.indexOf('://localhost'));
$.widget('aperto.simpleMenu', {
	options: {
            debug: false,
	inOutOpts: {
		mouseDelay: 100
	},
	
	menuSel: 'div.menu',
	menuItemSel: '> a, > strong', //
	addKeyNav: true,
	visibleClass: 'menu-visible',
	activateDelay: 300,
	
	showHiddenOnFocus: false,
	
	constrainHorizontal: false,
	constrainStyle: 'left',
	positionTop: false,
	
	
	
	closeOnItemLeave: true, // false funktioniert nur bei einfacher verschachtelung
	closeOnMenuLeave: false,
	initialOpenSel: '.ui-menu-visible', // Selector gilt nur für 1. Verschachtelung
	restoreInitialStateOnLeave: false, // true funktioniert nur für 1. Verachtelung
	
	
	nestedMenu: false
	},
	_create: function(){
	
	var o 	= this.options,
		that 	= this,
		firstUL = (this.element.is('ul, ol')) ? 
				this.element : 
				$('ul, ol', this.element).filter(':first') 
	;
	
	if( isLocal && !o.nestedMenu && this.element.parents(':aperto-simpleMenu').length ){
		alert('Are you sure you want to create multiple nested megamenus. Check your selector.');
	}
	
	this.timer = $.createTimer(this);
	
	this.mainItems = $('> li', firstUL[0]);
	
	this.menuItems = [];
	this.menus = [];
	
	function initItems(){
		var menu = $(o.menuSel, this), jElm;	
		if(menu[0]){
		jElm = $(this);
		jElm = jElm.addClass('has-menu');
		that.menuItems.push(this);
		that.menus.push(menu[0]);
		return menu;
		}
		return false;
	}
	
	function over(e){
		that.show($(this), e);
	}
		
	function out(e){
                if(o.debug){return;}
		if(o.closeOnItemLeave){
		that.hide($(this), e);
		}
	}
	
	this.initialOpenItem = $([]);
	
	this.mainItems.each(function(i){
		var menu = initItems.call(this), 
		jElm= $(this),
		toText = '',
		nextLi, 
		fromText, 
		toElem, 
		skipLink
		;
		
		if(menu){
		if(o.initialOpenSel && jElm.is(o.initialOpenSel)){
			that.initialOpenItem = jElm.addClass(o.visibleClass);
		}
		$('li', this).each(initItems);
		}
	});
	
	that.currentOpenItem = that.initialOpenItem;
	firstUL.context = firstUL.parent()[0];
	firstUL.selector = '> ul, > ol';
	
	if(o.restoreInitialStateOnLeave && this.initialOpenItem[0]){
		firstUL.inOut(function(){
		that.timer.clear('openTimer');
		}, function(e){
		that.timer.setDelay('openTimer', function(){
			that.show(that.initialOpenItem, e);
		}, 1);
		}, o.inOutOpts);
	} else if(!o.closeOnItemLeave && o.closeOnMenuLeave){
		firstUL.inOut(function(){
		that.timer.clear('openTimer');
		}, function(e){
		that.timer.setDelay('openTimer', function(){
			if(that.currentOpenItem && that.currentOpenItem[0]){
			that.hide(that.currentOpenItem, e);
			}
		}, 1);
		}, o.inOutOpts);
	}
	
	if(o.addKeyNav){
		this.mainItems.bind('keydown', function(e){
		if($(e.target).is(':input')){return undefined;}
		var ret;
		if($.ui.keyCode.LEFT === e.keyCode){
			ret = that.focusIndex(that.mainItems.index(this) - 1);
		} else if($.ui.keyCode.RIGHT === e.keyCode){
			ret = that.focusIndex(that.mainItems.index(this) + 1);
		}
		
		return ret;
		});
	}
	this.element
		.inOut(
		$.proxy(this, 'activateMenu'),
		$.proxy(this, 'inactivateMenu'),
		{
			mouseDelay: o.activateDelay,
			keyDelay: 0
		}
		)
	;
		
	this.menuItems = $(this.menuItems);
	this.menuItems.context = firstUL[0];
	this.menuItems.selector = '.has-menu';
	this.menuItems.inOut(over, out, o.inOutOpts);
	
	this.menuItems
		[o.inOutOpts.bindStyle || 'bind']('mouseleave mouseenter focusin focusout', function(){
		that.timer.clear('openTimer');
		})
	;
	
	this.menus = $(this.menus);
	this._trigger('init', {}, this.ui());
	
	
	},
	focusIndex: function(index){
	var focusItem = this.mainItems.get(index);
	if(focusItem){
		$(this.options.menuItemSel, focusItem).setFocus();
		return false;
	}
	return undefined;
	},
	ui: function(){
	return {
		instance: this,
		menuItems: this.menuItems,
		menus: this.menus,
		element: this.element
	};
	},
	constrainRight: function(menu){
	var offset = (this.element.offset().left + this.element.width()) - (menu.offset().left + menu.width());
	if(offset < 0){
		menu.css(this.options.constrainStyle, offset);
	}
	},
	activateMenu: function(){
	this.isActivated = true;
	if(this.showOnActivate && this.showOnActivate[0]){
		this.show(this.showOnActivate, {type: 'activated'});
	}
	this.showOnActivate = false;
	},
	inactivateMenu: function(){
	this.isActivated = false;
	this.showOnActivate = false;
	},
	show: function(menuItem, e){
	this.timer.clear('openTimer');
	e = e || {type: 'show'};
	var o 	= this.options,
		menu 	= $(o.menuSel +':first', menuItem)
	;
	if(menuItem.hasClass(o.visibleClass)){return;}
	
	if(!$.aperto.simpleMenu.shouldReactOnFocus(e, menu, o)){
		return false;
	}
	if(!this.isActivated){
		this.showOnActivate = menuItem;
		return;
	}
	if($.inArray(menuItem[0], this.mainItems) > -1){
		if((!o.closeOnItemLeave || o.restoreInitialStateOnLeave) && this.currentOpenItem && this.currentOpenItem[0]){
		this.hide(this.currentOpenItem, e);
		}
		this.currentOpenItem = menuItem;
	}
	
	if( o.positionTop !== false && isFinite(o.positionTop) ){
		menu.css({
		top: menu.offsetParent().outerHeight() + o.positionTop
		});
	}
	
	this._trigger('show', e, $.extend({}, this.ui(), {menuItem: menuItem, menu: menu}));
	menuItem.addClass(o.visibleClass);
	if(o.constrainHorizontal){
		this.constrainRight(menu);
	}
	
	return undefined;
	},
	hide: function(menuItem, e){
	e = e || {type: 'hide'};
	var o 	= this.options,
		that =this,
		menu = $(o.menuSel +':first', menuItem)
	;
	
	if(!menuItem.hasClass(o.visibleClass)){
		if(this.showOnActivate && this.showOnActivate[0] === menuItem[0]){
		this.showOnActivate = false;
		return;
		}
		return;
	}
	this._trigger('hide', e, $.extend({}, this.ui(), {menuItem: menuItem, menu: menu}));
	
	menuItem.removeClass(o.visibleClass);
	if($.inArray(menuItem[0], this.mainItems) > -1){
		this.currentOpenItem = $([]);
	}
	},
	hideAll: function(e) {
	var that	= this;
	e = e || {type: 'hideAll'};
	
	this
		.menuItems
		.filter('.'+this.option('visibleClass'))
		.each(function(){
		that.hide($(this), e);
	});
	}
});
$.aperto.simpleMenu.shouldReactOnFocus = function(e, menu, o){
	return !!(!e || !(!o.showHiddenOnFocus && 
		e.originalEvent && e.originalEvent.type &&
		e.originalEvent.type.indexOf('focus') !== -1 && 
		menu.css('display') === 'none'));
};
})(jQuery);
