if (typeof AF == 'undefined') {
    AF = {
        util:       {},
        effects:    {}
    };
}

/**
 * Get the index of the given element in the given array
 *
 * @param mixed $needle The element to search for
 * @param object $haystack The array (or whatever) to search for needle in
 * @return mixed The key or index under which needle was found, or undefined if it wasn't
 */
AF.util.indexOf = function(needle, haystack) {
    for (key in haystack) {
        if (haystack[key] == needle) {
            return key;
        }
    }
};

/**
 * Does an object contain the given element?
 *
 * @param mixed $needle The element to search for
 * @param object $haystack The array (or whatever) to search for needle in
 * @return bool true if haystack was found in needle, otherwise, false
 */
AF.util.contains = function(needle, haystack) {
    return typeof AF.util.indexOf(needle, haystack) != 'undefined';
};

/**
 * Class for preloading images
 */
AF.effects.ImagePreloader = function() {
    this._urls = [];
    this._state = 'ready';
};
AF.effects.ImagePreloader.prototype = {
    /**
     * Add the URL for one image
     *
     * @param string $url the URL of the image to add
     */
    addUrl: function(url) {
        if (this._state != 'ready') {
            throw("can only add an URL in the 'ready' state!");
        }

        if (!AF.util.contains(url, this._urls)) {
            this._urls.push(url);
        }
    },

    /**
     * Add the URLs for several images
     *
     * @param array $urls Array of image URLs to add
     */
    addUrls: function(urls) {
        if (this._state != 'ready') {
            throw("can only add URLs in the 'ready' state!");
        }

        for (i = 0; i < urls.length; i++) {
            if (!AF.util.contains(urls[i], this._urls)) {
                this._urls.push(urls[i]);
            }
        }
    },

    /**
     * Start preloading the images whose URLs have been added
     */
    run: function() {
        this._nImages = this._urls.length;
        this._nImagesDone = 0;
        
        this._setState('loading');

        for (var i = 0; i < this._nImages; i++) {
            var img = new Image();
            img.src = this._urls[i];
        }
    },

    /**
     * Get this preloader's state
     *
     * State can be one of the following:
     * <ul>
     *     <li><b>ready:</b> nothing's been done yet; image URLs can still be added</li>
     *     <li><b>loading:</b> the images are being loaded; no new URLs can be added</li>
     *     <li><b>done:</b> all images have loaded or errored out; no new URLs can be added</li>
     * </ul>
     *
     * @return string The preloader's current state
     */
    getState: function() {
        return this._state;
    },

    _setState: function(state) {
        if (this._state != state) {
            evtData = {
                oldState:   this._state,
                newState:   state
            };

            this._state = state;
        }
    }
};
            
