//This program displays a grid of 10x10 cells.
//The user can change the state of the cells.
//The user can then run 1, 10, 100, or 1000 generations.
//Each generation effects the cells according to rules
//about death, birth, crowding, and loneliness.
//The user can change the birth, crowding, and loneliness settings.
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

public class Game extends Applet implements ActionListener
{
  private int [] setting = new int [3];
  private Label [] labels = new Label [6];
  private Button [] buttons = new Button [7];
  private TextField [] textfields = new TextField [3];
  private World world = new World ();
  
  public void init ()
  {
    Panel controls = new Panel ();
    controls.setLayout (new GridLayout (1,6,1,1));
    controls.add (labels [0] = new Label ("Cycles:"));
    controls.add (buttons [0] = new Button ("1"));
    controls.add (buttons [1] = new Button ("10"));
    controls.add (buttons [2] = new Button ("100"));
    controls.add (buttons [3] = new Button ("1000"));
    controls.add (buttons [4] = new Button ("Clear"));
    
    Panel sets = new Panel ();
    sets.setLayout (new GridLayout (2,5,1,1));
    sets.add (labels [1] = new Label ("Rules:"));
    sets.add (labels [2] = new Label ("Birth >"));
    sets.add (labels [3] = new Label ("Loneliness <"));
    sets.add (labels [4] = new Label ("Crowding >"));
    sets.add (buttons [5] = new Button ("Reset"));
    sets.add (labels [5] = new Label ("Settings:"));
    sets.add (textfields [0] = new TextField (10));
    sets.add (textfields [1] = new TextField (10));
    sets.add (textfields [2] = new TextField (10));
    sets.add (buttons [6] = new Button("Update"));

    this.setLayout(new BorderLayout(0,2));
    this.add("North", controls);
    this.add("Center", world);
    this.add("South", sets);
	
    resetText();
    updateSettings();
    addActionListeners();
  }
  
  //Sets state of cells (alive or dead) 
  //Calls oneGeneration either 1,10,100, or 1000 times
  //depending on which button was pressed
  public void actionPerformed(ActionEvent event)
  {
    for (int count1=0; count1<10; count1++)
    {
	for (int count2=0; count2<10; count2++)
	{
	  if (event.getSource() == world.cell[count1][count2])
	  {
	    if (world.cell[count1][count2].getState())
	    {
	      world.cell[count1][count2].setState(false);
	    }
	   else
	   {
	     world.cell[count1][count2].setState(true);
	   }
	}
    }
  }
  if (event.getSource() == buttons[0])
  {
    oneGeneration();
  }
  if (event.getSource() == buttons[1])
  {
    for (int count1=0; count1<10; count1++)
    {
      oneGeneration();
    }
  }
  if (event.getSource() == buttons[2])
  {
    for (int count1=0; count1<100; count1++)
    {
      oneGeneration();
    }
  }
  if (event.getSource() == buttons[3])
  {
    for (int count1=0; count1<1000; count1++)
    {
      oneGeneration();
    }
  }
  if (event.getSource() == buttons[4]) 
  {
    for (int count1=0; count1<10; count1++)
    {
      for (int count2=0; count2<10; count2++)
      {
	 world.cell[count1][count2].setState(false);
      }
    }
  }
  if (event.getSource() == buttons[5])
  {
    resetText();
  }
  if (event.getSource() == buttons[6])
  {
    updateSettings();
  }
 } 

 //makes cells alive
 private void addActionListeners()
  {
    for (int count=0; count<7; count++)
	{
	  buttons[count].addActionListener(this);
	}
	for (int count1=0; count1<10; count1++)
	{
	  for (int count2=0; count2<10; count2++)
	  {
	    world.cell[count1][count2].addActionListener(this);
	  }
	}
  }

  //determines how many neighbors a cell has
  private void neighbors()
  { 
    int counter = 0; 
    for (int count1=1; count1<9; count1++)		
	{
	  for (int count2=1; count2<9; count2++)
	  {
		counter = 0;
		if (world.cell[count1-1][count2-1].getState()) counter++;
		if (world.cell[count1-1][count2].  getState()) counter++;
		if (world.cell[count1-1][count2+1].getState()) counter++;
		if (world.cell[count1][count2-1].getState()) counter++;
		if (world.cell[count1][count2+1].getState()) counter++;
		if (world.cell[count1+1][count2-1].getState()) counter++;
		if (world.cell[count1+1][count2].  getState()) counter++;
		if (world.cell[count1+1][count2+1].getState()) counter++;
		world.cell[count1][count2].setNeighbor(counter);
	  }
	}  
    }

   //determines what happens to a cell after one generation
   //and changes cell according to rules about birth and death.
   private void oneGeneration()
   {
    neighbors();	
    for (int count1=0; count1<10; count1++)
    {
      for (int count2=0; count2<10; count2++)
      {
	 if (world.cell[count1][count2].getState())
	 {
	   if (world.cell[count1][count2].getNeighbor() < setting[1])
	   {
	     world.cell[count1][count2].setState(false);
	   }
	  if(world.cell[count1][count2].getNeighbor() > setting[2])
	  { 
	    world.cell[count1][count2].setState(false);
	  }
	}
	else
	{
	   if (world.cell[count1][count2].getNeighbor() > setting[0])
	   { 
	     world.cell[count1][count2].setState(true);
	   }
	 }
      }
    }
  }  

  
  //resets settings of the birth, loneliness, and crowding text fields.
  private void resetText()
  {
    textfields[0].setText(""+2);
    textfields[1].setText(""+2);
    textfields[2].setText(""+3);	
  }

  //resets birth, loneliness, and crowding settings according to what 
  //was entered into the text fields.
  private void updateSettings()
  {
    setting[0] = Integer.parseInt(textfields[0].getText());
    setting[1] = Integer.parseInt(textfields[1].getText());
    setting[2] = Integer.parseInt(textfields[2].getText());	
  }	  
  
}