/**
 * @projectDescription	Barrierearmes, gebrauchstaugliches Dropdownmenu
 *
 * @author 	Alexander Farkas <a.farkas@pfirsichmelba.de> // http://pfirsichmelba.de
 * 
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 * 
 * Bei guten Verbesserungen/öffentlichem Einsatz wäre ich für eine kurze Mail mit Link dankbar.
 * 
 * @version 0.5
 * @param {String} $selektor CSS-selector of the wrapping element, id-selector = beeter performance
 * @param {options} [_settings] list of sveral options/settings
 * 
 * @option {Number|Array} [NavTimeout] delay to hide menu, if ypu use an array of two numbers, first is the delay for firstsubmenu, second for all other submenus, default is 250
 * @option {String} [ListType] listtype i.e. ol (default = ul)
 * @option {Number} [LimitLinks] 1 = (default) .active and .activepath submenus are available for keyboard users, Opera browser overrirdes this (because of spatial navigation),0 = all submenus are available for keyboard users. if you use this you should remove display:none for submenus -> better consistency for screenreader (the submenus stay hidden / are out of viewport), 2 = .active and .activepath submenus are available for keyboard users (Opera browser doesn´t override this)
 * 
 * You need CleannCSSAnimation for effects (CleanCSSAnimation removes the inline style "display: none" after animations -> good for screenreaders and keyboard-user):
 * CleannCSSAnimation Plugin: http://pfirsichmelba.de/artikel-scripts/lib/jq.cleanCSSanim.js
 * @option {Number} [Effect] needs CleannCSSAnimation plugin: 0 = no Effect (default), 1 = show and hide effect, 2 = show-effect, 3 = hide-effect
 * @option {String} [ShowEffect] Name of show effect, default=show
 * @option {String} [HideEffect] Name of hide effect, default=hide
 * @option {String|Number} [EffectSpeed] Speed of show and hide effect, default=300
 * 
 * You need Dimensions Plugin for jQuery:
 * @option {String} [Fit2ViewportClass] class-value for submenu, wich does not fit the viewport-width, default=false (= don´t check viewport width)
 * @option {Number} [FitIfViewportSmaller] only check, wether submenus fit viewport-width, if viewport is smaller than given option, default=1111 (if you want to check always set it to 9999, yopu have to set "Fit2ViewportClass")

*/

//  You sould compress/obfuscate this javascript-file....
function DickerFisch($selektor,_settings) {
	//config start
	//classnames: Styles
	// _DF_hoverclass = Hover-Class für mouseover LI und LI-Eltern von fokusierten a-Elementen
	// _DF_parent_class = Wenn zur Kategorie noch Unterkategorien gehören wird das LI-Element ausgezeichnet
	// $ofocusstyle = Opera verliert optische Markierung bei Tastaturnutzung fügt ans fokusierte a die nachfolgende id an.
	var _DF_hoverclass = 'over', _DF_parent_class = 'parent',$ofocusstyle = 'ofocus';
	//Array 0 = ancestors of active li-category | 1 = active li category
	var _DF_ActiveCatnAncestorsofIT = new Array(".activepath", ".active");
	var _jsreadyclass = 'navfxenabled';
	//_DF_hideclass = Soll versteckt werden; _waitingnavclass = Wartet darauf ausgeklappt zu werden
	var  _DF_hideclass = 'DF_hidelis', _waitingnavclass = 'DF_waitlis';
	// effect css-class: visible class value and hidden class value see/same in CleanCSSAnimation/unMakeInlineCSS, will be removed after animation
	var $nodisClass = "displaynone",$disClass = "displayblock";
	//config end
	var _DF_obj = this;
	//optional parameter
	var _settings = _settings || this;
	this.NavTimeout = _settings.NavTimeout || 0;
	this.ListType = _settings.ListType || 'ul';
	this.Effect = (_settings.Effect) ? _settings.Effect : 0;
	this.ShowEffect = _settings.ShowEffect || 'show';
	this.HideEffect = _settings.HideEffect || 'hide';
	this.EffectSpeed = _settings.EffectSpeed || 0;
	this.FitIfViewportSmaller = _settings.FitIfViewportSmaller || 1111;
	this.Fit2ViewportClass = _settings.Fit2ViewportClass || false;
	this.LimitLinks = (typeof _settings.LimitLinks == "number") ? _settings.LimitLinks : 1;
	_DF_obj.LimitLinks = ($.browser.opera && _DF_obj.LimitLinks == "1") ? 0 : _DF_obj.LimitLinks;
	this._DF_NavTimeID;
	//methods

	this._fastpullout = function(_eventobj){
		var $fastpullreturn = false;
		if(typeof $($selektor+' li.'+_DF_hoverclass).get(0) == "undefined")
			$fastpullreturn = true;
		else {
			$fastpullreturn = true;
			$(_eventobj).siblings("li").each(function(i){
				if($(this).is('.'+_DF_hoverclass)){
					$fastpullreturn = false;
					return false; //=break
				}
			});
		}
		return $fastpullreturn;
	};
	this.$oldtimer = 0;
	this.$fastpullin = function(_eventobj){
		var $aktimer = (typeof _DF_obj.NavTimeout != "number") ? _DF_obj.NavTimeout[1] : _DF_obj.NavTimeout;
		if(typeof _DF_obj.NavTimeout != "number" && $(_eventobj).parents('li').length == "0" && !$(_eventobj).children(_DF_obj.ListType).children('li').is('.'+_DF_hoverclass))
			$aktimer = _DF_obj.NavTimeout[0];
		if($(_eventobj).is('.'+_DF_hoverclass) || _DF_obj.$oldtimer != $aktimer){
			window.clearTimeout(_DF_obj._DF_NavTimeID);
			_DF_obj._DF_NavTimeID = window.setTimeout(_DF_obj._hide,$aktimer);
		}
		_DF_obj.$oldtimer = $aktimer;
	};
	this.$navstatus = function(_eventobj,$action){
		if($action == "show"){
			$(_eventobj).addClass(_waitingnavclass).removeClass(_DF_hideclass);
			if(_DF_obj._fastpullout(_eventobj))
				_DF_obj.$show();
		}else if($action == "hide")
			$(_eventobj).removeClass(_waitingnavclass).addClass(_DF_hideclass);
		_DF_obj.$fastpullin(_eventobj,'pullin');
	};	
	this.$show = function(){
		_showobj = $selektor+' li.'+_waitingnavclass;
		if(_DF_obj.Effect == 1 || _DF_obj.Effect == 2)
			$(_showobj+':not(.'+_DF_hoverclass+')>'+_DF_obj.ListType).addClass($nodisClass).CleanCSSAnimation(_DF_obj.ShowEffect,_DF_obj.EffectSpeed,function(){
   				$(this).removeClass($disClass);
 			});
		$(_showobj).removeClass(_waitingnavclass).addClass(_DF_hoverclass);
	};
	this._hide = function(){
		$hideobj = $selektor+' li.'+_DF_hideclass;
		if(_DF_obj.Effect == 1 || _DF_obj.Effect == 3)
			$($hideobj).removeClass(_DF_hideclass).children(_DF_obj.ListType).CleanCSSAnimation(_DF_obj.HideEffect,_DF_obj.EffectSpeed,function(){
   				$(this).removeClass($nodisClass).parent('li').removeClass(_DF_hoverclass);
				_DF_obj.$show();
 			});
		else{
			$($hideobj).removeClass(_DF_hoverclass+' '+_DF_hideclass);
			_DF_obj.$show();
		}
	};
	this.FitToScreen = function($liobj){
		var $subpos = $($liobj).addClass(_DF_hoverclass).children(_DF_obj.ListType).css('visibility','hidden').offset({scroll:false})['left'] + $($liobj).children(_DF_obj.ListType).outerWidth();
		if(_viewport < $subpos)
			$($liobj).children(_DF_obj.ListType).addClass(_DF_obj.Fit2ViewportClass);
	};
	if(_DF_obj.Fit2ViewportClass){
		var _viewport = $(document).innerWidth();
		_DF_obj.Fit2ViewportClass = (_viewport < _DF_obj.FitIfViewportSmaller) ? _DF_obj.Fit2ViewportClass : false;
	}
	//Init
	//Ready -> let´s go
	
	$($selektor+">"+_DF_obj.ListType).addClass(_jsreadyclass).find("li").each(function(){
		//Mouse Init
		$(this).hover(function() { 
				_DF_obj.$navstatus(this,'show');
			}, function() { 
				_DF_obj.$navstatus(this,'hide');
			}
		).addClass(_DF_parent_class).find('a').focus(function() {
			$(this).addClass($ofocusstyle);
			if(_DF_obj.LimitLinks < 1)
				$(this).parents('li').addClass(_DF_hoverclass);	
			else
				$(this).parents('li').filter(_DF_ActiveCatnAncestorsofIT[0]+','+_DF_ActiveCatnAncestorsofIT[1]).addClass(_DF_hoverclass);
		} ).blur(function() { 
			$(this).removeClass($ofocusstyle).parents("li").removeClass(_DF_hoverclass);
		});	
		if(_DF_obj.Fit2ViewportClass)
			_DF_obj.FitToScreen(this);
	});
	if(_DF_obj.Fit2ViewportClass)
		$($selektor+" li["+_DF_obj.ListType+"]").removeClass(_DF_hoverclass).children(_DF_obj.ListType).css('visibility','');
};
