﻿// The various loop modes
var CssSpriteAnimatorLoopMode = {RestartFromBegining : 1, BackAndForth : 2};
var AnimationDoneBehaviorMode = {Hide : 0, FadeOut : 1};

// Initialize and start CssSpriteAnimator with the specified clientId
function CssSpriteAnimator(clientId)
{
    this.clientId = clientId;
    this.spriteDiv = $(clientId + '_spriteDiv');
    this.frameCount = parseInt($(clientId + '_hiddenFrameCount').value);
    this.frameDelayMs = parseInt($(clientId + '_hiddenFrameDelayMs').value);
    this.loopMode = parseInt($(clientId + '_hiddenLoopMode').value);
    this.frameWidth = parseInt($(clientId + '_hiddenFrameWidth').value);
    this.currentFrame = 0;
    this.frameDelta = 1;
    this.spriteDiv.style.visibility = 'visible';
    this.loops = 0;
    this.loopCount = parseInt($(clientId + '_hiddenLoopCount').value);
    this.animationDoneBehavior = parseInt($(clientId + '_hiddenAnimationDoneBehavior').value);
    // Start the animation
    var _this = this;
    this.advanceToNextFrameInterval = setInterval('getSingleton(CssSpriteAnimator, "' + _this.clientId + '").advanceToNextFrame();', _this.frameDelayMs);
}

// Advance to the next frame based upon the animation settings of this CssSpriteAnimator
CssSpriteAnimator.prototype.advanceToNextFrame = function()
{
    // Incrementing frames?
    if (this.frameDelta == 1)
    {
        // Last frame?
        if (this.currentFrame == this.frameCount)
        {
            // Restart the animation from the begining?
            if (this.loopMode == CssSpriteAnimatorLoopMode.RestartFromBegining)
            {
                this.currentFrame = 1;
            }
            else // BackAndForth : reverse the animation
            {
                this.currentFrame--;
                this.frameDelta = -1;
            }
        }
        else // just increment to the next frame
        {
            this.currentFrame++;
        }
    }
    else // decrementing frames ...
    {
        // First frame?
        if (this.currentFrame == 1)
        {
            // Reverse the animation
            this.frameDelta = 1;
            this.currentFrame++;
        }
        else // just decrement to the next frame
        {
            this.currentFrame--;
        }
    }
    
    // Update the position of the background image so that the current frame is showing
    this.spriteDiv.style.backgroundPosition = ((this.currentFrame-1) * -this.frameWidth).toString() + 'px 0px';
    
    // Count this animation loop, and check if the animation should stop
    this.loops++;
    if (this.loops >= this.loopCount && this.loopCount != -1) // reached the maximum number of animation loops?
    {
        clearInterval(this.advanceToNextFrameInterval); // stop the animation interval
        this.performAnimationDoneBehavior();
    }
}

// Perform the "animation done" behavior
CssSpriteAnimator.prototype.performAnimationDoneBehavior = function()
{
    if (this.animationDoneBehavior == AnimationDoneBehaviorMode.Hide)
    {
        this.spriteDiv.style.visibility = 'hidden';
    }
    else if (this.animationDoneBehavior == AnimationDoneBehaviorMode.FadeOut)
    {
        this.startFadeOut();
    }    
}

// Start a fade out animation of this sprite
CssSpriteAnimator.prototype.startFadeOut = function()
{
    this.fadeOutOpacity = 1.0; 
    setElementOpacity(this.spriteDiv, this.fadeOutOpacity);
    var _this = this;
    this.fadeOutInterval = setInterval(function() { _this.updateFadeOut(); }, 30);
}

// Update the fade out of this sprite
CssSpriteAnimator.prototype.updateFadeOut = function()
{
    // Still fading?
    if (this.fadeOutOpacity > 0.0)
    {
        // Fade-in 1 more step
        this.fadeOutOpacity = this.fadeOutOpacity - 0.15;
        this.fadeOutOpacity = Math.max(this.fadeOutOpacity, 0.0);
        setElementOpacity(this.spriteDiv, this.fadeOutOpacity);
    }
    else // Done fading ...
    {
        clearInterval(this.fadeOutInterval);
        this.spriteDiv.style.visibility = 'hidden';
    }
}
