import java.awt.*;

public class tilt extends BufferedApplet
{
   int width = 0, height;
   double theta = 0, cos = 1, sin = 0;
   int w;
   int X, Y;
   Graphics g;

   double avgDt = .1;

   public void render(Graphics g) {
      this.g = g;
      int x, y;
      if (width == 0) {
	 width  = bounds().width;
	 height = bounds().height;
	 w = width / 40;

	 X = width/2;
	 Y = 2*height/3;

         time = System.currentTimeMillis() / 1000.;
      }

      // CLEAR BACKGROUND

      g.setColor(Color.white);
      g.fillRect(0,0,width,height);

      cos = Math.cos(theta);
      sin = Math.sin(theta);

      // DRAW WHEELS

      g.setColor(Color.black);
      g.fillRect(X - 2*w, Y, 4*w, 2*w);
      g.setColor(Color.blue);
      g.fillOval(X - 2*w - 3*w/2, Y+2*w-3*w/2, 3*w, 3*w);
      g.fillOval(X + 2*w - 3*w/2, Y+2*w-3*w/2, 3*w, 3*w);

      // DRAW TABLE TOP

      g.setColor(Color.black);
      drawLine(-width/3, -height/2,   width/3, -height/2);
      drawLine(-width/3, -height/2-w, width/3, -height/2-w);
      drawLine(-width/3, -height/2,  -width/3, -height/2-w);
      drawLine( width/3, -height/2  , width/3, -height/2-w);

      // DRAW SUPPORT PILLAR

      drawLine(-w, 0, -w, -height/2);
      drawLine( w, 0,  w, -height/2);
      fillDisk( 0, 0,  w);
      g.setColor(Color.white);
      fillDisk( 0,-1,  w-1);
      fillDisk( 0,-2,  w-1);
      fillDisk( 0,-3,  w-1);

      // DRAW PENDULUM

      int dx = (int)Math.max(-4,Math.min(4,accelaration));

      g.setColor(Color.red);
      drawLine(dx  ,-height/4, 0, -height/2 + w);
      drawLine(dx-1,-height/4,-1, -height/2 + w);
      drawLine(dx+1,-height/4, 1, -height/2 + w);
      fillDisk(dx,-height/4,w - 2);

      theta *= .9;
      animating = Math.abs(theta) > .0001;
   }

   void drawLine(int ax, int ay, int bx, int by) {
      int ux = ax, uy = ay;
      int vx = bx, vy = by;

      ax = (int)(ux * cos + uy * sin);
      ay = (int)(uy * cos - ux * sin);
      bx = (int)(vx * cos + vy * sin);
      by = (int)(vy * cos - vx * sin);

      g.drawLine(X + ax, Y + ay, X + bx, Y + by);
   }

   void fillDisk(int x, int y, int r) {
      int ux = x, uy = y;

      x = (int)(ux * cos + uy * sin);
      y = (int)(uy * cos - ux * sin);

      g.fillOval(X + x - r, Y + y - r, 2*r, 2*r);
   }

   int mx, my;

   public boolean mouseDown(Event e, int x, int y) {
      mx = x;
      my = y;
      return true;
   }

   double dt, time, velocity = 0, accelaration = 0;
   int dx = 0;

   public boolean mouseDrag(Event e, int x, int y) {

      dx = (dx + x - mx) / 2;
      int newX = X + dx;

      double newTime = System.currentTimeMillis() / 1000.;
      dt = newTime - time;
      if (dt < .001)
	 return true;

      time = newTime;

      double dxdt = dx / dt / width;

      if (newX > 10 && newX < width-10) {
         X += dx;

         accelaration = dxdt - velocity;
         velocity = .5 * velocity + .5 * dxdt;
         theta -= .04 * accelaration;
      }
      mx = x;
      my = y;
      damage = true;
      return true;
   }
   public boolean mouseUp(Event e, int x, int y) {
      return true;
   }
}

