/**
 * autocell2.java 28/04/20 - 31/08/22
 *
 * Auteur : Jean-Paul Quelen
 * jeu de la vie : vivant->vivant = 23; mort->vivant = 3.
 * Day & Night : vivant->vivant = 34678; mort->vivant = 3678.
 * HighLife : vivant->vivant = 23; mort->vivant = 36.
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;

public class autocell2 extends JFrame implements ActionListener, Runnable {
	static final long serialVersionUID = 220831L;
	private JButton demarrer = new JButton ("Démarrer");
	private JButton stop = new JButton ("Stop");
	private JButton init = new JButton ("Réinitialisation");
	private JButton jbc = new JButton ("couleur");
	private JTextField vv = new JTextField ("23", 5);
	private JTextField mv = new JTextField ("3", 5);
	private Grille grille = new Grille();
	int nx, ny, nxy;
	boolean[][] bgrille, bgrille1;
	static boolean dessine;
	String svv;
	String smv;
	boolean couleur = true;

	public autocell2(String s) {
		super(s);
		add (grille);
		JPanel boutons = new JPanel();
		boutons.setBackground (Color.GRAY);
		add (boutons, BorderLayout.NORTH);
		boutons.add (demarrer);
		boutons.add (stop);
		boutons.add (new JLabel ("vivant->vivant"));
		boutons.add (vv);
		boutons.add (new JLabel ("mort->vivant"));
		boutons.add (mv);
		boutons.add (init);
		boutons.add (jbc);
		demarrer.addActionListener (this);
		stop.addActionListener(this);
		init.addActionListener(this);
		jbc.addActionListener(this);
	}

	public void actionPerformed (ActionEvent e) {
		if (e.getSource() == demarrer) {
			svv = lectureregle(vv);
			smv = lectureregle(mv);
			dessine = true;
			Thread thr = new Thread (this);
			thr.start();
		} else if (e.getSource() == stop) {
			svv = lectureregle(vv);
			smv = lectureregle(mv);
			dessine = false;
		} else if (e.getSource() == init) {
			svv = lectureregle(vv);
			smv = lectureregle(mv);
			Grille.img = null;
			grille.repaint();
		} else if (e.getSource() == jbc) {
			couleur = !couleur;
		}
	}

	private void attendre (long tms) {
		try {
			Thread.sleep (tms);
		}
		catch (InterruptedException ie) {}
	}

	private String lectureregle (JTextField tf) {
		String stf = tf.getText();
		String[] stfs = stf.split ("[^0-8]");
		String sr = "";
		for (int i = 0; i < stfs.length; i++)
			sr += stfs[i];
		return sr;
	}

	private void regle (int i, int j, int voisins) {
		String sxv = (bgrille[i][j]) ? svv : smv;
		bgrille1[i][j] = false;
		for (int k = 0; k < sxv.length(); k++) {
			boolean bk = (voisins == Integer.parseInt (sxv.substring (k, k + 1)));
			if (bk) {
				bgrille1[i][j] = true;
				break;
			}
		}
	}

	public void run() {
		int voisins = 0;
		int nxm1 = nx - 1;
		int nym1 = ny - 1;
		while (dessine) {
			for (int i = 0; i < nx; i++) {
				for (int j = 0; j < ny; j++) {
					voisins = 0;
					if (i != nxm1 && bgrille[i+1][j])
						voisins++;
					if (i != nxm1 && j != nym1 && bgrille[i+1][j+1])
						voisins++;
					if (j != nym1 && bgrille[i][j+1])
						voisins++;
					if (i != 0 && j != nym1 && bgrille[i-1][j+1])
						voisins++;
					if (i != 0 && bgrille[i-1][j])
						voisins++;
					if (i != 0 && j != 0 && bgrille[i-1][j-1])
						voisins++;
					if (j != 0 && bgrille[i][j-1])
						voisins++;
					if (i != nxm1 && j != 0 && bgrille[i+1][j-1])
						voisins++;
					regle (i, j, voisins);
				}
			}
			grille.repaint();
			attendre (100L);
		}
	}

/**
 * classe Grille 28/04/2020
 *
 */

protected class Grille extends JPanel {
	static final long serialVersionUID = 200428L;
	static Image img;
	static Graphics gimg;
	int xmax, ymax;
	int pas = 10;

	public void update (Graphics g) {
		paint (g);
	}

	public void paint (Graphics g) {
		int gw = getWidth();
		int gh = getHeight();
		if (img == null || xmax != gw || ymax != gh) {
			attendre (1L);								// pour éviter des débordement dans les tableaux bgrille et bgrille1
			dessine = false;							// si la fenêtre est diminuée pendans le déroulement du thread
			xmax = gw;
			ymax = gh;
			img = createImage (xmax, ymax);
			gimg = img.getGraphics();
			nx = xmax / pas + 1;
			ny = ymax / pas + 1;
			bgrille = new boolean [nx] [ny];
			bgrille1 = new boolean [nx] [ny];
			nxy = nx * ny;

// initialisation de type aléatoire
			Random r = new Random();
			for (int i = 0; i < nx; i++) {
				for (int j = 0; j < ny; j++) {
					bgrille[i][j] = r.nextBoolean();
					bgrille1[i][j] = bgrille[i][j];
				}
			}
		}
		gimg.setColor (Color.WHITE);
		gimg.fillRect (0, 0, xmax, ymax);
		gimg.setColor (Color.BLACK);
		for (int x = 0; x < xmax; x += pas) {
			gimg.drawLine (x, 0, x, ymax);
		}
		for (int y = 0; y < ymax; y += pas) {
			gimg.drawLine (0, y, xmax, y);
		}
		if (couleur) {
			for (int i = 0; i < nx; i++) {
				for (int j = 0; j < ny; j++) {
					if (bgrille[i][j] || bgrille1[i][j]) {
						if (bgrille[i][j]) {
							if (bgrille1[i][j]) {
								gimg.setColor (Color.BLUE);
							} else {
								gimg.setColor (Color.RED);
							}
						} else {
						gimg.setColor (Color.GREEN);
						}
						gimg.fillOval (i * pas, j * pas, pas, pas);
					}
				}
			}
		} else {
			gimg.setColor (Color.BLUE);
			for (int i = 0; i < nx; i++) {
				for (int j = 0; j < ny; j++) {
					if (bgrille1[i][j])
						gimg.fillOval (i * pas, j * pas, pas, pas);
				}
			}
		}
		g.drawImage (img, 0, 0, this);
/*		for (int i = 0; i < nx; i++)
			for (int j = 0; j < ny; j++)
				bgrille[i][j] = bgrille1[i][j]; */
		for (int i = 0; i < nx; i++)
			System.arraycopy (bgrille1[i], 0, bgrille[i], 0, ny);
	}
}

	public static void main (String[] args) {
		autocell2 ac = new autocell2 ("Automate cellulaire");
		ac.setSize(800, 850);
		ac.setLocationRelativeTo (null);
		ac.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		ac.setVisible (true);
	}
}