// X. Show vertical bar for score with icon at top
// X. Keep minimum score at 0
// X. The bomb - larger penalty, opposite shape
// X. Levels with time or score upper limit
// X. Increase speed over levels
// X. Vary speed within the level
// X. Show timer to count down from 10 to times up
// X. Show after level screen with scores
// X. Splash screen with preloaded graphics
// 3. Change image of player on success or failure with little animation

var currentWidth = 0;
var currentOrient;
var currentScore;
var goodGreenHits,goodBlueHits,badGreenHits,badBlueHits;
var currentLevel;
var levelIndex = 0;
var countdownLength = 5;

var tokenQueueIndex = -1;
var tokenCount = 4;
var tokensInPlay = [];
var tokenPool = {};

var animationTimer;
var countdownTimer;
var releaseCountdown;
var tokenCountdown;
var tokenYDest;
var awaitTilt = true;

var player = document.getElementById("player");
var scoreBar = document.getElementById("scoreBar");
var scoreBarBack = document.getElementById("scoreBarBack");

// *************************************************************************************************

function Token(type, orient, speed, delay, points)
{
    var tk = function(speed, delay, points) { return Token(type, orient, speed, delay, points); }
    tk.type = type;
    tk.orient = orient;
    tk.speed = speed;
    tk.delay = delay;
    tk.points = points;
    return tk;
}

// *************************************************************************************************

addEventListener("load", function(event)
{
    setTimeout(function()
    {
        checkOrient();
        setInterval(checkOrient, 300);
    }, 0);

}, false);

function checkOrient()
{
    if (window.innerWidth != currentWidth)
    {
        if (currentWidth && awaitTilt)
        {
            awaitTilt = false;
            playNextLevel();
        }
        
        currentWidth = window.innerWidth;
        if (currentWidth == 320)
        {
            currentOrient = "portrait";
            recenterPlayer(129, 355, player.offsetLeft, player.offsetTop, 0);
        }
        else
        {
            currentOrient = "landscape";
            recenterPlayer(212, 207, player.offsetLeft, 207, 80);
        }
        
        document.body.setAttribute("orient", currentOrient);
        setTimeout(scrollTo, 0, 0, 1);
    }
}

function recenterPlayer(x, y, x1, y1, offset)
{
    var percent = 0;
    
    player.style.left = x + "px";
    player.style.top = y + "px";
    tokenYDest = y;
    
    for (var i = 0; i < tokensInPlay.length; ++i)
    {
        var token = tokensInPlay[i];
        var newY = y - ((y1)+offset - parseInt(token.style.top));
        token.style.top = newY + "px";
    }

    // var xd = x - x1, yd = y - y1;
    // var timer = setInterval(function()
    // {
    //     percent += 20;
    //     if (percent >= 100)
    //     {
    //         percent = 100;
    //         clearInterval(timer);            
    //     }
    // 
    //     player.style.left = (x1 + (xd * (percent/100))) + "px";
    //     player.style.top = tokenYDest + "px";
    // }, 0);
}

// *************************************************************************************************

function playNextLevel()
{
    for (var i = 0; i < tokensInPlay.length; ++i)
    {
        var token = tokensInPlay[i];
        token.style.display = "none";
    }
    
    tokensInPlay = [];

    var level = levelData[levelIndex];
    if (level)
        startLevel(level());
}

function startLevel(level)
{
    currentLevel = level;
    currentScore = goodBlueHits = goodGreenHits = badBlueHits = badGreenHits = 0;
    tokenIndex = 0;
    tokenCountdown = level.tokens.length;
    
    releaseToken();
    animationTimer = setInterval(animationLoop, 0);

    $("levelScreen").style.display = $("nextMessage").style.display = "none";
    $("splashScreen").style.display = "none";
}

function endLevel()
{
    clearInterval(animationTimer);
    clearTimeout(countdownTimer);
    
    if (currentScore < currentLevel.winningScore)
    {
        awaitTilt = true;
        $("nextMessage").innerHTML = "ALMOST! TILT TO REPLAY LEVEL";
    }
    else
    {
        if (++levelIndex <= levelData.length)
        {
            awaitTilt = true;
            $("nextMessage").innerHTML = "FANTASTIC! TILT TO PLAY NEXT LEVEL";
        }
        else
            $("nextMessage").innerHTML = "GAME OVER";
    }

    $("goodBluePoints").innerHTML = goodBlueHits;
    $("goodGreenPoints").innerHTML = goodGreenHits;
    $("badBluePoints").innerHTML = badBlueHits;
    $("badGreenPoints").innerHTML = badGreenHits;
    $("levelScreen").style.display = $("nextMessage").style.display = "block";
    $("countdown").innerHTML = "";
}

// *************************************************************************************************

function createToken(tokenInfo)
{
    var pool = tokenPool[tokenInfo.type];
    if (!pool)
        pool = tokenPool[tokenInfo.type] = [];

    if (pool.length)
        return pool.pop()
    else
    {
        token = document.createElement("token");
        document.body.appendChild(token);
        token.className = "token " + tokenInfo.type;
        token.pool = pool;
        return token;
    }
}

function releaseToken()
{
    var tokenInfo = currentLevel.tokens[tokenIndex++];
    if (tokenInfo)
    {
        var token = createToken(tokenInfo);
        tokensInPlay.splice(0, 0, token);

        token.style.top = -token.offsetHeight + "px";
        token.style.display = "block";

        var offset = currentOrient == "portrait" ? -18 : -30;
        tokenYDest = player.offsetTop - (token.offsetHeight+offset);

        token.points = tokenInfo.points
            ? tokenInfo.points
            : 1;

        token.speed = tokenInfo.speed
            ? tokenInfo.speed * currentLevel.speed
            : currentLevel.speed;

        releaseCountdown = tokenInfo.delay
            ? tokenInfo.delay * currentLevel.delay
            : currentLevel.delay;
        
        token.orient = tokenInfo.opposite == "opposite"
            ? (currentOrient == "portrait" ? "landscape" : "portrait")
            : tokenInfo.orient;
    }
}

function scoreToken(token, hit)
{
    tokensInPlay.pop();
    token.pool.push(token);
    token.style.display = "none";
        
    if (hit)
    {
        if (currentOrient == "portrait")
            ++goodGreenHits;
        else
            ++goodBlueHits;
    }
    else
    {
        if (currentOrient == "portrait")
            ++badBlueHits;
        else
            ++badGreenHits;
    }
        
    var points = hit ? token.points : -token.points;
    currentScore = Math.max(currentScore + points, 0);
    
    player.setAttribute("hit", hit ? "good" : "bad")
    setTimeout(function() { player.removeAttribute("hit"); }, 220);
    
    var height = scoreBarBack.offsetHeight * (currentScore/currentLevel.winningScore);
    var top = (scoreBarBack.offsetTop + scoreBarBack.offsetHeight) - height;
    scoreBar.style.top = top + "px";
    scoreBar.style.height = height + "px";
    
    if (--tokenCountdown == 0 || currentScore >= currentLevel.winningScore)
        endLevel();
    else if (tokenCountdown == countdownLength)
        startCountdown();
}

function startCountdown()
{
    var count = countdownLength*2 + 1;
    function counter()
    {
        if (--count % 2)
            $("countdown").innerHTML = "";
        else
            $("countdown").innerHTML = count/2;

        if (count)
            countdownTimer = setTimeout(counter, 500);
        else
        {
            $("countdown").innerHTML = "";
            endLevel();
        }
    }
    
    counter();
}

function animationLoop()
{
    if (--releaseCountdown == 0)
        releaseToken();
        
    for (var i = 0; i < tokensInPlay.length; ++i)
    {
        var token = tokensInPlay[i];
        var y = parseFloat(token.style.top) + token.speed;
        if (y >= tokenYDest)
        {
            var hit = token.orient == currentOrient;
            scoreToken(token, hit);
            --i;
        }
        else
            token.style.top = y + "px";
    }
}

function $(id)
{
    return document.getElementById(id); 
}
