/**
 * ReadyAgain
 * 
 * jQuery plugin to allow the re-execution of the <code>ready</code> function.
 * 
 * @author William King
 * @version 1.0.0
 * 
 */
(function ($) {

	// Save the jQuery 'ready' function
	var jqReady = $.fn.ready,
		ourReadyList = [];
		
	// Overwrite the jQuery 'ready' function with our own
	$.fn.ready = function()
	{
		// If an extra boolean parameter, that evaluates to 'false', is added to the call
		// to 'ready', then we do NOT save it for re-execution. This is required especially
		// for 'ReadyAgain' in order to prevent an endless loop of re-execution.
		if(arguments.length == 2 && typeof arguments[1] == 'boolean' && arguments[1] === false)
			return jqReady.apply(this,arguments);
		
		// jQuery 'ready' pushes the supplied function into an Array, so
		// we save the origingal Array 'push' method and...
		var arrayPush = Array.prototype.push, result;
		
		// ...overwrite the Array 'push' method with our own, saving the 'pushed'
		// function to our own array (i.e. intercept Array.push)
		Array.prototype.push = function()
		{
			// save 'pushed' function to our own array using original Array.push
			arrayPush.apply(ourReadyList,arguments);
			
			// Use the original Array.push on jQuery's 'readyList' and return 
			// the result as normal
			return arrayPush.apply(this,arguments);
		};
		
		// Execute the original jQuery.ready method
		result = jqReady.apply(this,arguments);
		
		// Restore Array.push method to its original state
		Array.prototype.push = arrayPush;

		// Return the jQuery.ready method result
		return result;
	};

	/**
	 * <code>$('selector').ReadyAgain()</code>:
	 * <br> 
	 * 	Will execute previously saved 'ready' functions	within the context of each element 
	 * 	returned by the jQuery 'selector'.
	 * <br><br>
	 * <code>$.fn.ReadyAgain()</code>:
	 * <br>
	 * 	Will execute previously saved 'ready' functions within the 'document' context
	 * <br><br>
	 * <b>!! IMPORTANT !!</b>
	 * <br>
	 * ALWAYS add the boolean 'false' as a second argument to the jQuery.ready function
	 * in which ReadyAgain executes. This prevents an endless loop of re-execution.
	 * <br>
	 * <code>
	 *   $(document).ready(function()
	 *   {
	 *     $.fn.ReadyAgain();
	 *    
	 *   }, false);
	 * </code>
	 */
	$.fn.ReadyAgain = function()
	{
		// If called directly (e.g. $.fn.ReadyAgain(), will re-execute saved 
		// 'ready' functions within the document context.		
		if(this.length == 0)
			return $(document).ReadyAgain();

		this.each(function()
		{
			// Execute each of the saved functions
			for(var i in ourReadyList)
				ourReadyList[i].call(this,$);
		});
		
		return this;
	};
	
})(jQuery);

