
/////////////////////////////////////////////////////////////////////////////////////////////////
function AnimAgony(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_AGONY;       m_nextState[STATE_TITLE] = STATE_INGAME;
    m_stateDuration[STATE_INGAME] = 128/SPEEDER_AGONY;     m_nextState[STATE_INGAME] = STATE_FOREST;
    m_stateDuration[STATE_FOREST] = 256/SPEEDER_AGONY;     m_nextState[STATE_FOREST] = STATE_INGAME2;
    m_stateDuration[STATE_INGAME2] = 128/SPEEDER_AGONY;     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;
    
    
    // sprites
    var waves = new Array(5);
    waves[0]=SpriteAwav0000;
    waves[1]=SpriteAwav0001;
    waves[2]=SpriteAwav0002;
    waves[3]=SpriteAwav0003;
    waves[4]=SpriteAwav0004;
    
    
    // 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;
        
        counter = 0;
        
        enemyState = ENEMYSTATE_NONE;
    }
    
    this.Update = function()
    {
        switch (currentState)
        {
            case STATE_TITLE:
            {
                if (m_needsUpdate == true)
                {
                   //.ClearScreen("#000000");
                    g.DrawSprite(SpriteAgony,0, 0);
                }
            }
            break;
            case STATE_INGAME:
            case STATE_INGAME2:
            case STATE_FOREST:
            {
                DrawBkGradient();
                DrawTrees();
                DrawWaves();
                DrawShots();
                DrawEnemies();
                DrawOwl();

            }
            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()
    {
        var x = Math.floor(offset_mountain);
        g.DrawSprite(SpriteAgonybk, x, 0);
        g.DrawSprite(SpriteAgonybk, x+SpriteAgonybk.w, 0);
        offset_mountain-=0.5;
        if (offset_mountain < -SpriteAgonybk.w)
            offset_mountain = 0;
    }
    
    var waveIndex = 0;
    var waveOffset = 0;
    
    function DrawWaves()
    {
        var sprite = waves[waveIndex];
        var x = waveOffset;
  
        var y = SCREEN_HEIGHT - sprite.h ;
        while (x < SCREEN_WIDTH)
        {
            g.DrawSprite(sprite, x, y);
            x+=sprite.w;
           }
        if (waveOffset<-sprite.w)
            waveOffset = 0;
        waveIndex++;
        if (waveIndex>=waves.length)
            waveIndex = 0;
    }
    
    ////////////////////////////////////////////////
    var treeindex = 0;
    function DrawTrees()
    {
        g.DrawSprite(SpriteAgonytree, treeindex, 0);
        g.DrawSprite(SpriteAgonytree, treeindex + SpriteAgonytree.w, 0);
        treeindex-=3;
        if (treeindex < -SpriteAgonytree.w)
            treeindex = 0;
    }

    ////////////////////////////////////////////////
    var spriteArray = new Array(4);
    spriteArray[0] = SpriteOwl1;
    spriteArray[1] = SpriteOwl2;
    spriteArray[2] = SpriteOwl3;
    spriteArray[3] = SpriteOwl2;
    var offsetX = 3;
    var offsetY = 5;
    var offset_Beast_Stepsize = 1;
    var offset_Beast_Max = spriteArray.length*offset_Beast_Stepsize;
    var offset_Beast = 0;
    
    var offset_shot = 0;
    
    var sinVal = 0;
    var owlY = 0;
    var owlX = 0;
    
    var owlSecY = 0;
    
    var currentOwlAmp = 6;
    
    function DrawOwl()
    {
        var index = Math.floor(offset_Beast/offset_Beast_Stepsize);
        var sprite = spriteArray[index];
        owlX = 4;
        owlY = owlSecY + Math.floor((SCREEN_HEIGHT/4) + (currentOwlAmp*Math.sin(sinVal))) + 1;
      
        if (owlY < 0 ) 
            owlY = 0;
        if (owlY > (SCREEN_HEIGHT - sprite.h))
            owlY = SCREEN_HEIGHT - sprite.h;
        
        y = owlY;        
        
        if (currentEnemyX < 12)
        {
            
            if (currentEnemyY < SCREEN_HEIGHT/2)
                owlSecY++;
            else
                owlSecY--;
        }
        else
        {
            if (owlSecY>0)
                owlSecY--;
            if (owlSecY<0)
                owlSecY++;
        }
        
        // collision??
        
      
        var owl1_x = owlX;
        var owl1_y = owlY;
        var owl2_x = owlX + sprite.w;
        var owl2_y = owlY;
        var owl3_x = owlX + sprite.w;
        var owl3_y = owlY + sprite.y;
        var owl4_x = owlX;
        var owl4_y = owlY + sprite.y;                        
        
        var owlHit = false;
        var enemyS = enemies[currentEnemy];
        owlHit |= TestBB(owl1_x, owl1_y, currentEnemyX, currentEnemyY, enemyS.w, enemyS.h);
        owlHit |= TestBB(owl2_x, owl2_y, currentEnemyX, currentEnemyY, enemyS.w, enemyS.h);
        owlHit |= TestBB(owl3_x, owl3_y, currentEnemyX, currentEnemyY, enemyS.w, enemyS.h);
        owlHit |= TestBB(owl4_x, owl4_y, currentEnemyX, currentEnemyY, enemyS.w, enemyS.h);
        
        if (owlHit == true)
        {
            ResetEnemy();
            g.DrawSpriteMask(sprite, owlX, y, "#FFFFFF");
            
        }
        else
            g.DrawSprite(sprite, owlX, y);
            
        offset_Beast++;
        if (offset_Beast>=offset_Beast_Max)
            offset_Beast = 0;
        
          
        sinVal+=0.18;
        if (sinVal > (Math.PI*2))
        {
            sinVal -= Math.PI*2;
            currentOwlAmp = Math.random() * 6;
        }
    }
    
    var currentShot = 0;
    var shotPos = new Array(2);
    shotPos[0] = new Array(-1,0);
    shotPos[1] = new Array(-1,0);
    
    var shotCounter = 0;
    
    function DrawShots()
    {
   
        if (shotCounter == 0)
        {
            shotCounter = 3;
            shotPos[currentShot][0] = owlX+6;
            shotPos[currentShot][1] = owlY+2;
            currentShot++;
            if (currentShot>=shotPos.length)
                currentShot = 0;
        }
        shotCounter--;
        
        for (var i = 0; i < shotPos.length; i++)
        {
//             DebugOut(shotPos[i][0] + "," + shotPos[i][1]);
            if (shotPos[i][0]<0)
                continue;
            g.DrawSprite(SpriteAshot, shotPos[i][0], shotPos[i][1]);
            shotPos[i][0]+=5;
            if (shotPos[i][0]>SCREEN_WIDTH)
                shotPos[i][0] = -1;           
        }
    }
    
    
    var enemies = new Array(2);
    enemies[0] = SpriteAgonye1;
    enemies[1] = SpriteAgonye2;
    
    var currentEnemy = 0;
    var currentEnemyX = SCREEN_WIDTH;
    var currentEnemyY = 0;
    
    var enemyHits = 0;
    
    var currentEnemyStartY = 5;
    
    var shotRefX = Math.floor(SpriteAshot.w/2);
    var shotRefY = Math.floor(SpriteAshot.h/2);
    
    var counter = 0;
    
    function ResetEnemy()
    {
        // reset enemy
        currentEnemy = Math.floor(Math.random() * enemies.length);
        currentEnemyX = SCREEN_WIDTH;
        currentEnemyStartY = enemies[currentEnemy].w + Math.floor((SCREEN_HEIGHT - (enemies[currentEnemy].w*2))*Math.random());
        enemyHits = 0;     
    }
    
    function DrawEnemies()
    {
        // move enemy
        currentEnemyX--;
            
        counter++;
        
        if (enemyHits >= 2 || currentEnemyX < -enemies[currentEnemy].w)
        {
            ResetEnemy();
        }
        
        currentEnemyY = currentEnemyStartY + Math.floor(enemies[currentEnemy].w * Math.sin(counter/10));            
        
        // check shot
        
        var enemyHit = false;
        
        var sprite = enemies[currentEnemy];
        
        for (var i = 0; i < shotPos.length; i++)
        {
            // shot bb
            var shotX = shotPos[i][0];
            var shotY = shotPos[i][1];
            var shot1X = shotX + SpriteAshot.y;
            var shot1Y = shotY;
            var shot2X = shotX + SpriteAshot.w;            
            var shot2Y = shotY + SpriteAshot.h;          
            var shot3X = shotX + SpriteAshot.w;            
            var shot3Y = shotY;                   
            
            enemyHit = TestBB(shotX, shotY, currentEnemyX, currentEnemyY, sprite.w, sprite.h);      
            enemyHit |= TestBB(shot1X, shot1Y, currentEnemyX, currentEnemyY, sprite.w, sprite.h);      
            enemyHit |= TestBB(shot2X, shot2Y, currentEnemyX, currentEnemyY, sprite.w, sprite.h);    
            enemyHit |= TestBB(shot3X, shot3Y, currentEnemyX, currentEnemyY, sprite.w, sprite.h);    
            
            if (enemyHit == true)
                shotPos[i][0] = -1;
        }
        
        if (false == enemyHit)
        {
            g.DrawSprite(sprite, currentEnemyX, currentEnemyY);
        }
        else
        {
            g.DrawSpriteMask(sprite, currentEnemyX, currentEnemyY, "#FFFFFF");
            enemyHits++;
        }
    

        
    }
    
    function TestBB(x,y,bx,by,bw,bh)
    {
        b2x = bx+bw;
        b2y = by+bh;
        
        return (x>=bx && x <= b2x && y >= by && y <= b2y);    
    }
    
}



