/**
 * @author trixta
 * Quelle: 
 * http://www.protofunc.com/2009/03/29/leichtgewichtiges-barrierearmes-generisches-hover-plugin-fur-jquery/
 */
(function($){
	/* 
	*	focusin/focusout von  jörn zaefferer´s delegate plugin
	*	 Copyright (c) 2007 Jörn Zaefferer
	*/

	$.each({
		focus: 'focusin',
		blur: 'focusout'	
	}, function( original, fix ){
		$.event.special[fix] = {
			setup:function() {
				if ( $.browser.msie ) return false;
				this.addEventListener( original, $.event.special[fix].handler, true );
			},
			teardown:function() {
				if ( $.browser.msie ) return false;
				this.removeEventListener( original,
				$.event.special[fix].handler, true );
			},
			handler: function(e) {
				arguments[0] = $.event.fix(e);
				arguments[0].type = fix;
				return $.event.handle.apply(this, arguments);
			}
		};
	});
	
	/*
	*  inout
	*  hover = focusblur
	*/
	var handler = {};
	$.each({enter: [1, 'in', true], out: [-1, 'out', false]}, function(handle, params){
		handler[handle] = function(e){
			var fn = e.data[0],
				o = e.data[1],
				pre = e.data[2],
				inOutData = e.data[3],
				elem = this
			;
			
			clearTimeout(inOutData.inOutTimer);
			if (params[2] != inOutData.inOutState && (params[2] || !o.bothOut || !inOutData.inEvents)) {
				pre.call(elem, e);
			}
			
			inOutData.inEvents = Math.max(inOutData.inEvents + params[0], 0);
			
			inOutData.inOutTimer = setTimeout(function() {
				if (params[2] != inOutData.inOutState && 
						(params[2] || !o.bothOut || !inOutData.inEvents)){
					inOutData.inOutState = params[2];
					e.type = params[1];
					fn.call(elem, e);
				}
			}, /focus/.test(e.type) ? o.keyDelay : o.mouseDelay);
			
		};
	});

	$.fn.inOut = function(enter, out, preEnter, preOut, opts){
		opts = $.extend({}, $.fn.inOut.defaults, opts);
		
		var inEvents = 'mouseenter focusin', 
			outEvents = 'mouseleave focusout'
		;
		if(opts.useEventTypes === 'mouse'){
			inEvents = 'mouseenter'; 
			outEvents = 'mouseleave'; 
		} else if(opts.useEventTypes === 'focus'){
			inEvents = 'focusin'; 
			outEvents = 'focusout'; 
		}
		
		return this
			.each(function(){
				var inOutData = {inEvents: 0};
				$(this)
					.bind(inEvents, [enter, opts, preEnter, inOutData], handler.enter)
					.bind(outEvents, [out, opts, preOut, inOutData], handler.out);
			});
	};
	$.fn.inOut.defaults = {
		mouseDelay: 0,
		keyDelay: 1,
		bothOut: false,
		useEventTypes: 'both' // both || mouse || focus
	};

})(jQuery);
