/**
 * I provide an alternative method to $(document).ready() for attaching event handlers. Instead of
 * waiting for the entire DOM to load before attaching event listeners, I attach them as the DOM is
 * downloaded so there is no delay in attaching event listeners.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * @author      William Buick <wilbuick@gmail.com>
 * @copyright   Copyright (c) 2008 William Buick
 * @license     http://www.gnu.org/licenses/gpl.html
 * @version     $Id: $
 * @package     jquery
 * @subpackage  plugins.elementready
 */
(function($) {

    /**
     * I contain the number of micro seconds for the polling interval.
     *
     * @access private
     * @var int
     */
    var poll_interval = 100;

    /**
     * I contain the name of the class that the elementready callback attaches to elements that it
     * has already uncovered to prevent the callback being executed more than once for each element
     * that the selector matches. When the DOM has finished loading this class is removed from each
     * element.
     *
     * @access private
     * @var string
     */
    var found_element_class_prefix = 'jquery_elementready_';

    /**
     * I am a callback function that is called every specified interval to match elements within the
     * DOM and execute the callback function as each new element is uncovered.
     *
     * @access private
     * @param string query The jQuery attribute selector
     * @param function callback The callback function executed each time a new element is uncovered within the DOM
     * @return void
     */
    function matchElementsInDOM(query, callback, found_element_class)
    {
        $(query).each(function() {
            if ($(this).contents().length > 0 || $(this).parents().length > 0) {
                if (!$(this).hasClass(found_element_class)) {
                    callback.apply($(this).get(0));
                    $(this).addClass(found_element_class);
                }
            }
        });
    };

    $.extend({
        /**
         * I match elements within the dom and run a callback function everytime an element is
         * found. This is preformed as the DOM is being loaded to get around the problem of waiting
         * for the document to load when using the $(document).ready() method.
         *
         * @access public
         * @param string query jQuery attribute selector
         * @param function The callback function passed that is executed when an element in the dom is found
         * @return void
         */
        elementReady: function(query, callback)
        {
            var interval, found_element_class;

            found_element_class = found_element_class_prefix + Math.floor(Math.random() * 102400);

            interval = setInterval(function() { matchElementsInDOM(query, callback, found_element_class); }, poll_interval);

            $(document).ready(function() {
                matchElementsInDOM(query, callback, found_element_class);
                clearInterval(interval);

                $(query).each(function() {
                    $(this).removeClass(found_element_class);
                });
            });
        }

    });

})(jQuery);
