/*
 * "Grundkurs Programmieren in Java - Band 1 (3. Auflage, 2006)I"
 * 2001-2006, Carl Hanser Verlag
 * Loesungsvorschlag zu Aufgabe 12.5 (Version 3.0)
 * (c) 2001-2006 D. Ratz, J. Scheffler, D. Seese, J. Wiesenberger
 *
 */

import Prog1Tools.IOTools;
import Prog1Tools.GameEngine;
import Prog1Tools.GameModel;

import Prog1Tools.IOTools;

public class SpielDesLebensMitGui implements GameModel {

  boolean[][] gewebe;
  int generationenZaehler;

  // Konstruktor
  public SpielDesLebensMitGui (int zeilen, int spalten) {
    generationenZaehler = 1;
    gewebe = erzeugeGewebe( zeilen, spalten );
  }


  // erzeugt Gewebe der Dim n*m mit zufaelligem Inhalt *** */
  public static boolean[][] erzeugeGewebe (int n, int m) {

    boolean[][] g = new boolean[n][m];

      for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
          g[i][j] = ( ((int)(Math.random()*10))%2 == 0 ) ? true : false;
          // damit der triadische Operator auch mal zur Anwendung kommt ;-)

    return g;
  }



  // berechnet die Anzahl der Nachbarzellen von Zelle an Pos (x,y)
  public static int getAnzNachbarn (boolean[][] g, int x, int y) {

    int zaehler = 0;

    for (int i = x-1; i <= x+1; i++)
      for (int j = y-1; j <= y+1; j++)
        if ( (i >= 0) && ( i < g.length )   && // k. "Bereichsueberschreitung" vertikal
             (j >= 0) && ( j < g[i].length) && // k. "Bereichsueberschreitung" horizontal
             ( ( i != x) || ( j != y) )     && // n. Zelle (x,y) selbst als Nachbar
             g[i][j]                           // Zelle lebt
           ) zaehler++;

     return zaehler;
  }



  // erzeuge die naechste Generation
  public static boolean[][] nextGeneration (boolean[][] g) {

    int anzNachbarn;
    boolean[][] nextGeneration = new boolean[g.length][g[0].length];

    for (int i = 0; i < g.length; i++)
      for (int j = 0; j < g[i].length; j++) {
        anzNachbarn = getAnzNachbarn(g, i, j);
        if ( (anzNachbarn < 2) ||           // Vereinsamung  ... oder ...
             (anzNachbarn > 3)               // Übervoelkerung
           ) nextGeneration[i][j] = false;  // ... Zelle in der n. Generation
        else
          if (anzNachbarn == 2)             // mit genau zwei lebenden Nachbarn ...
            nextGeneration[i][j] = g[i][j]; // ... keine Zustandsaenderung
          else nextGeneration[i][j] = true; // ... ansonsten lebt Zelle
      } // for

    return nextGeneration;
  }


  /* ****************************************************************** */
  // Methoden f. das Interface 'GameModel'

  public int columns () {
    return gewebe[0].length;
  }

  public int rows () {
    return gewebe.length;
  }

  // Feuer-Button gedrückt: nächste Generation berechnen
  public void firePressed() {
    generationenZaehler++;
    gewebe = nextGeneration(gewebe);
  }


  // Beschriftung fur den Feuer-Button
  public String getFireLabel() {
    return "Nächste Generation";
  }

  // Beschriftung der Titel-Zeile
  public String getGameName() {
    return "Spiel des Lebens";
  }

  // Im Text-Fenster wollen wir immer die Nr. der aktuellen Generation anzeigen
  public String getMessages() {
    return "Generation Nr. " + generationenZaehler;
  }

  // befindet sich an einer Position eine Zelle oder nicht?
  public char getContent( int row, int col ) {
    if (gewebe[row][col])
      return 'o';
    else
      return ' ';
  }

  // invertieren einer Zelle
  public void buttonPressed(int row, int col) {
    gewebe[row][col] ^= true;
  }



  /*
   *
   * ****** main-Methode ******
   *
   */
  public static void main (String[] args) {
    int zeilen, spalten;

    zeilen  = IOTools.readInteger( "Anzahl der Zeilen?  > " );
    spalten = IOTools.readInteger( "Anzahl der Spalten? > " );
    new GameEngine( new SpielDesLebensMitGui( zeilen, spalten) );
  }


}

