var GAME_STATE_STOPPED = -1;
var GAME_STATE_FIRST_MOVE = 0;
var GAME_STATE_STARTED = 1;

var FIELD_EMPTY = 0;
var FIELD_PLAYER_X = 1;
var FIELD_PLAYER_O = -1;

function startGame()
{
    gameState = GAME_STATE_FIRST_MOVE;
    for (var i = 0; 9 > i; i++)
        setFieldValue(i, FIELD_EMPTY);
    board = [FIELD_EMPTY, FIELD_EMPTY, FIELD_EMPTY, FIELD_EMPTY, FIELD_EMPTY, FIELD_EMPTY, FIELD_EMPTY, FIELD_EMPTY, FIELD_EMPTY];
}

var gameState, board;
if (window.addEventListener)
    window.addEventListener('load', startGame, false); // The W3C DOM way
else
    window.onload = startGame; // The IE7 way

function printMessage(msg)
{
    var msgBox = document.getElementById('msgbox');
    msgBox.appendChild(document.createTextNode(msg));
    msgBox.appendChild(document.createElement('br'));
}

function setFieldValue(fieldNo, value)
{
    var textValue;
    switch (value) {
        case FIELD_EMPTY: textValue = ''; break;
        case FIELD_PLAYER_X: textValue = 'X'; break;
        case FIELD_PLAYER_O: textValue = 'O'; break;
    }
    var field = document.getElementById('a' + fieldNo);
    if (typeof field.textContent != 'undefined')
        field.textContent = textValue; // The W3C DOM way
    else
        field.innerHTML = textValue; // The IE7 way
}

function gameClick(field)
{
    // Can we move?
    if (gameState == GAME_STATE_STOPPED) {
        printMessage('Nulstil for at spille igen');
        return;
    }
    
    if (board[field]) {
        printMessage('Du kan ikke sætte X her');
        return;
    }
    
    // Make our move
    board[field] = FIELD_PLAYER_X;
    setFieldValue(field, FIELD_PLAYER_X);
    
    // Did we win?
    if (hasWinner()) {
        printMessage('Du vandt!');
        gameState = GAME_STATE_STOPPED;
        return;
    }
    
    // No, calculage computer's move
    var computermove = -1;
    if (gameState == GAME_STATE_FIRST_MOVE) {
        computermove = board[4] == FIELD_EMPTY ? 4 : 0;
        gameState = GAME_STATE_STARTED;
    } else {
        computermove = findBestMove(FIELD_PLAYER_O);
    }
    
    // Computer couldn't move, the game is over with no winner
    if (computermove == -1) {
        printMessage('Ingen vinder!');
        gameState = GAME_STATE_STOPPED;
        return;
    }
    
    // Make computer's move
    board[computermove] = FIELD_PLAYER_O;
    setFieldValue(computermove, FIELD_PLAYER_O);
    
    // Did the computer win?
    if (hasWinner()) {
        printMessage('Du tabte!');
        gameState = GAME_STATE_STOPPED;
    }
}

function findBestMove(player)
{
    var bestmove = -1;
    
    function findOutcome(player, ground)
    {
        var OUTCOME_UNDETERMINED = -2;
        var OUTCOME_OTHER_PLAYER_WINS = -1;
        var OUTCOME_GAME_OPEN = 0;
        var OUTCOME_PLAYER_WINS = 1;
        
        var bestOutcome = OUTCOME_UNDETERMINED;
        if (hasWinner()) return OUTCOME_OTHER_PLAYER_WINS;
        for (var i = 0; i < 9; i++) {
            if (board[i] != FIELD_EMPTY) continue;
            board[i] = player;
            var outcome = -findOutcome(-player, false);
            if (outcome > bestOutcome) {
                if (ground) bestmove = i;
                bestOutcome = outcome;
            }
            board[i] = FIELD_EMPTY;
            if (bestOutcome == OUTCOME_PLAYER_WINS) return OUTCOME_PLAYER_WINS;
        }
        if (bestOutcome == OUTCOME_UNDETERMINED) return OUTCOME_GAME_OPEN;
        return bestOutcome;
    }
    
    findOutcome(player, true);
    return bestmove;
}

function hasWinner()
{
    function isWinningPos(a, b, c)
    {
        return board[a] != FIELD_EMPTY && board[a] == board[b] && board[a] == board[c];
    }
    return (isWinningPos(0,3,6)|| isWinningPos(0,1,2) || isWinningPos(0,4,8) || isWinningPos(1,4,7) ||
        isWinningPos(2,5,8) || isWinningPos(2,4,6) || isWinningPos(3,4,5) || isWinningPos(6,7,8));
}

