'use strict';

var _ = require('underscore');
var expect = require('chai').expect;
var Grid = require('../app/scripts/models/grid');
var Player = require('../app/scripts/models/player');
var Chip = require('../app/scripts/models/chip');

describe('grid', function () {

  it('should initialize', function () {
    var grid = new Grid({
      columnCount: 9,
      rowCount: 8
    });
    expect(grid.columnCount).to.equal(9);
    expect(grid.rowCount).to.equal(8);
    expect(grid.columns).to.have.length(9);
    grid.columns.forEach(function (column) {
      expect(column).to.have.length(0);
    });
  });

  it('should know when it is full', function () {
    var grid = new Grid({
      columnCount: 9,
      rowCount: 8
    });
    var player = new Player({color: 'red', name: 'Bob'});
    _.times(9, function (c) {
      _.times(8, function () {
        grid.columns[c].push(new Chip({player: player}));
      });
    });
    expect(grid.checkIfFull()).to.be.true;
  });

  it('should know when it is not full', function () {
    var grid = new Grid({
      columnCount: 9,
      rowCount: 8
    });
    var player = new Player({color: 'red', name: 'Bob'});
    _.times(9, function (c) {
      _.times(7, function () {
        grid.columns[c].push(new Chip({player: player}));
      });
    });
    expect(grid.checkIfFull()).to.be.false;
  });

  it('should reset', function () {
    var grid = new Grid({
      columnCount: 9,
      rowCount: 8
    });
    var player = new Player({color: 'red', name: 'Bob'});
    _.times(9, function (c) {
      _.times(6, function () {
        grid.columns[c].push(new Chip({player: player}));
      });
    });
    grid.resetGrid();
    grid.columns.forEach(function (column) {
      expect(column).to.have.length(0);
    });
  });

  // Place chips at the given columns with the given players
  function placeChips(args) {
    var currentPlayer = args.players[0];
    args.columns.forEach(function (column) {
      var chip = new Chip({player: currentPlayer});
      args.grid.placeChip({column: column, chip: chip});
      if (currentPlayer == args.players[0]) {
        currentPlayer = args.players[1];
      } else {
        currentPlayer = args.players[0];
      }
    });
  }

  it('should place chip and set its column/row', function () {
    var grid = new Grid({
      columnCount: 9,
      rowCount: 6
    });
    var player1 = new Player({color: 'red'});
    var player2 = new Player({color: 'blue'});
    placeChips({
      grid: grid,
      players: [player1, player2],
      columns: [2, 2]
    });
    expect(grid.columns[2][0]).to.be.an.instanceof(Chip);
    expect(grid.columns[2][0]).to.have.property('column', 2);
    expect(grid.columns[2][0]).to.have.property('row', 0);
    expect(grid.columns[2][1]).to.be.an.instanceof(Chip);
    expect(grid.columns[2][1]).to.have.property('column', 2);
    expect(grid.columns[2][1]).to.have.property('row', 1);
  });

  describe('score', function () {

    it('should be 0 for maximizing player empty grid', function () {
      var grid = new Grid({
        columnCount: 7,
        rowCount: 6
      });
      var maximizingPlayer = new Player({color: 'red'});
      expect(grid.getScore(maximizingPlayer, true)).to.equal(0);
    });

    it('should be 0 for minimizing player empty grid', function () {
      var grid = new Grid({
        columnCount: 7,
        rowCount: 6
      });
      var minimizingPlayer = new Player({color: 'blue'});
      expect(grid.getScore(minimizingPlayer, false)).to.equal(0);
    });

    it('should be 1000 for maximizing player win', function () {
      var grid = new Grid({
        columnCount: 7,
        rowCount: 6
      });
      var maximizingPlayer = new Player({color: 'red'});
      var minimizingPlayer = new Player({color: 'blue'});
      placeChips({
        grid: grid,
        players: [maximizingPlayer, minimizingPlayer],
        columns: [2, 3, 3, 2, 4, 4, 4, 5, 5, 5, 5]
      });
      expect(grid.getScore(maximizingPlayer, true)).to.equal(1000);
    });

    it('should be -1000 for minimizing player win', function () {
      var grid = new Grid({
        columnCount: 7,
        rowCount: 6
      });
      var maximizingPlayer = new Player({color: 'red'});
      var minimizingPlayer = new Player({color: 'blue'});
      placeChips({
        grid: grid,
        players: [maximizingPlayer, minimizingPlayer],
        columns: [2, 3, 3, 2, 4, 4, 4, 5, 5, 5, 5]
      });
      expect(grid.getScore(minimizingPlayer, false)).to.equal(-1000);
    });

    it('should count connect-threes for maximizing player', function () {
      var grid = new Grid({
        columnCount: 7,
        rowCount: 6
      });
      var maximizingPlayer = new Player({color: 'red'});
      var minimizingPlayer = new Player({color: 'blue'});
      placeChips({
        grid: grid,
        players: [maximizingPlayer, minimizingPlayer],
        columns: [2, 0, 3, 6, 4, 3]
      });
      expect(grid.getScore(maximizingPlayer, true)).to.equal(2);
    });

    it('should count connect-threes for minimizing player', function () {
      var grid = new Grid({
        columnCount: 7,
        rowCount: 6
      });
      var maximizingPlayer = new Player({color: 'red'});
      var minimizingPlayer = new Player({color: 'blue'});
      placeChips({
        grid: grid,
        players: [maximizingPlayer, minimizingPlayer],
        columns: [2, 0, 3, 6, 4, 3]
      });
      expect(grid.getScore(minimizingPlayer, false)).to.equal(0);
    });

  });

});

@@ -2975,34 +2975,16 @@
 e 0 for 
-maximizing player 
 empty gr
@@ -2994,32 +2994,32 @@
 , function () %7B%0A
+
       var grid =
@@ -3137,24 +3137,82 @@
 r: 'red'%7D);%0A
+      var minimizingPlayer = new Player(%7Bcolor: 'blue'%7D);%0A
       expect
@@ -3268,226 +3268,8 @@
 0);%0A
-    %7D);%0A%0A    it('should be 0 for minimizing player empty grid', function () %7B%0A      var grid = new Grid(%7B%0A        columnCount: 7,%0A        rowCount: 6%0A      %7D);%0A      var minimizingPlayer = new Player(%7Bcolor: 'blue'%7D);%0A
     

Combine empty grid score tests