
/////////////////////////////////////////////////////////////////////////////////////////////////
function AnimSOTB(canvas)
{
    var g = canvas;
    var firstUpdate = true;    
    
    // states
    var STATE_NONE = -1;
    var STATE_TITLE = 0;
    var STATE_INGAME = 1;
    var STATE_FOREST = 2;
    var STATE_INGAME2 = 3;
    var NUMBER_OF_STATES = 4;
    
    var m_stateDuration = new Array(NUMBER_OF_STATES);
    var states = new Array(NUMBER_OF_STATES);
    var m_nextState = new Array(NUMBER_OF_STATES);
        
    // state defs 
    m_stateDuration[STATE_TITLE] = 35/SPEEDER_SOTB;       m_nextState[STATE_TITLE] = STATE_INGAME;
    m_stateDuration[STATE_INGAME] = 128/SPEEDER_SOTB;     m_nextState[STATE_INGAME] = STATE_FOREST;
    m_stateDuration[STATE_FOREST] = 256/SPEEDER_SOTB;     m_nextState[STATE_FOREST] = STATE_INGAME2;
    m_stateDuration[STATE_INGAME2] = 128/SPEEDER_SOTB;     m_nextState[STATE_INGAME2] = STATE_NONE;
    var currentState = STATE_TITLE;    
    
    // calc complete length
    var DURATION = 0;
    for (var i = 0; i < m_stateDuration.length; i++)
    {
        DURATION+=m_stateDuration[i];
    }
    var m_duration = DURATION;    
    
    var m_needsUpdate = true;
    var m_timeLastChange = m_duration;
    
    // init color table
    var m_colTable = new cColorTable();
    m_colTable.Init(SCREEN_HEIGHT);
    m_colTable.AddColor(200,   200,    230); // start color
    m_colTable.AddRadiantTo(173,   173,    183,    5); 
    m_colTable.AddRadiantTo(154,   154,    165,    2);
    m_colTable.AddRadiantTo(122,   116,    152,    3);
    m_colTable.AddRadiantTo(229,   107,    146,    6);
    m_colTable.AddColor(108,   141,    0);
    m_colTable.AddRadiantTo(46,     68,    0,    7);    
    
    // offsets
    var offset_trees = SCREEN_WIDTH;
    var offset_mountain = 0;
    var offset_foreground = 0;
    var offset_clouds = 0;

    // enemy states
    var ENEMYSTATE_ATTACKING = 0;
    var ENEMYSTATE_DYING = 1;
    var ENEMYSTATE_NONE = 2;
    var ENEMYSTATE_WAITING = 3;
    
    var enemyState = ENEMYSTATE_NONE;
    
    ////////////////////////////////////    
    this.Reset = function()
    {
        firstUpdate = true;
        m_duration = DURATION;    
        currentState = STATE_TITLE;  
        m_needsUpdate = true;
        m_timeLastChange = m_duration;
        
        offset_trees = SCREEN_WIDTH;
        offset_mountain = 0;
        offset_foreground = 0;
        offset_clouds = 0;
        
        enemyState = ENEMYSTATE_NONE;
    }
    
    this.Update = function()
    {
        switch (currentState)
        {
            case STATE_TITLE:
            {
                if (m_needsUpdate == true)
                {
                    g.ClearScreen("#000000");
                    g.DrawSprite(SpriteBeast, 0, 1);
                }
            }
            break;
            case STATE_INGAME:
            case STATE_INGAME2:
            {
                DrawBkGradient();
                DrawClouds();
                DrawMountains();
                DrawBeast();
                DrawEnemy();
                DrawForeground();
            }
            break;
            case STATE_FOREST:
            {
                DrawBkGradient();
                DrawClouds();
                DrawMountains();
                DrawTrees();
                DrawBeast();
                DrawEnemy();
                DrawForeground();                
            }
            break;            
        }
        
        // automatic state change
        if ((m_timeLastChange - m_stateDuration[currentState]) >= m_duration)
        {
            currentState = m_nextState[currentState];
            m_timeLastChange = m_duration;
        }
        // timer
        m_duration--;
        if (m_duration <= 0)
        {
            return false;
        }
        return true;
    }    
    
    // specific helper functions
    function DrawBkGradient()
    {
      for (var y = SCREEN_HEIGHT-1; y >= 0; y--)
      {
        for (var x = SCREEN_WIDTH-1; x >= 0; x--)
        {
            g.PutPixel(x,y, m_colTable.GetColor(y));
        }
      }
    }
    
    ////////////////////////////////////////////////
    function DrawMountains()
    {
        g.DrawSprite(SpriteMountain, offset_mountain, 7);
        g.DrawSprite(SpriteMountain, offset_mountain + SpriteMountain.w, 7);
        
        offset_mountain-=1;
        if (offset_mountain <= -(SpriteMountain.w))
           offset_mountain = 0;        
    }
    ///////////////////////////////////////////////
    function DrawForeground()
    {
        var y = SCREEN_HEIGHT - SpriteFloor.h;
        g.DrawSprite(SpriteFloor, offset_foreground, y);
        g.DrawSprite(SpriteFloor, offset_foreground + SpriteFloor.w, y);
        
        offset_foreground-=8;
        if (offset_foreground <= -(SpriteFloor.w))
           offset_foreground = 0;       
    }
    ///////////////////////////////////////////////
    var offset_trees_stepsize = 2;
    function DrawTrees()
    {
        var y = 0;
        g.DrawSprite(SpriteTree, offset_trees, y);
        g.DrawSprite(SpriteTree, offset_trees + SpriteTree.w, y);

        offset_trees-=offset_trees_stepsize;
        
        var timeLeft = m_stateDuration[currentState] - (m_timeLastChange - m_duration);
        if (timeLeft > (SpriteTree.w) )
        {
            if (offset_trees <= -(SpriteTree.w))
               offset_trees = 0;       
        }
    }    
    ///////////////////////////////////////////////
    var offset_clouds_stepDevider = 2;
    function DrawClouds()
    {
        var y = 0;
        var x = Math.floor(offset_clouds/offset_clouds_stepDevider);
        g.DrawSprite(SpriteClouds, x, y);
        g.DrawSprite(SpriteClouds, x + SCREEN_WIDTH, y);

        offset_clouds-=1;
        
        if (offset_clouds <= -(SCREEN_WIDTH*offset_clouds_stepDevider))
           offset_clouds = 0;       
    }     
    ///////////////////////////////////////////////

    var enemyPosX = 0;
    var enemyStdPosY = 10;
    var enemyPosY = 0;
    var randOffset = 0;
    var jumpSpeed = 0;
    var wait = 0;
    
    var ENEMYTYPE_STONE = 0;
    var ENEMYTYPE_CREATURE = 1;
    var NUMBER_OF_ENEMYTYPES = 2;
    var enemyType = 0;
    
    function DrawEnemy()
    {
        var x = 0;
        var y = 0;
        switch (enemyState)
        {
            case ENEMYSTATE_NONE:
            {
                enemyState = ENEMYSTATE_ATTACKING;
                enemyPosX = SCREEN_WIDTH;
                enemyPosY = enemyStdPosY;
                randOffset = Math.random()*2.5;
                jumpSpeed = 1.5 + Math.random();
                enemyType = Math.floor(Math.random()*NUMBER_OF_ENEMYTYPES);
            }
            break;
            case ENEMYSTATE_ATTACKING:
            {
                enemyPosX-=2;
                y = Math.round(5*Math.sin((enemyPosX+randOffset)/jumpSpeed));
                if (enemyPosX < (4+SpriteB0000.w))
                    enemyState = ENEMYSTATE_DYING;
            }
            break;
            case ENEMYSTATE_DYING:
            {
                enemyPosX++;
                enemyPosY+=3;
                if (enemyPosY > SCREEN_HEIGHT)
                {
                    enemyState = ENEMYSTATE_WAITING;
                    wait = Math.random()*15;
                }
            }
            break;
            case ENEMYSTATE_WAITING:
            {
                wait--;
                if (wait<0)
                    enemyState = ENEMYSTATE_NONE;
            }
            break;
        }
        
        switch (enemyType)
        {
            case ENEMYTYPE_STONE:
                g.DrawSprite(SpriteStones, enemyPosX + x, enemyPosY + y);
                break;
            case ENEMYTYPE_CREATURE:
                g.DrawSprite(SpriteEnemy, enemyPosX + x, enemyPosY + Math.round(y/8));
                break;
        }
        
    }   
    ////////////////////////////////////////////////
    var spriteArray = new Array(6);
    spriteArray[0] = SpriteB0000;
    spriteArray[1] = SpriteB0001;
    spriteArray[2] = SpriteB0002;
    spriteArray[3] = SpriteB0003;
    spriteArray[4] = SpriteB0004;
    spriteArray[5] = SpriteB0005;
    var offset_Beast = 0;
    var offset_Beast_Stepsize = 1;
    var offset_Beast_Max = spriteArray.length*offset_Beast_Stepsize;
    
    function DrawBeast()
    {
        var index = Math.floor(offset_Beast/offset_Beast_Stepsize);
        g.DrawSprite(spriteArray[index], 4, 11);
        offset_Beast++;
        if (offset_Beast>=offset_Beast_Max)
            offset_Beast = 0;
    }
}


