﻿/**
	* function: delayCloseHover
	* Arguements: (int) delay, (function) mouse over, (function) mouse out
	*
	* Description:
	* Even function, delays the call to the mouse out event
	*
	* Returns: (function)
	*/
( function( $ ) {
	$.fn.delayCloseHover = function( delay_ms, over_fn, out_fn ) {

		var sys_config = {
			timeout: delay_ms,
			over: over_fn,
			out: out_fn
		};

		var handleHover = function( e ) {

			var parent_elem = ( e.type == "mouseover" ? e.fromElement : e.toElement ) || e.relatedTarget;

			while( parent_elem && parent_elem != this ) {

				try {

					parent_elem = parent_elem.parentNode;
				} catch( e ) {

					parent_elem = this;
				}
			}

			if( parent_elem == this ) {

				return false;
			}

			var obj = this;

			if( this.hover_to_status ) {

				obj.hover_to_status = clearTimeout( obj.hover_to_status );
			}

			if( e.type == "mouseover" ) {

				if( obj.hover_status != 1) {

					obj.hover_status = 1;
					sys_config.over.apply( obj, [e] );
				}

			} else {

				if( obj.hover_status == 1 ) {

					obj.hover_to_status = setTimeout( function(){ delay_here( e, obj ); } , sys_config.timeout );
				}
			}
		};

		var delay_here = function( ev, obj ) {

			obj.hover_to_status = clearTimeout( obj.hover_to_status );
			obj.hover_status = 0;
			return sys_config.out.apply( obj, [ev] );
		};

		return this.mouseover( handleHover ).mouseout( handleHover );
	};
} )( jQuery );
