package pythagoras;

import java.applet.*;
import java.awt.*;
import psplot.*;
import real.*;

class BucklandRotator implements Runnable {
	BucklandCanvas s;
	double inc = 0.025;
	
	public BucklandRotator(BucklandCanvas s) {
		this.s = s;
	}
	
	public void run() {
		while (s.t <= 1.0) {
			s.t += inc;
			s.repaint();
			try {
				Thread.sleep(50);
			} catch(InterruptedException ex) { ; }
		}
	}
	
}

class BucklandCanvas extends PlotCanvas {
	double A, B, C;
	PlotNode cn;
	double t = 0;
	BucklandRotator sr;
	Thread th;
	
	public BucklandCanvas(Applet a, int w, int h, double x, double y) {
		super(a, w, h);
		A = x; B = y;
		C = Math.sqrt(A*A + B*B);
		double W = 8, H = W*h/w;
		setCorners(-W, -H, W, H);
		// set the origin at the centre
		translate(-(A+B)/2.0, -(A+B)/2.0);
		cn = new PlotNode(this, new RealPoint(B, A+B));
		sr = new BucklandRotator(this);
		mkFixedpaths();
	}
	
	PlotPath smallsquare;
	PlotPath bigsquare;
	PlotPath triangle;
	PlotPath csquare;
	
	void mkFixedpaths() {
	
		bigsquare = new PlotPath(this);
		bigsquare.moveto(0, 0);
		bigsquare.lineto((A+B), 0);
		bigsquare.lineto((A+B), (A+B));
		bigsquare.lineto(0, (A+B));
		bigsquare.close();
		
	}
	
	boolean ready = true;

	public void draw() {
		ready = false;
		csquare = new PlotPath(this);
		csquare.moveto(A, 0);
		csquare.lineto(A+B, A);
		csquare.lineto(B, (A+B));
		csquare.lineto(0, B);
		csquare.close();
		// csquare.fill(Color.red);
		csquare.stroke(Color.black);
		
		triangle = new PlotPath(this);
		translate(0, B);
		triangle.moveto(0, 0);
		RealPoint P = new RealPoint(B, 0);
		triangle.rlineto(P.x, P.y);
		P = new RealPoint(0, A);
		triangle.rlineto(P.x, P.y);
		triangle.close();
		triangle.stroke(Color.black);
		translate(0, -B);
		
		triangle = new PlotPath(this);
		// rotate(t*Math.PI);
		translate(0, B);
		triangle.moveto(0, 0);
		P = new RealPoint(B, 0);
		P = P.rotated(t*1.5*Math.PI);
		triangle.rlineto(P.x, P.y);
		P = new RealPoint(0, A);
		P = P.rotated(t*1.5*Math.PI);
		triangle.rlineto(P.x, P.y);
		triangle.close();
		// triangle.fill(Color.green);
		triangle.fill(Color.red);
		triangle.stroke(Color.black);
		translate(0, -B);
		
		triangle = new PlotPath(this);
		translate(A+B, A);
		// rotate(-t*Math.PI);
		triangle.moveto(0, 0);
		P = new RealPoint(-A, 0);
		P = P.rotated(-t*1.5*Math.PI);
		triangle.rlineto(P.x, P.y);
		P = new RealPoint(0, B);
		P = P.rotated(-t*1.5*Math.PI);
		triangle.rlineto(P.x, P.y);
		triangle.close();
		// triangle.fill(Color.blue);
		triangle.fill(Color.red);
		triangle.stroke(Color.black);
		translate(-A-B, -A);
		
		triangle = new PlotPath(this);
		triangle.moveto(A+B, A);
		triangle.rlineto(-B, 0);
		triangle.rlineto(0, -A);
		triangle.close();
		triangle.fill(Color.red);
		triangle.stroke(Color.black);
		
		triangle = new PlotPath(this);
		triangle.moveto(A, 0);
		triangle.rlineto(0, B);
		triangle.rlineto(-A, 0);
		triangle.close();
		triangle.fill(Color.red);
		triangle.stroke(Color.black);
		
		smallsquare = new PlotPath(this);
		double D = B-A;
		smallsquare.moveto(A, B);
		smallsquare.rlineto(D, 0);
		smallsquare.rlineto(0, -D);
		smallsquare.rlineto(-D, 0);
		smallsquare.close();
		// smallsquare.fill(Color.pink);
		smallsquare.fill(Color.red);
		smallsquare.stroke(Color.black);
		
		cn.draw();
		ready = true;
	}
	
	int active = -1;

	public boolean mouseDown(Event evt, int x, int y) {
		// if (x, y) inside a node set mouseState = MouseActive
		RealPoint P = toRealPoint(x, y);
		if (cn.contains(P)) {
			active = 0;
			t = 0.0;
		} else {
			if (t > 1.0) {
				t = 0.0;
			}
			else {
				active = 1;
				th = new Thread(sr);
				th.start();
			}
		}
		repaint();
		return true;
	}

	public boolean mouseDrag(Event evt, int x, int y) {
		if (active == 0 && ready) {
			RealPoint q = toRealPoint(x, y);
			if (q.x < 0) q.x = 0;
			else if (q.x > (A+B)) q.x = A+B;
			q.y = (A+B);
			A = (B + A) - q.x;
			B = q.x;
			C = Math.sqrt(A*A + B*B);
			cn.locate(q);
			repaint();
		}
		return true;
	}

	public boolean mouseUp(Event evt, int x, int y) {
		// set nodes inactive
		if (active == 1) {
			th.stop();
		}
		active = -1;
		return true;
	}
}

public class BucklandApplet extends Applet {

	double a = 2.6/2.0, b = Math.sqrt(25.0 - 4*a*a)/2.0;
	BucklandCanvas baby;
	
	public void init() {
		setBackground(Color.white);
		// System.out.println("***");
		baby = new BucklandCanvas(this, bounds().width, bounds().height,
				 a, b);
		add(baby);
		show();
	}

}