/**
 * folium.java - jpq - 03/02/99
 * jdk1.2 - 22/03/99
 * main() ajouté le 19/12/17. Modification le 15 et le 22/09/22
 */

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import geo.*;

public class folium extends Panel implements MouseListener, MouseMotionListener {
	static final long serialVersionUID = 220922L;
	static Repere R;

// on definit ici les objets mathématiques
	static Pt C, P, M, Q;
	static PointLibre A;
	static PointSurDroite B, D, N;
	static Droite xpx, ypy, dBC, dCD, dAN, dNP, dPQ, dMQ;
	static Segment AB, BN, DP, DA, AN, NP, PQ, QM, MN;
	int gw, gh;

	public folium() {
		setBackground (Color.WHITE);
		addMouseMotionListener (this);
		addMouseListener (this);
	}

	public void update (Graphics g) {
		paint (g);
	}

	public void paint (Graphics g) {
		g.setFont (new Font (Font.SANS_SERIF, Font.PLAIN, 10));
		g.setColor (getBackground());
		if (gw != getSize().width || gh != getSize().height) {
			gw = getSize().width;
			gh = getSize().height;

// on initialise ici les objets mathématiques
			if (R == null) {
				R = new Repere (gw / 2, gh / 2, gw, gh, 40.0, 40.0);
				A = new PointLibre (0.0, 0.0);
				xpx = new Droite (0.0, 1.0, 0.0);
				B = new PointSurDroite (1.0, 0.0, xpx);
				ypy = new Droite (1.0, 0.0, 0.0);
				D = new PointSurDroite (0.0, 1.0, ypy);
				C = new Pt (B.x, D.y);
				dCD = new Droite (0.0, 1.0, -D.y);
				AB = new Segment (A, B);
				BN = new Segment();
				DP = new Segment();
				DA = new Segment (D, A);
				dBC = new Droite (1.0, 0.0, -B.x);
				N = new PointSurDroite (1.0, 2.0, dBC);
				dAN = new Droite();
				AN = new Segment();
				dNP = new Droite();
				P = new Pt();
				dPQ = new Droite();
				Q = new Pt();
				dMQ = new Droite();
				M = new Pt();
				NP = new Segment();
				PQ = new Segment();
				QM = new Segment();
				MN = new Segment();
			} else {
				R.MAJ (R.X (A.x), R.Y (A.y), gw, gh, R.unitex, R.unitex);
				A.MAJ (0.0, 0.0);
			}
			g.fillRect (0, 0, R.XMAX, R.YMAX);
		}

// on trace dans la couleur du fond les objets liés
		if ((A.deplace) || (B.deplace) || (D.deplace)) {
			if (A.deplace) {
				R.MAJ (R.X (A.x), R.Y (A.y), gw, gh, R.unitex, R.unitex);
				A.MAJ (0.0, 0.0);
			}
			g.fillRect (0, 0, R.XMAX, R.YMAX);
		} else {
			BN.trace ("", R, g);
			DP.trace ("", R, g);
			AN.trace ("", R, g);
			NP.trace ("", R, g);
			PQ.trace ("", R, g);
			QM.trace ("", R, g);
			MN.trace ("", R, g);
			P.traceNom ("P", R, g);
			Q.traceNom ("Q", R, g);
			M.traceNom ("M", R, g);
			N.trace ("N", R, g);
		}

// on recalcule les objets liés

		if ((A.deplace) || (B.deplace) || (D.deplace)) {
			C.MAJ (B.x, D.y);
			AB.MAJ (A, B);
			DA.MAJ (D, A);
			dCD.MAJ (0.0, 1.0, -D.y);
			dBC.MAJ (1.0, 0.0, -B.x);
			N.MAJ();
		}
			AN.MAJ (A, N);
			dAN.MAJ (-N.y, N.x, 0.0);
			dNP = dAN.perpendiculaire (N);
			P = dCD.intersection (dNP);
			BN.MAJ (B, N);
			DP.MAJ (D, P);
			dPQ = dAN.parallele (P);
			Q = dBC.intersection (dPQ);
			dMQ = dAN.perpendiculaire (Q);
			M = dAN.intersection (dMQ);
			NP.MAJ (N, P);
			PQ.MAJ (P, Q);
			QM.MAJ (Q, M);
			MN.MAJ (M, N);

// on trace
//		g.setColor (Color.BLACK);
//		R.cadre (g);

		g.setColor (Color.YELLOW);
		R.trace (g);

		g.setColor (Color.CYAN);
		dBC.trace ("", R, g);

		g.setColor (Color.MAGENTA);
		AB.trace ("", R, g);
		BN.trace ("", R, g);
		DP.trace ("", R, g);
		DA.trace ("", R, g);
		C.traceNom ("C", R, g);

		g.setColor (Color.BLUE);
		AN.trace ("", R, g);
		NP.trace ("", R, g);
		PQ.trace ("", R, g);
		QM.trace ("", R, g);
		MN.trace ("", R, g);
		P.traceNom ("P", R, g);
		Q.traceNom ("Q", R, g);

		g.setColor (Color.BLACK);
		M.trace ("M", R, g);

		g.setColor (Color.RED);
		A.trace ("A", R, g);
		B.trace ("B", R, g);
		D.trace ("D", R, g);
		if (N.deplace)
			N.trace ("", R, g);
		else
			N.trace ("N", R, g);

	}

	public void mousePressed (MouseEvent e) {
		int X = e.getX();
		int Y =  e.getY();
		if (N.deplace = N.zone (X, Y, R)) {
			repaint();
		} else if (A.deplace = A.zone (X, Y, R)) {
		} else if (B.deplace = B.zone (X, Y, R)) {
		} else if (D.deplace = D.zone (X, Y, R)) {
		}
	}

	public void mouseDragged (MouseEvent e) {
		int X = e.getX();
		int Y =  e.getY();
		N.bouge (X, Y, R);
		A.bouge (X, Y, R);
		B.bouge (X, Y, R);
		D.bouge (X, Y, R);
		repaint();
	}

	public void mouseReleased (MouseEvent e) {
		N.deplace = A.deplace = B.deplace = D.deplace = false;
		repaint();
	}

	public void mouseMoved (MouseEvent e) {
		int X = e.getX();
		int Y = e.getY();
		if (N != null && N.zone (X, Y, R) || A != null && A.zone (X, Y, R) || B  != null && B.zone (X, Y, R) || D != null && D.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) {
		folium fo = new folium();
		JFrame f = new JFrame ("Le folium parabolique");
		f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		f.add (fo);
		f.setSize (600, 600);
		f.setVisible (true);
	}

}
