/**
 * sym5.java - jpq - 07/07/99
 * double-buffering
 * jdk1.2
 * modification et ajout de main() le 22/12/17 ; modification le 06, 12 et le 22/09/22
 */

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.Random;
import geo.*;

public class sym5 extends Panel implements MouseListener, MouseMotionListener, ActionListener {
	static final long serialVersionUID = 220922L;
	static Repere R;
	int X, Y;
	static Image img;
	static Graphics g1;
	int gw, gh;

// on definit ici les objets mathématiques
	static Pt[] Ai = new Pt [4];
	static Pt[] Bi = new Pt [4];
	static Pt[] Oki = new Pt [4];
	static Pt O;
	static PointLibre OOk, AOk, BOk;
	double x, y, x0, y0, x1, y1;
	static Droite d, dOk;
	static Polygone pA, pB, pOk;

	int pas = 40;
	int pass2 = 20;
	Button sa = new Button ("symétrie par rapport à d");
	Button sc = new Button ("symétrie par rapport à O");
	Button ns = new Button ("nouveau");
	Random rnd = new Random();
	boolean typsymcent;

//----------------------------------------------------------------------------
	public sym5() {
		addMouseMotionListener (this);
		addMouseListener (this);

		sa.setFont (new Font ("Arial", Font.PLAIN, 10));
		sa.addActionListener (this);
		add (sa);
		sc.setFont (new Font ("Arial", Font.PLAIN, 10));
		sc.addActionListener (this);
		add (sc);
		ns.setFont (new Font ("Arial", Font.PLAIN, 10));
		ns.addActionListener (this);
		add (ns);
		setBackground (Color.WHITE);
	}

	public void update (Graphics g) {
		paint (g);
	}

	public void paint (Graphics g) {
		if (img == null || gw != getSize().width || gh != getSize().height) {
			gw = getSize().width;
			gh = getSize().height;
			img = createImage (gw, gh);
			g1 = img.getGraphics();

// on initialise ici les objets mathématiques
			if (R == null) {
				R = new Repere (gw / 2, gh / 2, gw, gh, pas, pas);
				O = new Pt (R.x (R.X (0.0) / pass2 * pass2), R.y (R.Y (0.0) / pass2 * pass2));
				OOk = new PointLibre (0.5, 0.5);
				AOk = new PointLibre (-0.5, -0.5);
				BOk = new PointLibre (-1.0, 1.0);
				dOk = new Droite (AOk, BOk);
				Ai [0] = new Pt (-0.5, -1.5);
				Ai [1] = new Pt (1.5, -1.5);
				Ai [2] = new Pt (1.0, -0.5);
				Ai [3] = new Pt (1.5, 1.5);
				typsymcent = true;
				d = new Droite();
				for (int i = 0; i < 4; i++) {
					Bi[i] = Ai[i].symetrie (O);
					Oki[i] = new Pt();
				}
				pA = new Polygone (Ai);
				pB = new Polygone (Bi);
				pOk = new Polygone (Oki);
			} else {
				R.MAJ (gw / 2, gh / 2, gw, gh, pas, pas);
			}
			g1.setFont (new Font ("Arial", Font.PLAIN, 12));		
		}


// on recalcule les objets liés
		dOk.MAJ (AOk, BOk);
		Ai[0].MAJ (Ai[0].x, Ai[0].y);
		Ai[1].MAJ (Ai[1].x, Ai[1].y);
		Ai[2].MAJ (Ai[2].x, Ai[2].y);
		Ai[3].MAJ (Ai[3].x, Ai[3].y);
		for (int i = 0; i < 4; i++) {
			Bi[i].MAJ (Bi[i]);
			Oki[i].MAJ (Oki[i]);
		}
		pA.MAJ (Ai);
		pB.MAJ (Bi);
		pOk.MAJ (Oki);

// on trace dans la couleur du fond les objets liés
		g1.setColor (getBackground());
		g1.fillRect (0, 0, R.XMAX, R.YMAX);

// on trace
		g1.setColor (Color.blue);
		pA.trace (false, "", R, g1);

		g1.setColor (Color.CYAN);
		pB.trace (false, "", R, g1);

		g1.setColor (Color.BLACK);
		pOk.trace (false, "", R, g1);

//		g1.setColor (Color.BLACK);
		R.cadre (g1);

		g1.setColor (Color.GREEN);
		dOk.trace ("d", R, g1);

		g1.setColor (Color.RED);
		OOk.trace ("O", R, g1);
		AOk.trace ("", R, g1);
		BOk.trace ("", R, g1);

		g.drawImage (img, 0, 0, this);
	}

	private void alea() {
		int i = rnd.nextInt() % (getSize().width / 4);
		x = R.x ((i + R.X (0.0)) / pass2 * pass2);
		i = rnd.nextInt() % (getSize().height / 4);
		y = R.y ((i + R.Y (0.0)) / pass2 * pass2);
	}

	public void actionPerformed (ActionEvent e) {
		if ((e.getSource() == sa) || (e.getSource() == sc)) {
			if (e.getSource() == sa)
				for (int i = 0; i < 4; i++)
					Oki[i] = Ai[i].symetrie (dOk);
			else
				for (int i = 0; i < 4; i++)
					Oki[i] = Ai[i].symetrie (OOk);
			pOk.MAJ (Oki);
		} else {			// == ns
			typsymcent = rnd.nextBoolean();
			for (int i = 0; i < 4; i++) {
				alea();
				Ai[i].MAJ (x, y);
			}
			pA.MAJ (Ai);
			alea();
			x0 = x;
			y0 = y;
			if (typsymcent) {
				O.MAJ (x0, y0);
				for (int i = 0; i < 4; i ++)
					Bi[i] = Ai[i].symetrie (O);
			} else {
				alea();
				d.MAJ (x0, y0, x, y);
				for (int i = 0; i < 4; i ++)
					Bi[i] = Ai[i].symetrie (d);
			}
			pB.MAJ (Bi);
		}
		repaint();
	}

	public void mousePressed (MouseEvent e) {
		int X = e.getX();
		int Y =  e.getY();
		if (OOk.deplace = OOk.zone (X, Y, R)) {
		} else if (AOk.deplace = AOk.zone (X, Y, R)) {
		} else if (BOk.deplace = BOk.zone (X, Y, R)) {
		}
	}

	public void mouseDragged (MouseEvent e) {
		int X = e.getX();
		int Y = e.getY();
		OOk.bouge (X, Y, R);
		AOk.bouge (X, Y, R);
		BOk.bouge (X, Y, R);
		repaint();
	}

	public void mouseReleased (MouseEvent e) {
		OOk.deplace = AOk.deplace = BOk.deplace = false;
	}


	public void mouseMoved (MouseEvent e) {
		int X = e.getX();
		int Y = e.getY();
		if (OOk != null) {
			if (OOk.zone (X, Y, R) || AOk.zone (X, Y, R) || BOk.zone (X, Y, R)) {
				setCursor (new Cursor (Cursor.HAND_CURSOR));
			} else {
				setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
			}
		}
	}

	public void mouseClicked (MouseEvent e) {}
	public void mouseEntered (MouseEvent e) {}
	public void mouseExited (MouseEvent e) {}


	public static void main (String[] args) {
		sym5 s5 = new sym5();
		JFrame f = new JFrame ("sym5");
		f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		f.add (s5);
		f.setSize (600, 600);
		f.setVisible (true);
	}

}
