/**
 * mandelb.java
 * Jean-Paul Quelen
 * 18/04/2020
 *
 * trace l'ensemble de Mandelbrot avec des couleurs aléatoires
 */

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

public class mandelb extends JPanel implements MouseListener, ActionListener {
	static final long serialVersionUID = 200418L;
	int xmax, ymax, Niter, NCouleur, x, y, n, nm1;
	double Zoom, Rayon2, xo, yo, pas;
	int [] [] TCouleur;
	Random r;
	double Cy, Cx, Zx, Zy, Z;
	TextField mult;
	Button nt;

	public mandelb() {
		setCursor (new Cursor (Cursor.CROSSHAIR_CURSOR));
		NCouleur = 256;
		Niter = 256;
		add (mult = new TextField ("x 1", 10));
		Font f = new Font ("Helvetica", Font.PLAIN, 10);
		mult.setFont (f);
		mult.setBackground (Color.black);
		mult.setForeground (Color.white);
		add (nt = new Button ("Nouveau tracé"));
		nt.setFont (f);
		nt.addActionListener (this);
		addMouseListener (this);
		setBackground (Color.black);
	}

// (ré)initialisation
	public void init () {
		xo = yo = 0;
		Rayon2 = 4.0;
		Zoom = 1.0;
		pas = 4.0 / Zoom / (xmax > ymax ? xmax : ymax);
		y = 0;
		Cy = yo - ymax * pas / 2.0;
		mult.setText ("x 1");
// nouvelles couleurs
		TCouleur = new int [Niter] [3];
		r = new Random ();
		int Niterm1 = Niter - 1;
		TCouleur [Niterm1] [0] = TCouleur [Niterm1] [1] = TCouleur [Niterm1] [2] = 0;
		for (n = 0; n < Niterm1; n++)
			for (int p = 0; p < 3; p++)
				TCouleur [n] [p] = Math.abs (r.nextInt ()) % NCouleur;
	}

	public void update (Graphics g) {
		paint (g);
	}

	public void paint (Graphics g) {
		if (xmax != getWidth() || ymax != getHeight()) {
			xmax = getWidth();
			ymax = getHeight();
			init();
		}
		while (y < ymax) {
			Cx = xo - xmax * pas / 2.0;
			for (x = 0; x < xmax; x ++ ) {
				Zx = Zy = 0.0;
				n = 0;
				while (((Zx * Zx + Zy * Zy) < Rayon2) & (n < Niter)) {
					Z = Zx * Zx - Zy * Zy + Cx;
					Zy = 2.0 * Zx * Zy + Cy;
					Zx = Z;
					n++;
				}
				nm1 = n - 1;
				g.setColor (new Color (TCouleur [nm1] [0], TCouleur [nm1] [1], TCouleur [nm1] [2]));
				g.drawLine (x, y, x, y);
				Cx += pas;
			}
			Cy += pas;
			y ++;
		}
	}

	public void actionPerformed (ActionEvent e) {
		if (e.getSource() == nt) {
			init();
		}
		repaint();
	}

	public void mousePressed (MouseEvent e) {
		xo += pas * (e.getX () - xmax / 2.0);
		yo += pas * (e.getY () - ymax / 2.0);
		Zoom *= 2.0;
		pas = 4.0 / Zoom / ((xmax > ymax) ? xmax : ymax);
		y = 0;
		Cy = yo - ymax * pas / 2.0;
		mult.setText ("x " + (int) Zoom);
		repaint();
	}

  public void mouseReleased (MouseEvent e) {}
  public void mouseClicked (MouseEvent e) {}
  public void mouseEntered (MouseEvent e) {}
  public void mouseExited (MouseEvent e) {}

////////////////////////////////////////////////////////////////////////////////

	public static void main (String [] args) {
		int w = 600;
		int h = 600;

		mandelb m = new mandelb();

		JFrame f = new JFrame ("Ensemble de Mandelbrot");
		f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		f.add (m);
		f.setSize (w, h);
		f.setVisible (true);
	}
  
}
