package edu.wright.hendrix11.conway.logic;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Joe Hendrix
 */
public class Grid {
    private List<Cell> aliveCells = new ArrayList<>();

    public void addLivingCell(Cell cell) {
        assert cell.isAlive();
        aliveCells.add(cell);
    }

    public void removeDeadCell(Cell cell) {
        assert !cell.isAlive();
        aliveCells.remove(cell);
    }

    public void tick() {
        List<Cell> toggleTheseCells = new ArrayList<>();

        checkLivingCells(toggleTheseCells);

        toggleCells(toggleTheseCells);
    }
    
    private void toggleCells(List<Cell> toggleTheseCells) {
        for(Cell cell : toggleTheseCells) {
            cell.toggle();

            if(cell.isAlive()) {
                aliveCells.add(cell);
            } else {
                assert !cell.isAlive();
                aliveCells.remove(cell);
            }
        }
    }
    
    private void checkAdjacentDeadCells(List<Cell> toggleTheseCells) {
        Set<Cell> newbornCells = new HashSet<>();
        
        for(Cell cell : aliveCells) {
            for(Cell neighbor : cell.getNeighbors()) {
                if(neighbor != null && !neighbor.isAlive()) {
                    checkDeadCell(cell.getNorthernCell(), newbornCells);
                } else if(neighbor == null) {
                    // Todo: this case
                }
            }
        }
        
        toggleTheseCells.addAll(newbornCells);
    }
    
    private void checkDeadCell(Cell deadCell, Set<Cell> newbornCells) {
        assert !deadCell.isAlive();
        
        int numberOfLivingNeighbors = deadCell.getNumberLivingNeighbors();
        
        assert numberOfLivingNeighbors >= 0 && numberOfLivingNeighbors <= 8;
        
        if(numberOfLivingNeighbors == 3) {
            newbornCells.add(cell.getNorthernCell());
        }
    }
    
    private void checkLivingCell(Cell livingCell, List<Cell> toggleTheseCells) {
        assert livingCell.isAlive();
        
        int numberOfLivingNeighbors = livingCell.getNumberLivingNeighbors();
        
        assert numberOfLivingNeighbors >= 0 && numberOfLivingNeighbors <= 8;
        
        if(numberOfLivingNeighbors < 2 || numberOfLivingNeighbors > 3) {
            toggleTheseCells.add(livingCell);
        }
    }
    
    private void checkLivingCells(List<Cell> toggleTheseCells) {
        for(Cell cell : aliveCells) {
            checkLivingCell(cell, toggleTheseCells);
        }
    }

}

@@ -200,19 +200,18 @@
 private 
-Lis
+Se
 t%3CCell%3E 
@@ -223,32 +223,30 @@
 Cells = new 
-ArrayLis
+HashSe
 t%3C%3E();%0A%0A    
@@ -501,19 +501,18 @@
         
-Lis
+Se
 t%3CCell%3E 
@@ -534,24 +534,22 @@
 s = new 
-ArrayLis
+HashSe
 t%3C%3E();%0A%0A
@@ -591,16 +591,66 @@
 eCells);
+%0A        checkAdjacentDeadCells(toggleTheseCells);
 %0A%0A      
@@ -718,27 +718,26 @@
 toggleCells(
-Lis
+Se
 t%3CCell%3E togg
@@ -1068,27 +1068,26 @@
 ntDeadCells(
-Lis
+Se
 t%3CCell%3E togg
@@ -1106,67 +1106,8 @@
 ) %7B%0A
-        Set%3CCell%3E newbornCells = new HashSet%3C%3E();%0A        %0A
     
@@ -1273,24 +1273,27 @@
             
+if(
 checkDeadCel
@@ -1298,46 +1298,98 @@
 ell(
-cell.getNorthernCell(), newbornCells);
+neighbor)) %7B%0A                        toggleTheseCells.add(neighbor);%0A                    %7D
 %0A   
@@ -1516,64 +1516,8 @@
   %7D%0A
-        %0A        toggleTheseCells.addAll(newbornCells);%0A
     
@@ -1531,28 +1531,31 @@
     private 
-void
+boolean
  checkDeadCe
@@ -1574,32 +1574,8 @@
 Cell
-, Set%3CCell%3E newbornCells
 ) %7B%0A
@@ -1789,35 +1789,39 @@
        %0A        
-if(
+return 
 numberOfLivingNe
@@ -1836,75 +1836,9 @@
 == 3
-) %7B%0A            newbornCells.add(cell.getNorthernCell());%0A        %7D
+;
 %0A   
@@ -1849,36 +1849,39 @@
    %0A    private 
-void
+boolean
  checkLivingCell
@@ -1900,37 +1900,8 @@
 Cell
-, List%3CCell%3E toggleTheseCells
 ) %7B%0A
@@ -2126,19 +2126,23 @@
         
-if(
+return 
 numberOf
@@ -2195,67 +2195,9 @@
  %3E 3
-) %7B%0A            toggleTheseCells.add(livingCell);%0A        %7D
+;
 %0A   
@@ -2238,19 +2238,18 @@
 ngCells(
-Lis
+Se
 t%3CCell%3E 
@@ -2310,32 +2310,35 @@
 ) %7B%0A            
+if(
 checkLivingCell(
@@ -2345,28 +2345,70 @@
 cell
-, toggleTheseCells);
+)) %7B%0A                toggleTheseCells.add(cell);%0A            %7D
 %0A   
@@ -2420,11 +2420,10 @@
 %7D%0A    %7D%0A
-%0A
 %7D%0A

Update Grid.java