/*
 * Javascript MineSweeper v0.2
 * http://labs.ugolandini.com/minesweeper
 *
 * Copyright (c) 2010 Ugo Landini
 * Dual licensed under the MIT and GPL licenses.
 * http://labs.ugolandini.com/license/GPL-LICENSE.txt
 * http://labs.ugolandini.com/license/MIT-LICENSE.txt
 *
 * Date:            2010-01-10
 * Last updated:    2010-01-10
 */

function MineField(timerElement, rows, columns, bombs) {

    this.startedTimer = false;
    this.timerElement = $(timerElement);
    this.firstClick = true;
    this.table = null;
    this.x = rows + 2;
    this.y = columns + 2;
    this.bombs = Math.max(0,Math.min(bombs, rows * columns / 3));
    this.toBeShown = (rows*columns) - this.bombs;
    this.init();
    this.adjournGameNumbers();

}

MineField.prototype.forEveryMineCell = function(fn) {

    for (var row = 0; row < this.field.length; row++) {
        for (var col = 0; col < this.field[row].length; col++) {
            fn.call(this, row, col);
        }
    }

};

MineField.prototype.adjournGameNumbers = function() {


    var shown = $(".shown").length;
    var flags = $(".flagged").length;

    var bombsRemaining = this.bombs - flags;

    var bombsElement = $("#bombsRemaining");
    bombsElement.text(bombsRemaining);

    if (shown == this.toBeShown) {
        MineTimer.stopTimer();
        Utilities.gameWon();
        MineTimer.resetTimer();
    }

};

MineField.prototype.init = function() {

    MineTimer.init(this.timerElement);
    this.field = new Array(this.x);
    for (var i = 0; i < this.field.length; i++)
        this.field[i] = new Array(this.y);


    this.forEveryMineCell(function(row, col) {
        this.field[row][col] = new MineCell(this, row, col);
    });

};

MineField.prototype.clearGame = function() {

    this.forEveryMineCell(function(row, col) {
        (this.field[row][col]).clear();
    });

    this.startedTimer = false;    
    this.firstClick = true;

};

MineField.prototype.replayGame = function() {

    this.forEveryMineCell(function(row, col) {
        (this.field[row][col]).clearAttributes();
    });
    this.startedTimer = false;        

};

MineField.prototype.near = function(mx, my) {

    if (mx < 1 || my < 1 || mx > (this.x - 2) || my > (this.y - 2)) {
        return 0;
    }

    var howManyBombs = 0;

    for (var i = -1; i < 2; i++) {
        for (var j = -1; j < 2; j++) {
            if ((i != 0) || (j != 0))
                howManyBombs += this.field[mx + i][my + j].bomb;
        }
    }
    
    return howManyBombs;
};

MineField.prototype.initWithBombs = function(firstx, firsty) {

    var bombs = this.bombs;
    while (bombs > 0) {
        var x = 1 + Math.floor((this.x - 2) * Math.random());
        var y = 1 + Math.floor((this.y - 2) * Math.random());
        if ((this.field[x][y].bomb == 0) && ((x < firstx - 1) || (x > firstx + 1) || (y < firsty - 1) || (y > firsty + 1))) {
            this.field[x][y].bomb = 1;
            bombs--;
        }
    }


};

MineField.prototype.showBombs = function() {

    this.forEveryMineCell(function(row, col) {
        if ((this.field[row][col]).bomb == 1) {
            $("#" + row + "-" + col).addClass("bombed");
        }
    });

};


MineField.prototype.appendToTable = function(table) {

    if (!this.table) {
        this.table = table;
    }

    $("tbody", table).remove();

    $(table).append($("<tbody>"));
    var rows = this.field.length - 1;
    var cols = this.field[0].length - 1;

    for (var r = 1; r < rows; r++) {
        var trow = $("<tr>");

        for (var c = 1; c < cols; c++) {
            this.field[r][c].appendToRow(trow);
        }
        trow.appendTo(table);
    }
    $(table).data("mineField", this);

};

