/**
 * autocell.java 13/04/20
 *
 * @ author Jean-Paul Quelen
 */

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class autocell extends JPanel implements ActionListener {
	static final long serialVersionUID = 200413L;
	dessin d;
	Button ok, plus;
	int dimCote;
	TextField tfloi, tfdimCote;
	String loi, cells;
	int ncases, x, y;

	public autocell() {
		setLayout (new BorderLayout());
		Font f = new Font (Font.SANS_SERIF, Font.PLAIN, 10);
		Panel p = new Panel();
		add (p, BorderLayout.NORTH);
		p.setBackground (Color.lightGray);

		dimCote = 8;
		p.add (tfdimCote = new TextField ("8", 10));
		tfdimCote.setFont (f);

		p.add (tfloi = new TextField ("01111000", 20));
		tfloi.setFont (f);

		p.add (ok = new Button ("ok"));
		ok.setFont (f);
		ok.addActionListener (this);

		p.add (plus = new Button ("+"));
		plus.setFont (f);
		plus.addActionListener (this);

		add (d = new dessin(), BorderLayout.CENTER);
	}

	private void getLoidimCote () {
// on récupère la loi suite de 0 et de 1, éventuellement complétée par des 0. Elle sera de longueur 2^n
		loi = tfloi.getText();
		int n = loi.length();
		int p2 = 1;
		ncases = 0;
		while (p2 < n) {
			p2 *= 2;
			ncases++;
		}
		while (n < p2) {
			loi += '0';
			n++;
		}
		tfloi.setText (loi);

// on récupère la taille des carrés de chaque cellule
		int dc = dimCote;
		try {
			dc = Integer.parseInt (tfdimCote.getText());
			if (dc > 0)
				dimCote = dc;
		}
		catch (NumberFormatException nfe) {}
		tfdimCote.setText (Integer.toString (dimCote));

// intialisation de y
		y = 0;
	}

	public void actionPerformed (ActionEvent e) {
		if (e.getSource () == ok) {
			getLoidimCote();
			d.repaint();
		}
		else if (e.getSource () == plus) {
			y += dimCote + 2;
			d.repaint();
		}
	}

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Canvas {
	static final long serialVersionUID = 200413L;
	int w, h;

	public dessin () {
		getLoidimCote();
	}

	private int index (String motif) {
		int r = 0;
		int f = 1;
		int ml = motif.length();
		for (int i = ml - 1; i >= 0; i--) {
			if (motif.charAt (i) != '0') {
				r += f;
			}
			f *= 2;
		}
		return r;
	}

	private String cZeros (String s) {
		for (int i = 1; i < ncases; i++) {
			s = '0' + s + '0';
		}
		return s;
	}

	public void update (Graphics g) {
		paint (g);
	}

	public void paint (Graphics g) {
		if (w != getWidth() || h != getHeight()) {
			w = getWidth();
			h = getHeight();
			y = 0;
		}
		if (y == 0) {
			g.setColor (Color.WHITE);
			g.fillRect (0, 0, w, h);
			g.setColor (Color.BLACK);
			cells = cZeros ("1");
		} else {

// détermination de la nouvelle série de cellules
			String ncells = "";
			int clmn = cells.length() - ncases;
			for (int i = 0; i <= clmn; i++) {
				ncells += loi.charAt (index (cells.substring (i, i + ncases)));
			}
			cells = cZeros (ncells);
		}

// affichage de la série de cellules
		int cl = cells.length();
		int x = (w - dimCote * cl) / 2;
		for (int i = 0; i < cl; i++) {
			if (cells.charAt (i) == '1')
				g.fillRect (x, y, dimCote + 1, dimCote + 1);
			else
				g.drawRect (x, y, dimCote, dimCote);
			x += dimCote;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////

	public static void main (String [] args) {
		int w = 600;
		int h = 600;

		autocell a = new autocell();

		JFrame f = new JFrame ("Automate cellulaire");
		f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		f.add (a);
		f.setSize (w, h);
		f.setVisible (true);
	}

}