// Generated by CoffeeScript 1.12.7
(function() {
  var GoBoard, GoCell, GoGame, GoPlayers, GoStone,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  GoBoard = (function() {
    function GoBoard(id, game) {
      this.handleClick = bind(this.handleClick, this);
      this.$el = $("" + id);
      this.size = this.$el.children().length;
      this.$el.on('click', this.handleClick);
      this.game = game;
      this.cells = [];
      this.states = [];
      this.buildCells();
    }

    GoBoard.prototype.handleClick = function(e) {
      var $t;
      $t = $(e.target);
      if (!(($t.data('x') != null) && ($t.data('y') != null))) {
        return;
      }
      return this.game.handleClick($t.data('x'), $t.data('y'));
    };

    GoBoard.prototype.addCell = function(c) {
      if (!this.cells[c.x]) {
        this.cells[c.x] = [];
      }
      return this.cells[c.x][c.y] = c;
    };

    GoBoard.prototype.buildCells = function() {
      var c, cell, k, len, ref, results;
      ref = this.$el.find(".cell");
      results = [];
      for (k = 0, len = ref.length; k < len; k++) {
        cell = ref[k];
        c = new GoCell($(cell).data('x'), $(cell).data('y'), this);
        results.push(this.addCell(c));
      }
      return results;
    };

    GoBoard.prototype.removeCell = function(x, y, color) {
      console.log("remove cell " + x + "," + y);
      if (!this.cells[x]) {
        this.cells[x] = [];
      }
      if (this.cells[x][y].removeStone()) {
        return true;
      } else {
        return false;
      }
    };

    GoBoard.prototype.isEmpty = function(x, y) {
      return this.cells[x][y].isEmpty();
    };

    GoBoard.prototype.updateColor = function() {
      this.$el.removeClass(this.game.currentColor);
      return this.$el.addClass(this.game.nextColor());
    };

    GoBoard.prototype.addStone = function(stone) {
      var cell, state;
      cell = this.cells[stone.x][stone.y];
      if (cell.addStone(stone)) {
        state = this.encodeState();
        return true;
      } else {
        return false;
      }
    };

    GoBoard.prototype.isGameEnded = function(stone) {
      var count, counter, i, j, k, l, len, len1, length, n, ref, ref1, ref2, shouldContinueCounting;
      count = (function() {
        var k, results;
        results = [];
        for (n = k = 0; k <= 8; n = ++k) {
          results.push(0);
        }
        return results;
      })();
      shouldContinueCounting = (function() {
        var k, results;
        results = [];
        for (n = k = 0; k <= 8; n = ++k) {
          results.push(true);
        }
        return results;
      })();

      /*
      current stone is X, search surrounding up to length 4
       0 1 2
       3 X 4
       5 6 7
       */
      length = 1;
      while (length <= 4 && ((shouldContinueCounting.filter(function(x) {
          return x === true;
        })).length !== 0)) {
        counter = 0;
        ref = [-1, 0, 1];
        for (k = 0, len = ref.length; k < len; k++) {
          i = ref[k];
          ref1 = [-1, 0, 1];
          for (l = 0, len1 = ref1.length; l < len1; l++) {
            j = ref1[l];
            if ((i !== 0 || j !== 0) && shouldContinueCounting[counter]) {
              if ((ref2 = this.cells[stone.x + i * length][stone.y + j * length]) != null ? ref2.color(stone.color) : void 0) {
                count[counter] += 1;
              } else {
                shouldContinueCounting[counter] = false;
              }
            }
            counter += 1;
          }
        }
        length += 1;
      }
      if (count[0] + count[8] >= 4 || count[1] + count[7] >= 4 || count[2] + count[6] >= 4 || count[3] + count[5] >= 4) {
        return true;
      }
      return false;
    };

    GoBoard.prototype.encodeState = function() {
      var row;
      return ((function() {
        var k, len, ref, results;
        ref = this.cells;
        results = [];
        for (k = 0, len = ref.length; k < len; k++) {
          row = ref[k];
          results.push(parseInt(row.map(function(cell) {
            return cell.state();
          }).join(''), 3).toString(36));
        }
        return results;
      }).call(this)).join(',');
    };

    GoBoard.prototype.state = function() {
      var cell, k, l, len, len1, ref, row, s;
      s = [];
      ref = this.cells;
      for (k = 0, len = ref.length; k < len; k++) {
        row = ref[k];
        for (l = 0, len1 = row.length; l < len1; l++) {
          cell = row[l];
          s.push(cell.state());
        }
      }
      return s;
    };

    return GoBoard;

  })();

  GoCell = (function() {
    function GoCell(x, y, board) {
      var ref;
      this.board = board;
      ref = [x, y], this.x = ref[0], this.y = ref[1];
      this.stone = false;
      this.$el = this.board.$el.find("[data-x=" + x + "][data-y=" + y + "]");
      this.dead = false;
    }

    GoCell.prototype.state = function() {
      if (this.isEmpty()) {
        return 0;
      }
      if (this.isBlack()) {
        return 1;
      }
      if (this.isWhite()) {
        return 2;
      }
    };

    GoCell.prototype.isEmpty = function() {
      return !this.stone;
    };

    GoCell.prototype.isWhite = function() {
      var ref;
      return ((ref = this.stone) != null ? ref.color : void 0) === 'white';
    };

    GoCell.prototype.isBlack = function() {
      var ref;
      return ((ref = this.stone) != null ? ref.color : void 0) === 'black';
    };

    GoCell.prototype.color = function(c) {
      var ref;
      return ((ref = this.stone) != null ? ref.color : void 0) === c;
    };

    GoCell.prototype.oppositeColor = function() {
      var ref;
      if (!'stone') {
        return 'empty';
      }
      if (((ref = this.stone) != null ? ref.color : void 0) === 'black') {
        return 'white';
      } else {
        return 'black';
      }
    };

    GoCell.prototype.addStone = function(stone) {
      this.stone = stone;
      this.$el.data('stone', this.stone);
      return this.$el.addClass(this.stone.color);
    };

    GoCell.prototype.removeStone = function() {
      if (this.stone.color === 'black') {
        this.$el.data('stone', '');
        this.$el.removeClass(this.stone.color);
        this.stone = false;
        return true;
      }
      return false;
    };

    return GoCell;

  })();

  GoStone = (function() {
    function GoStone(game, x, y, color) {
      this.game = game;
      this.x = x;
      this.y = y;
      this.color = color;
    }

    return GoStone;

  })();

  GoPlayers = (function() {
    function GoPlayers(id, game) {
      this.$el = $(id + " .goPlayers");
      this.game = game;
    }

    return GoPlayers;

  })();

  GoGame = (function() {
    function GoGame(id) {
      this.board = new GoBoard(id, this);
      this.players = new GoPlayers(id, this);
      this.currentColor = 'black';
      this.black = 0;
      this.white = 0;
      this.step = 0;
    }

    GoGame.prototype.handleClick = function(x, y) {
      var stone;
      stone = new GoStone(this, x, y, this.currentColor);
      if (this.step === 6) {
        if (!this.board.isEmpty(x, y)) {
          if (this.board.removeCell(x, y, 'black')) {
            this.black--;
            this.step++;
          }
        }
      } else {
        if (!this.board.isEmpty(x, y)) {
          return;
        }
        if (this.addStone(stone)) {
          this.step++;
          console.log(this.step);
          if (this.board.isGameEnded(stone)) {
            console.log(stone.x, stone.y, "five in a row!");
            alert(this.currentColor + " is the winner! Black: " + this.black + " White: " + this.white);
            return;
          }
          if (this.step !== 5) {
            this.board.updateColor();
          }
        }
      }
      if (this.step === 4) {
        alert("Black places two stones in this round");
      }
      if (this.step === 6) {
        return alert("White: click on any black on the board to remove it, then place a white stone");
      }
    };

    GoGame.prototype.addStone = function(stone) {
      var ret;
      if (ret = this.board.addStone(stone)) {
        if (this.currentColor === 'black') {
          this.black += 1;
        } else {
          this.white += 1;
        }
        return true;
      }
      return false;
    };

    GoGame.prototype.nextColor = function() {
      if (this.currentColor === 'black') {
        return this.currentColor = 'white';
      } else {
        return this.currentColor = 'black';
      }
    };

    return GoGame;

  })();

  new GoGame('#board15');

}).call(this);
