/**
 * @author Guy Fraser, Adaptavist.com Limited
 * 
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * Version: 1.1
 * 
 * Docs: http://www.adaptavist.com/display/free/jquery.eventdefer.js
 * 
 */

;(function( $ ) {

	// save some electrons
	var CT = clearTimeout;
	var ST = setTimeout;
	var AP = Array.prototype;

	$.each(['trigger','triggerHandler'],function(i,method){
		$.fn[method+'Defer'] = function(){
			var args = arguments;
			// event id
			var id = method+'Defer.'+args[0];
			// clear any untriggered event with this id
			CT(this.data(id));
			// set timer for our function
			var delay = (typeof(args[args.length-1])=='number') ? AP.pop.call(args) : 150;
			var self = this;
			this.data(id,ST(function() {
				self[method].apply(self,args);
			}, delay));
			return this;
		};
	});

	$.fn.bindDefer = function() { // event, data, handler, delay
		// make local arguments visible to action function
		var args = arguments;
		// work out delay
		var delay = (typeof(args[args.length-1])=="number") ? AP.pop.call(args) : 150;
		// store original handler
		var handler = AP.pop.call(args);
		// following function is what actually calls the event listener (after delay)
		var self = this;
		// add new delayed handler
		var timer;
		AP.push.call(args,function(){
			// clear any unhandled event
			CT(timer);
			// store args for event handler action
			args = arguments;
			// start action timer
			timer = ST(function() {
				handler.apply(self,args);
			},delay);
		});
		// bind our delayed action
		this.bind.apply(this,args);
		return this;
	};
		
})(jQuery);
