import java.awt.*;

public class balance extends BufferedApplet
{
   int width = 0, height;
   int cx, cy, cr; // CIRCLE X,Y,RADIUS
   int wx, wy, wr; // WEIGHT X,Y,RADIUS
   int bx[] = {0,0,0}, by[] = {0,0,0}, br;

   public void render(Graphics g) {
      if (width == 0) {
	 width  = bounds().width;
	 height = bounds().height;
	 wr = width/15;
	 wx = width/2;
	 wy = width/2;
	 br = width/30;
	 cx = width/2;
	 cy = width/2;
	 cr = width/2 - 1;

	 for (int i = 0 ; i < 3 ; i++) {
	    double theta = 2 * Math.PI * i / 3;
	    bx[i] = (int)(cx + (cr-br) * Math.cos(theta));
	    by[i] = (int)(cy + (cr-br) * Math.sin(theta));
         }
      }

      g.setColor(Color.white);
      g.fillRect(0,0,width,width);
      g.setColor(Color.black);
      g.drawOval(cx-cr, cy-cr, 2*cr, 2*cr);

      g.setColor(Color.red);
      for (int i = 0 ; i < 3 ; i++)
	 g.fillOval(bx[i]-br, by[i]-br, 2*br, 2*br);

      g.setColor(Color.blue);
      g.fillOval(wx-wr,wy-wr,2*wr,2*wr);

      rebalance();
   }

   int BX, BY;

   int oldbx[] = {0,0,0};
   int oldby[] = {0,0,0};

   void rebalance() {
      int x = 0, y = 0;
      for (int i = 0 ; i < 3 ; i++) {
	 oldbx[i] = bx[i];
	 oldby[i] = by[i];

	 x += bx[i] - cx;
	 y += by[i] - cy;
      }
      BX = cx + x/3;
      BY = cy + y/3;

      int dx = BX - (cx+(cx-wx)/2);
      int dy = BY - (cy+(cy-wy)/2);

      for (int i = 0 ; i < 3 ; i++) {
	 bx[i] -= dx;
	 by[i] -= dy;
      }

      for (int i = 0 ; i < 3 ; i++) {
	 int j = (i+1) % 3;
	 int k = (i+2) % 3;
	 double dij = dsqr(i,j), dik = dsqr(i,k);
	 bx[i] += (int)(2 * cr * (bx[i] - bx[j]) / dij);
	 by[i] += (int)(2 * cr * (by[i] - by[j]) / dij);
	 bx[i] += (int)(2 * cr * (bx[i] - bx[k]) / dik);
	 by[i] += (int)(2 * cr * (by[i] - by[k]) / dik);
      }

      for (int i = 0 ; i < 3 ; i++) {
	 int X = bx[i] - cx;
	 int Y = by[i] - cy;
	 int R = (int)Math.sqrt(X*X + Y*Y);
	 bx[i] = cx + X * (cr-br) / R;
	 by[i] = cy + Y * (cr-br) / R;
      }

      animating = false;
      for (int i = 0 ; i < 3 ; i++)
	 if (Math.abs(oldbx[i] - bx[i]) + Math.abs(oldby[i] - by[i]) > 0)
	    animating = true;
   }

   double dsqr(int i, int j) {
      double x = bx[i] - bx[j];
      double y = by[i] - by[j];
      return x * x + y * y;
   }

   int mx, my;

   public boolean mouseDown(Event e, int x, int y) {
      mx = x;
      my = y;
      return true;
   }
   public boolean mouseDrag(Event e, int x, int y) {
      int X = wx + x - mx - cx;
      int Y = wy + y - my - cy;
      if (X*X + Y*Y < (cr-wr)*(cr-wr)) {
         wx += x - mx;
         wy += y - my;
      }
      mx = x;
      my = y;
      damage = true;
      return true;
   }
   public boolean mouseUp(Event e, int x, int y) {
      return true;
   }
}

