/**
 * pscalaire.java - jpq - 25/04/99 - jdk1.2 - double-buffering
 * modification et ajout de main() le 22/12/17. Modification le 04, 12 et le 22/09/2022
 */

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import geo.*;

public class pscalaire extends JFrame {
	static final long serialVersionUID = 220922L;
	static Repere R;
	int X, Y, Xp, Yp;
	static Image img;
	static Graphics g1;
	int gw, gh;
	Feuille dessin = new Feuille();

// on definit ici les objets mathématiques
	static PointLibre A, B, C, D, I, J;
	static Pt K, L;
	static Vecteur AB, CD;
	static Segment CK, DL, KL, sAB;
	JLabel lb;
	int pas = 40;
	int an;

	public pscalaire (String titre) {
		super (titre);
		setLayout (new BorderLayout());
		JPanel jp = new JPanel();
		jp.setBackground (Color.BLACK);
		add (jp, BorderLayout.NORTH);
		
		jp.add (lb = new JLabel ("u.v = ----------"));
		Font f = new Font ("Arial", Font.PLAIN, 14);
		lb.setFont (f);
//		lb.setBackground (Color.BLACK);
		lb.setForeground (Color.WHITE);
		setBackground (Color.WHITE);
		add (dessin, BorderLayout.CENTER);
	}

	private String reducfraction (int n, int d) {
		boolean signe = n * d < 0;
		n = Math.abs (n);
		d = Math.abs (d);
		int a = (n >= d) ? n : d;
		int b = (n >= d) ? d : n;
		while (b > 0)
			b = a % (a = b);
		n = n / a;
		d = d / a;
/*		if (d == 1)
			String s = Integer.toString (n);
		else
			return Integer.toString (n) + " / " + Integer.toString (d); */
		return ((signe) ? " - " : "") + Integer.toString (n) + ((d == 1)? "" : " / " + Integer.toString (d));
	}

protected class Feuille extends Canvas  implements MouseListener, MouseMotionListener {
	static final long serialVersionUID = 220922L;

	public Feuille() {
		setBackground (Color.WHITE);
		addMouseMotionListener (this);
		addMouseListener (this);
	}

	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();

			if (R == null) {
// on initialise ici les objets mathématiques
				R = new Repere (gw / 2, gh / 2, gw, gh, pas, pas);
				A = new PointLibre (-2.5, -1.0);
				B = new PointLibre (4.0, -1.0);
				AB = new Vecteur();
				C = new PointLibre (-2.0, 1.0);
				D = new PointLibre (3.0, 3.0);
				CD = new Vecteur();
				I = new PointLibre (0.5 * (A.x + B.x), 0.5 * (A.y + B.y));
				J = new PointLibre (0.5 * (C.x + D.x), 0.5 * (C.y + D.y));
				K = new Pt();
				L = new Pt();
				CK = new Segment();
				DL = new Segment();
				KL = new Segment();
				sAB = new Segment();
			} else {
				R.MAJ (gw / 2, gh / 2, gw, gh, pas, pas);
			}
		}

// on recalcule les objets liés
		if (I.deplace) {
			A.MAJ (Math.rint (I.x * 2.0 - AB.x) / 2.0, Math.rint (I.y * 2.0 - AB.y) / 2.0);
			B.MAJ (Math.rint (I.x * 2.0 + AB.x) / 2.0, Math.rint (I.y * 2.0 + AB.y) / 2.0);
			I.MAJ (0.5 * (A.x + B.x), 0.5 * (A.y + B.y));
		} else if (J.deplace) {
			C.MAJ (Math.rint (J.x * 2.0 - CD.x) / 2.0, Math.rint (J.y * 2.0 - CD.y) / 2.0);
			D.MAJ (Math.rint (J.x * 2.0 + CD.x) / 2.0, Math.rint (J.y * 2.0 + CD.y) / 2.0);
			J.MAJ (0.5 * (C.x + D.x), 0.5 * (C.y + D.y));
		} else if (A.deplace || B.deplace) {
			A.MAJ (0.5 * Math.round (2.0 * A.x), 0.5 * Math.round (2.0 * A.y));
			B.MAJ (0.5 * Math.round (2.0 * B.x), 0.5 * Math.round (2.0 * B.y));
			I.MAJ (0.5 * (A.x + B.x), 0.5 * (A.y + B.y));
		} else if (C.deplace || D.deplace) {
			C.MAJ (0.5 * Math.round (2.0 * C.x), 0.5 * Math.round (2.0 * C.y));
			D.MAJ (0.5 * Math.round (2.0 * D.x), 0.5 * Math.round (2.0 * D.y));
			J.MAJ (0.5 * (C.x + D.x), 0.5 * (C.y + D.y));
		}
		AB.MAJ (A, B);
		CD.MAJ (C, D);
		an = (int) (((B.x - A.x) * (D.x - C.x) + (B.y - A.y)*(D.y - C.y)) * 4.0);
		sAB.MAJ (A, B);
		K = C.projection (sAB);
		L = D.projection (sAB);
		CK.MAJ (C, K);
		DL.MAJ (D, L);
		KL.MAJ (K, L);

		g1.setFont (new Font (Font.SANS_SERIF, Font.PLAIN, 10));

// on trace dans la couleur du fond
		g1.setColor (getBackground());
		g1.fillRect (0, 0, R.XMAX, R.YMAX);

// on trace
		lb.setText ("u.v = " + reducfraction (an, 4));

		g1.setColor (Color.YELLOW);
		R.trace_grille (0.5, 0.5, g1);

		g1.setColor (Color.BLACK);
		R.cadre (g1);

		g1.setColor (Color.GREEN);
		K.traceNom ("K", R, g1);
		L.traceNom ("L", R, g1);
		CK.trace ("", R, g1);
		DL.trace ("", R, g1);
		KL.trace ("", R, g1);

		g1.setColor (Color.RED);
		R.trace (g1);
		R.trace_repere_gradue (1.0, 1.0, g1);

		g1.setColor (Color.BLUE);
		AB.trace (A, "u", R, g1);
		CD.trace (C, "v", R, g1);

		g1.setColor (Color.RED);
		A.trace ("A", R, g1);
		B.trace ("B", R, g1);
		C.trace ("C", R, g1);
		D.trace ("D", R, g1);
		I.trace (null, R, g1);
		J.trace (null, R, g1);

		g.drawImage (img, 0, 0, this);
	}

	public void mousePressed (MouseEvent e) {
		int X = e.getX();
		int Y =  e.getY();
		if (A.deplace = A.zone (X, Y, R)) {
		} else if (B.deplace = B.zone (X, Y, R)) {
		} else if (C.deplace = C.zone (X, Y, R)) {
		} else if (D.deplace = D.zone (X, Y, R)) {
		} else if (I.deplace = I.zone (X, Y, R)) {
		} else if (J.deplace = J.zone (X, Y, R)) {
		}
	}
 
	public void mouseDragged (MouseEvent e) {
		int X = e.getX();
		int Y =  e.getY();
		A.bouge (X, Y, R);
		B.bouge (X, Y, R);
		C.bouge (X, Y, R);
		D.bouge (X, Y, R);		 
		I.bouge (X, Y, R);
		J.bouge (X, Y, R);
		repaint();
	}

	public void mouseReleased (MouseEvent e) {
		A.deplace = B.deplace = C.deplace = D.deplace = I.deplace = J.deplace = false;
	}

	public void mouseMoved (MouseEvent e) {
		int X = e.getX();
		int Y = e.getY();
		if (A.zone (X, Y, R) || B.zone (X, Y, R) || C.zone (X, Y, R)
				|| D.zone (X, Y, R) || I.zone (X, Y, R) || J.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) {}

}	// fin de protected class Feuille

	public static void main (String[] args) {
		pscalaire p = new pscalaire ("pscalaire");
		p.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		p.setSize (600, 600);
		p.setVisible (true);
	}

}
