import java.awt.*;
import java.lang.Math;

public class Gears extends BufferedApplet {
	int wid_, hei_;
	long T0 = -1;
	double tlast_ = 0.;
	Cube cube_ = new Cube();
	Sphere sphere_ = new Sphere(14,15);
	Gear gear1_ = new Gear(10,.15),
		gear2_ = new Gear(5,.2),
		gear3_ = new Gear(6,.1),
		gear4_ = new Gear(180,.005);
	final double d12 = .7, d13 = .75, d34 = 9.25;
	Vector3D g1pos_ = new Vector3D(-0.5,-0.5,0),
		g2pos_ = new Vector3D(g1pos_.x()+d12,g1pos_.y(),0),
		g3pos_ = new Vector3D(g1pos_.x(),g1pos_.y()+d13,0),
		g4pos_ = new Vector3D(-0.5+d34*Math.sqrt(2.)/2.,-0.5+d13+d34*Math.sqrt(2)/2.,0),
		g5pos_ = new Vector3D(),
		g6pos_ = new Vector3D(),
		g7pos_ = new Vector3D(),
		g8pos_ = new Vector3D(),
		g9pos_ = new Vector3D(),
		g0pos_ = new Vector3D(),
		g1siz_ = new Vector3D(0.5,0.5,0.5),
		g2siz_ = new Vector3D(0.25,0.25,0.5),
		g3siz_ = new Vector3D(0.3,0.3,0.5),
		g4siz_ = new Vector3D(9,9,1),
		g5siz_ = new Vector3D(),
		g6siz_ = new Vector3D(),
		g7siz_ = new Vector3D(),
		g8siz_ = new Vector3D(),
		g9siz_ = new Vector3D(),
		g0siz_ = new Vector3D();
	Matrix3D view_ = new Matrix3D();
	Color backg_ = Color.white;
	public void init() {
		super.init();
		wid_ = getBounds().width;
		hei_ = getBounds().height;
		animating=true;
		view_.identity();
		cube_.setScale(.57,.61,.59);
		//cube_.setRotationZ(0.08);
		cube_.setSkewXY(0,1);
		sphere_.setRotationZ(0.1);
		view_.yRotation(.1);
		view_.xRotation(.05);
		gear1_.setScale(g1siz_);
		gear2_.setScale(g2siz_);
		gear3_.setScale(g3siz_);
		gear4_.setScale(g4siz_);
		gear1_.next_[0] = gear2_;
		gear1_.next_[1] = gear3_;
		gear2_.next_[0] = gear4_;
		gear1_.setTranslation(g1pos_);
		gear2_.setTranslation(g2pos_);
		gear3_.setTranslation(g3pos_);
		gear4_.setTranslation(g4pos_);
	}
	double vel_=0.,push_=.0; // velocity of time!
	final double DRAG = .1;
	public void render(Graphics g) {
		long T = System.currentTimeMillis();
		if(T0<0) {
			T0 = T;
			return; // in case zero time is bad
		}
		double t = (T-T0) / 1000.0,
			dt = t - tlast_;
		Graphics2D g2 = (Graphics2D)g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
	    g.setColor(backg_);
     	g.fillRect(0,0,wid_,hei_);
		
		double mov = (dt*(push_-DRAG)) /10.;
		vel_ += mov;
		if(vel_<0.)
			vel_ = 0.;
		System.out.println("dt " + dt + " mov " + mov + " -> vel " + vel_);

		/*
		cube_.setRotationX(t/10.);
		cube_.setRotationY(t/20.);
		cube_.render(view_,wid_,hei_);
		cube_.draw(g);
		
		/*
		sphere_.setRotationY(t/9);
		sphere_.render(view_,wid_,hei_);
		sphere_.draw(g);
		*/
		
		gear1_.spin(vel_);
		gear1_.render(view_,wid_,hei_);
		gear1_.draw(g);
		gear2_.render(view_,wid_,hei_);
		gear2_.draw(g);
		gear3_.render(view_,wid_,hei_);
		gear3_.draw(g);
		gear4_.render(view_,wid_,hei_);
		gear4_.draw(g);
		
		tlast_ = t;
	}
	Vector3D mouse_ = new Vector3D();
	public boolean mouseMove(Event e, int wx, int wy) {
		int smdim = Math.min(hei_,wid_);
		mouse_.set(0,2.*wx/smdim - 1.);
		mouse_.set(1,2.*(hei_-wy)/smdim - 1.);
		double d = mouse_.dist(g2pos_),
			r = g2siz_.magn();
		if(d<r) {
			push_ = ((r-d)/r/3+Math.sin(tlast_)+1.)/20.;
			if(push_>1.)
				push_ = 1.;
		}
		else
			push_ = 0.;
		System.out.println("d " + d + " r " + r + " push " + push_
			+ " = vel " + vel_);
		return true;
	}
	
}
