/**
 * @author Blue Ink Software
 * v. 1.0
 *
 * This jQuery plugin animates an image using a vertical image sprite
 * with each frame defined by a given "frameHeight" and the total frames.
 * The plugin will animate through the frames as many times as the
 * given "repeat" parameter.  Once the animation reaches the end
 * it will stop on the last frame.
 
 * The animation can either be setup to run on hover of the given
 * object or instantly once the plugin is setup.  You can also specify
 * that the animation runs on hover and/or automatically.  If a mode of both
 * is specified, the animation will be restarted on hover and will go
 * go back into automatic mode once the user's mouse moves out of the
 * hit area of the given object. If only hover mode is selected, once
 * the mouse is out of the hit area the animation stops and is reset
 * back to the first frame.
 *
 */
(function($)
{
    $.fn.frameAnimation = function(settings)
    {
        var config =
        {
            'mode': 'hover',   // Possible options are 'hover', 'auto', 'both'
            'delay': 50,       // Time in milliseconds between each frame
            'frameHeight': 0,  // Height of each frame
            'numFrames': 1,    // Total number of frames in the image sprite
            'hoverRepeat': 1,  // How many times each animation sequence runs when in hover mode
            'autoRepeat': 1,   // How many times each animation sequence runs when in auto mode 
            'startDelay': 500, // Delay before the first auto mode sequence is started
            'timeout': 4000    // Used when the mode is 'auto' or 'both'
                               // and represents the time in milliseconds between each
                               // total frame sequence If it is set to 0 then the
                               // animation runs constantly.  If set to -1 then the 
                               // animation is only run for one sequence
        };

        if (settings)
            $.extend(config, settings);

        settings = config;

        this.each(function()
        {
            var step = settings.frameHeight;
            var limit = settings.numFrames;
            var delay = settings.delay;
            var mode = settings.mode;

            var offset = 0;
            var currFrame = 1;
            var repeat = 1;
            var t = 0;

            function Clear(obj, resetFrame)
            {
                if (t) clearInterval(t); t = 0;
                offset = 0;
                currFrame = 1;
                repeat = 1;
                if (resetFrame)
                    obj.css("backgroundPosition", "0px 0px");
            }

            function BackgroundPosition(obj)
            {
                bgPos = obj.css('background-position');
                if (typeof (bgPos) === 'undefined') { bgPos = obj.css('background-position-x') + ' ' + obj.css('background-position-y') };
                return bgPos;
            }

            var MoveFrame = function(obj)
            {
                offset -= step;
                obj.css("backgroundPosition", "0px " + offset + "px");
            }

            var CheckMode = function(obj, numRepeat)
            {
                if (mode == 'auto' || mode == 'both')
                {
                    if (settings.timeout > 0)
                        t = setTimeout(function() { Animate(obj, numRepeat, true) }, settings.timeout);
                    else if (settings.timeout == 0)
                        Animate(obj, numRepeat, true);
                }
            }

            var Animate = function(obj, numRepeat, resetFrame)
            {
                if (t) clearInterval(t); t = 0;

                currFrame++;
                if (currFrame == limit)
                {
                    if (repeat < numRepeat)
                    {
                        repeat++;
                        obj.css("backgroundPosition", "0px 0px");
                        offset = 0;
                        currFrame = 1;
                        t = setTimeout(function() { Animate(obj, numRepeat, resetFrame) }, delay);
                    }
                    else
                    {
                        Clear(obj, resetFrame);
                        if (resetFrame)
                            CheckMode(obj, numRepeat);
                    }
                }
                else
                {
                    MoveFrame(obj);
                    t = setTimeout(function() { Animate(obj, numRepeat, resetFrame) }, delay);
                }
            }

            if (mode == 'hover' || mode == 'both')
            {
                // Set mouseover and mouseout functionality
                $(this).hover(function(evt)
                {
                    Clear($(evt.target), true);
                    Animate($(evt.target), settings.hoverRepeat, false);
                    return false;
                }, function(evt)
                {
                    Clear($(evt.target), true);
                    CheckMode($(evt.target), settings.autoRepeat);
                    return false;
                }
                );
                if (mode == 'both')
                {
                    var obj = $(this);
                    if (settings.startDelay > 0)
                        t = setTimeout(function() { Animate(obj, settings.autoRepeat, true) }, settings.startDelay);
                    else
                        Animate(obj, settings.autoRepeat, true);
                }
            }
            else if (mode == 'auto')
            {
                var obj = $(this);
                if (settings.startDelay > 0)
                    t = setTimeout(function() { Animate(obj, settings.autoRepeat, true) }, settings.startDelay);
                else
                    Animate(obj, settings.autoRepeat, true);
            }
        });
        return this;
    };
})(jQuery);
