code: package wprover;
  
  import java.io.DataOutputStream;
  import java.io.IOException;
  import java.io.DataInputStream;
  
  /**
   * Created by IntelliJ IDEA.
   * User: Administrator
   * Date: 2005-1-14
   * Time: 13:37:42
   * To change this template use File | Settings | File Templates.
   */             
  public class AnimateC {
  
      double bx, by;
  
      double minwd = 0;
      double minht = 0;
      double width = 0;
      double height = 0;
  
      CPoint pA = null;
      double x, y;
  
      Object onObj = null;
      int onType = 0; // 1:line 2:cirlce 3:trace   // 4: prove
  
  
      double dx, dy; // for line
  
      double csa, sia; // for circle
  
      double gap = CMisc.ANIMATE_GAP;
  
      int pindex = 0;
      int step_time = 0; // for trace;
  
      double delta = 0.05;
  
      public AnimateC(AnimateC n) {
          bx = n.bx;
          by = n.by;
          width = n.width;
          height = n.height;
          pA = n.pA;
          x = n.x;
          y = n.y;
          onObj = n.onObj;
          onType = n.onType;
          dx = n.dx;
          dy = n.dy;
          csa = n.csa;
          sia = n.sia;
          gap = n.gap;
          pindex = n.pindex;
          step_time = n.step_time;
          delta = n.delta;
      }
  
  
      String getAnimationString() {
          if (pA == null) {
              return null;
          }
  
          String son = "\nANI " + pA.toString();
  
          if (onType == 1) {
              CLine ln = (CLine) onObj;
              CPoint pl[] = ln.getTowSideOfLine();
              if (pl == null) {
                  return null;
              }
              son += " LN(" + pl[0] + "," + pl[1] + ") " + (int) gap;
              return son;
          } else if (onType == 2) {
              Circle c = (Circle) onObj;
              CPoint p = c.getSidePoint();
              if (c.o == null || p == null) {
                  return null;
              }
              son += " CR(" + c.o + "," + p + ") " + (int) gap;
              return son;
          }
          return null;
      }
  
      public boolean loadAnimationString(String s, drawTextProcess dp) {
          if (!s.startsWith("ANI")) {
              return false;
          }
          s = s.substring(4);
          if (s == null) {
              return false;
          }
          s = s.trim();
          int index = 0;
          int len = s.length();
  
          char c = s.charAt(index);
          String name = "";
          while (c != ' ') {
              name += c;
              index++;
              if (index >= len) {
                  return false;
              }
              c = s.charAt(index);
          }
          String s1 = "";
          while (c != '(') {
              s1 += c;
              index++;
              if (index >= len) {
                  return false;
              }
              c = s.charAt(index);
          }
          s1 = s1.trim();
  
          String sx = "";
          index++;
          if (index >= len) {
              return false;
          }
          c = s.charAt(index);
          while (c != ',') {
              sx += c;
              index++;
              if (index >= len) {
                  return false;
              }
              c = s.charAt(index);
          }
          String sy = "";
          index++;
          if (index >= len) {
              return false;
          }
          c = s.charAt(index);
          while (c != ')') {
              sy += c;
              index++;
              if (index >= len) {
                  return false;
              }
              c = s.charAt(index);
          }
          String loc = "";
          c = s.charAt(++index);
          while (index < len) {
              loc += s.charAt(index++);
          }
          CPoint p1 = dp.findPoint(name);
          CPoint p2 = dp.findPoint(sx.trim());
          CPoint p3 = dp.findPoint(sy.trim());
          int n = Integer.parseInt(loc.trim());
          Object obj = null;
          if (s1.equals("LN")) {
              {
                  obj = dp.fd_line(p2, p3);
                  if (obj == null) {
                      CLine ln = new CLine(p2, p3);
                      dp.addLineToList(ln);
                      obj = ln;
                  }
                  onType = 1;
              }
          } else if (s1.equals("CR")) {
              {
                  obj = dp.fd_circle(p2, p3);
                  if (obj == null) {
                      Circle c1 = new Circle(p2, p3);
                      dp.addCircleToList(c1);
                      obj = c1;
                  }
                  onType = 2;
              }
          }
          if (p1 == null || p2 == null || p3 == null || obj == null) return false;
          pA = p1;
          onObj = obj;
          gap = n;
          return true;
      }
  
      void Setstep(double step) {
          gap = step + delta;
  
          if (onType == 3) {
              gap = step;
              step_time = (int) (1000 / step);
          }
          this.reClaclulate();
      }
  
      public int getValue(int f) {
          if (onType == 1 || onType == 2) {
              return this.getInitValue();
          }
  
          CTrace ct = (CTrace) onObj;
          double len = ct.Roud_length();
          int n = ct.getPointSize();
          if (n == 0) {
              return 0;
          }
          int d = (int) ((f * gap * n) / (len));
          return d;
      }
  
      AnimateC() {
      }
  
      public int getInitValue() {
          return (int) gap;
      }
  
      public void valueChanged(int v) {
          if (onType == 1 || onType == 2) {
              gap = v + delta;
          }
      }
  
      AnimateC(CPoint p, Object obj, double width, double height) {
          pA = p;
          onObj = obj;
          this.width = width;
          this.height = height;
  
          if (obj instanceof CLine) {
              onType = 1;
          } else if (obj instanceof Circle) {
              onType = 2;
          } else if (obj instanceof CTrace) {
              onType = 3;
          } else {
              CMisc.print("Error,undifined on type ");
          }
          reClaclulate();
  
      }
  
      public void reClaclulate() {
          if (onType == 2) {
              Circle c = (Circle) onObj;
              CPoint pt = c.getSidePoint();
              double rx = c.o.getx();
              double ry = c.o.gety();
              double r = Math.sqrt(Math.pow(pt.getx() - rx, 2) +
                      Math.pow(pt.gety() - ry, 2));
              csa = Math.cos(-gap / r);
              sia = Math.sin(-gap / r);
          } else if (onType == 1) {
              CLine line = (CLine) onObj;
              CPoint[] pp = line.getTowSideOfLine();
              if (line.isVertical()) {
                  dx = (pp[1].getx() - pp[0].getx());
                  dy = (pp[1].gety() - pp[0].gety());
                  double r = Math.sqrt(dx * dx + dy * dy);
                  dx = dx / r;
                  dy = dy / r;
              } else {
                  if (pp[0] == pA) {
                      pp[0] = pp[1];
                      pp[1] = pA;
                  }
  
                  dx = (pp[1].getx() - pp[0].getx());
                  dy = (pp[1].gety() - pp[0].gety());
                  double r = Math.sqrt(dx * dx + dy * dy);
                  dx = dx / r;
                  dy = dy / r;
              }
          } else if (onType == 3) {
  
          } else {
              CMisc.print("Error,undifined on type ");
          }
      }
  
      public void startAnimate() {
          reClaclulate();
  
          bx = pA.getx();
          by = pA.gety();
  
          x = pA.getx();
          y = pA.gety();
  
      }
  
      public void resetXY() {
          pA.setXY(x, y);
      }
  
      public String toString() {
          if (pA == null || onObj == null)
              return super.toString();
          return pA + " on " + onObj;
      }
  
      public void stopAnimate() {
          // pA.setXY(bx, by);
      }
  
      public int getRounds() {
          if (onType == 2) {
              Circle c = (Circle) onObj;
              CPoint pt = c.getSidePoint();
              double rx = c.o.getx();
              double ry = c.o.gety();
              double r = Math.sqrt(Math.pow(pt.getx() - rx, 2) +
                      Math.pow(pt.gety() - ry, 2));
              return (int) Math.abs(Math.PI * r * 2 / gap);
          } else if (onType == 1) {
              int n1 = (int) Math.abs((width - minwd) / (gap * dx));
              int n2 = (int) Math.abs((height - minht) / (gap * dy));
              return Math.min(n1, n2) * 2;
          }
          return 0;
      }
  
      public boolean onTimer() {
          // pA.setXY(x, y);
          boolean r = true;
  
          if (onType == 2) {
              Circle c = (Circle) onObj;
              double x = pA.getx();
              double y = pA.gety();
              double rx = c.o.getx();
              double ry = c.o.gety();
  
              double x0 = csa * (x - rx) - sia * (y - ry) + rx;
              double y0 = sia * (x - rx) + csa * (y - ry) + ry;
  
              pA.setXY(x0, y0);
  
          } else if (onType == 1) {
              double x = pA.getx() + gap * dx;
              double y = pA.gety() + gap * dy;
              if (x < minwd || x > width || y < minht || y > height) {
                  dx = -dx;
                  dy = -dy;
                  r = false;
              }
              pA.setXY(x, y);
          } else if (onType == 3) {
              CTrace ct = (CTrace) onObj;
  
              int len = ct.getPointSize();
              if (len == 0) {
                  return r;
              }
              if (pindex >= len) {
                  pindex = 0;
              }
              pA.setXY(ct.getPtxi(pindex), ct.getPtyi(pindex));
              pindex++;
          }
  
          x = pA.getx();
          y = pA.gety();
  
          return r;
      }
  
      public void onFailed() {
          if (onType == 2) {
              sia = -sia;
          }
      }
  
      public void Save(DataOutputStream out) throws IOException {
          out.writeDouble(bx);
          out.writeDouble(by);
          out.writeDouble(width);
          out.writeDouble(height);
  
          if (pA == null) {
              out.writeInt(-1);
          } else {
              out.writeInt(pA.m_id);
          }
  
          out.writeInt(onType);
  
          CClass c = (CClass) onObj;
          if (c == null) {
              out.writeInt(-1);
          } else {
              out.writeInt(c.m_id);
          }
  
          out.writeDouble(dx);
          out.writeDouble(dy);
          out.writeDouble(csa);
          out.writeDouble(sia);
          out.writeDouble(gap);
          out.writeInt(pindex);
          out.writeInt(step_time);
  
      }
  
      public void Load(DataInputStream in, drawProcess dp) throws IOException {
          bx = in.readDouble();
          by = in.readDouble();
          width = in.readDouble();
          height = in.readDouble();
          int d = in.readInt();
          pA = dp.getPointById(d);
          onType = in.readInt();
  
          d = in.readInt();
  
          if (onType == 1) {
              onObj = dp.getLineByid(d);
          } else if (onType == 2) {
              onObj = dp.getCircleByid(d);
          } else if (onType == 3) {
              onObj = dp.getTraceById(d);
          }
  
          dx = in.readDouble();
          dy = in.readDouble();
          csa = in.readDouble();
          sia = in.readDouble();
          gap = in.readDouble();
          pindex = in.readInt();
          step_time = in.readInt();
  
      }
  
  
  }
  