package edu.pdx.cs410J.whitlock;

import com.google.common.annotations.VisibleForTesting;

/**
 * This class is represents a <code>Student</code>.                                 
 */                                                                                 
public class GameOfLife {

  private static final char DEAD_CELL = '.';
  private static final char ALIVE_CELL = '*';

  private final char[][] grid;
  private int nextUnpopulatedRow;
  private final int rowCount;
  private final int columnCount;

  public GameOfLife(int rowCount, int columnCount) {
    this.grid = new char[rowCount][columnCount];
    this.nextUnpopulatedRow = 0;
    this.rowCount = rowCount;
    this.columnCount = columnCount;
  }

  /**
   * Main program that parses the command line, creates a
   * <code>Student</code>, and prints a description of the gameoflife to
   * standard out by invoking its <code>toString</code> method.
   */
  public static void main(String[] args) {
    System.err.println("Missing command line arguments");
    System.exit(1);
  }

  void addRow(String row) {
    this.grid[this.nextUnpopulatedRow] = row.toCharArray();
    this.nextUnpopulatedRow++;
  }

  void computeNextGeneration() {
    for (int row = 0; row < this.rowCount; row++) {
      for (int column = 0; column < this.columnCount; column++) {
        this.grid[row][column] = getNextGenerationCell(row, column);
      }
    }

  }

  private char getNextGenerationCell(int row, int column) {
    char cell = getCell(row, column);
    int numberOfLiveNeighbors = getNumberOfLiveNeighbors(row, column);
    if (cell == ALIVE_CELL) {
      if (numberOfLiveNeighbors < 2) {
        return DEAD_CELL;

      } else if (numberOfLiveNeighbors > 3) {
        return DEAD_CELL;
      }

    }
    return DEAD_CELL;
  }

  @VisibleForTesting
  int getNumberOfLiveNeighbors(int row, int column) {
    int numberLiveNeighbors = 0;

    if (northwestNeighborIsAlive(row, column)) {
      numberLiveNeighbors++;
    }

    if (northeastNeighborIsAlive(row, column)) {
      numberLiveNeighbors++;
    }

    if (southeastNeighborIsAlive(row, column)) {
      numberLiveNeighbors++;
    }

    if (southwestNeighborIsAlive(row, column)) {
      numberLiveNeighbors++;
    }

    if (northNeighborIsAlive(row, column)) {
      numberLiveNeighbors++;
    }

    if (eastNeighborIsAlive(row, column)) {
      numberLiveNeighbors++;
    }

    if (southNeighborIsAlive(row, column)) {
      numberLiveNeighbors++;
    }

    if (westNeighborIsAlive(row, column)) {
      numberLiveNeighbors++;
    }

    return numberLiveNeighbors;
  }

  private boolean westNeighborIsAlive(int row, int column) {
    return cellIsAlive(row, column - 1);
  }

  private boolean southNeighborIsAlive(int row, int column) {
    return cellIsAlive(row + 1, column);
  }

  private boolean eastNeighborIsAlive(int row, int column) {
    return cellIsAlive(row, column + 1);
  }

  private boolean northNeighborIsAlive(int row, int column) {
    return cellIsAlive(row - 1, column);
  }

  private boolean southwestNeighborIsAlive(int row, int column) {
    return cellIsAlive(row + 1, column - 1);
  }

  private boolean southeastNeighborIsAlive(int row, int column) {
    return cellIsAlive(row + 1, column + 1);
  }

  private boolean northeastNeighborIsAlive(int row, int column) {
    return cellIsAlive(row - 1, column + 1);
  }

  private boolean northwestNeighborIsAlive(int row, int column) {
    return cellIsAlive(row - 1, column - 1);
  }

  private boolean cellIsAlive(int row, int column) {
    if (row < 0) {
      return false;

    } else if (column < 0) {
      return false;

    } else if (column >= this.columnCount) {
      return false;

    } else if (row >= this.rowCount) {
      return false;

    } else {
      return getCell(row, column) == ALIVE_CELL;
    }
  }

  private char getCell(int row, int column) {
    return this.grid[row][column];
  }

  String getRow(int rowIndex) {
    return new String(this.grid[rowIndex]);
  }
}
@@ -1905,761 +1905,144 @@
     
-if (northwestNeighborIsAlive(row, column)) %7B%0A      numberLiveNeighbors++;%0A    %7D%0A%0A    if (northeastNeighborIsAlive(row, column)) %7B%0A      numberLiveNeighbors++;%0A    %7D%0A%0A    if (southeastNeighborIsAlive(row, column)) %7B%0A      numberLiveNeighbors++;%0A    %7D%0A%0A    if (southwestNeighborIsAlive(row, column)) %7B%0A      numberLiveNeighbors++;%0A    %7D%0A%0A    if (northNeighborIsAlive(row, column)) %7B%0A      numberLiveNeighbors++;%0A    %7D%0A%0A    if (eastNeighborIsAlive(row, column)) %7B%0A      numberLiveNeighbors++;%0A    %7D%0A%0A    if (southNeighborIsAlive(row, column)) %7B%0A      numberLiveNeighbors++;%0A    %7D%0A%0A    if (westNeighborIsAlive(row, column)) %7B%0A      numberLiveNeighbors++;%0A    %7D%0A%0A    return numberLiveNeighbors;%0A  %7D%0A%0A  private boolean westNeighborIsAlive(int row, int
+for (int i = row - 1; i %3C= row + 1; i++) %7B%0A      for (int j = column - 1; j %3C= column + 1; j++) %7B%0A        if (!(i == row && j ==
  column)
  %7B%0A 
@@ -2041,837 +2041,149 @@
 umn)
+)
  %7B%0A    
-return cellIsAlive(row, column - 1);%0A  %7D%0A%0A  private boolean southNeighborIsAlive(int row, int column) %7B%0A    return cellIsAlive(row + 1, column);%0A  %7D%0A%0A  private boolean eastNeighborIsAlive(int row, int column) %7B%0A    return cellIsAlive(row, column + 1);%0A  %7D%0A%0A  private boolean northNeighborIsAlive(int row, int column) %7B%0A    return cellIsAlive(row - 1, column);%0A  %7D%0A%0A  private boolean southwestNeighborIsAlive(int row, int column) %7B%0A    return cellIsAlive(row + 1, column - 1);%0A
+      if (cellIsAlive(i, j)) %7B%0A            numberLiveNeighbors++;%0A        
   %7D%0A
-%0A
   
-private boolean southeastNeighborIsAlive(int row, int column) %7B%0A    return cellIsAlive(row + 1, column + 1);%0A  %7D%0A%0A  private boolean northeastNeighborIsAlive(int row, int column) %7B%0A    return cellIsAlive(row - 1, column + 1);%0A  %7D%0A%0A  private boolean northwestNeighborIsAlive(int row, int column) %7B%0A    return cellIsAlive(row - 1, column - 1)
+      %7D%0A      %7D%0A    %7D%0A%0A    return numberLiveNeighbors
 ;%0A  

Refactor logic for computing a cell's neighbors into a single double loop.