code: package wprover;
  
  import java.awt.*;
  import java.awt.geom.Rectangle2D;
  import java.awt.font.LineMetrics;
  import java.awt.font.FontRenderContext;
  import java.io.DataOutputStream;
  import java.io.IOException;
  import java.io.DataInputStream;
  import java.io.FileOutputStream;
  
  /**
   * Created by IntelliJ IDEA.
   * User: Administrator
   * Date: 2005-1-26
   * Time: 15:29:29
   * To change this template use File | Settings | File Templates.
   */
  public class CText extends CClass {
  
      final public static int NORMAL_TEXT = 0;
      final public static int NAME_TEXT = 1;
      final public static int CNAME_TEXT = 2;
      final public static int VALUE_TEXT = 3;
  
  
      private int type = NORMAL_TEXT;
      private int x, y;
      private Font font;
      private String str;
      public CTextValue tvalue;
  
      CClass father = null; // if any;
  
  
      double w, h;
      double height;
      private String svalue;
      private double posX, posY;
  
  
      public Font getFont() {
          return font;
      }
  
      public void setTextType(int t) {
          type = t;
          tvalue = CTextValue.parseString(str);
          if (tvalue == null)
              tvalue = new CTextValue();
  
          m_dash = 3;
          m_color = 16;
      }
  
      public boolean fontsizeChange(int n) {
          int size = font.getSize() + n;
          if (size <= 5)
              return false;
  
          font = new Font(font.getName(), font.getStyle(), size);
          return true;
      }
  
      public int getFontSize() {
          return font.getSize();
      }
  
      public void setBold() {
          if (!font.isBold())
              font = new Font(font.getName(), Font.BOLD, font.getSize());
      }
  
      public void setPlain() {
          if (!font.isPlain())
              font = new Font(font.getName(), Font.PLAIN, font.getSize());
      }
  
      public void setFont(Font f) {
          font = f;
      }
  
      public void setFontSize(int n) {
          if (n != font.getSize())
              font = new Font(font.getName(), font.getStyle(), n);
      }
  
      public CText() {
          super(CClass.TEXT);
          str = new String();
  
      }
  
      public void setXY(int x, int y) {
          this.x = x;
          this.y = y;
      }
  
      public CText(CClass f, double dx, double dy, int type) {
          super(CClass.TEXT);
          str = new String();
          this.m_color = drawData.getColorIndex(Color.black);
          this.type = type;
          font = CMisc.nameFont;
          x += dx;
          y += dy;
          father = f;
      }
  
      public void move(double dx, double dy) {
          super.move(dx, dy);
          if (type == NORMAL_TEXT || type == VALUE_TEXT) {
              x += dx;
              y += dy;
          }
  
      }
  
      public boolean equals(Object obj) {
          if (obj == null) return false;
          if (!(obj instanceof CText)) return false;
          CText t = (CText) obj;
          if (type != t.getType()) return false;
          if (str == null || str.length() == 0) return false;
  
          String s1 = obj.toString();
          if (s1 == null || s1.length() == 0) return false;
  
          return str.compareTo(obj.toString()) == 0;
      }
  
  //    public CText(String s) {
  //
  //        super(CClass.TEXT);
  //        x = y = 50;
  //        str = s;
  //        font = new Font("Dialog", Font.PLAIN, 14);
  //    }
  
      public CText(int x, int y, String s) {
          super(CClass.TEXT);
          str = s;
          font = new Font("Dialog", Font.PLAIN, 14);
          this.x = x;
          this.y = y;
      }
  
  
      public String getText() {
          if (type == NORMAL_TEXT)
              return str;
          else if (type == NAME_TEXT)
              return father.m_name;
          else if (type == CNAME_TEXT)
              return str;
          else if (type == VALUE_TEXT)
              return str;
  
          return null;
  
      }
  
      public void setText1(String s) {
          str = s;
      }
  
      public void setText(String s) {
  
          if (type == NORMAL_TEXT)
              str = s;
          else if (type == NAME_TEXT)
              father.m_name = s;
          else if (type == CNAME_TEXT) {
              CAngle ag = (CAngle) father;
              ag.setShowType(2);
              father.m_name = s;
              str = s;
          } else if (type == VALUE_TEXT) {
              str = s;
              CTextValue dt = CTextValue.parseString(str);
              if (dt != null)
                  tvalue = dt;
          }
      }
  
      public String getString() {
          return str;
      }
  
      public Dimension getTextDimension() {
          return new Dimension((int) w, (int) height);
      }
  
      public int getX() {
          return x;
      }
  
      public int getY() {
          return y;
      }
  
      public Point getLocation() {
          return new Point(x, y);
      }
  
      public int getType() {
          return this.type;
      }
  
  
      public int vlength() {
          if (str == null) return 0;
          return str.length();
      }
  
      public void setSvalue(String s) {
          svalue = s;
      }
  
      public boolean nameTextShown = CMisc.nameTextShown;
  
      public boolean isdraw() {
          if (!super.isdraw())
              return false;
          if (father != null && !father.isdraw())
              return false;
  
          if (CMisc.isApplication()) {
              if (type == NAME_TEXT)
                  return CMisc.nameTextShown;
          } else {
              if (type == NAME_TEXT)
                  return nameTextShown;          //APPLET ONLY
          }
          return true;
      }
  
      public int getSX() {
          double lx;
          lx = 0;
          if (type == NORMAL_TEXT) {
              lx = x;
          } else if (type == NAME_TEXT) {
              CPoint p = (CPoint) father;
              lx = p.getx() + x;
          } else if (type == CNAME_TEXT && CMisc.show_angle_text) {
              CAngle ag = (CAngle) father;
              lx = ag.getxForString() + x;
          }
          return (int) lx;
      }
  
      public int getSY() {
          double ly;
          ly = 0;
          if (type == NORMAL_TEXT) {
  //            lx = x;
              ly = y;
          } else if (type == NAME_TEXT) {
              CPoint p = (CPoint) father;
  //            lx = p.getx() + x;
              ly = p.gety() + y;
          } else if (type == CNAME_TEXT && CMisc.show_angle_text) {
              CAngle ag = (CAngle) father;
  //            lx = ag.getxForString() + x;
              ly = ag.getyForString() + y;
          }
          return (int) ly;
      }
  
  
      public String getValueText() {
          double r = tvalue.dvalue; //CTextValue.calvalue(tvalue, null);
          String shead = "";
          switch (m_width) {
              case 0:
                  break;
              case 1:
                  shead = m_name;
                  break;
              case 2:
                  shead = str;
                  break;
              case 3: {
                  if (m_name == null || m_name.length() == 0)
                      shead = str;
                  else
                      shead = m_name + " = " + str;
              }
              break;
              default:
                  shead = str;
          }
  
          return shead + " = " + r;
      }
  
      public void draw(Graphics2D g2) {
          if (!isdraw()) return;
  
          String tstring = null;
  
          double lx, ly;
          lx = ly = 0;
          if (type == NORMAL_TEXT) {
              tstring = str;
              lx = x;
              ly = y;
              posX = lx;
              posY = ly;
          } else if (type == NAME_TEXT) {
              tstring = father.m_name;
              CPoint p = (CPoint) father;
              lx = p.getx() + x;
              ly = p.gety() + y;
              posX = lx;
              posY = ly;
          } else if (type == CNAME_TEXT && CMisc.show_angle_text) {
              CAngle ag = (CAngle) father;
              tstring = str;
              double r[] = CLine.Intersect(ag.lstart, ag.lend);
              if (r != null) {
                  double dx = ag.getxForString() - r[0];
                  double dy = ag.getyForString() - r[1];
                  double rad = Math.sqrt(w * w + height * height) / 2;
                  double len = Math.sqrt(dx * dx + dy * dy);
                  dx += rad * dx / len;
                  dy += rad * dy / len;
                  lx = r[0] + x + dx - w / 2;
                  ly = r[1] + y + dy - height / 2;
                  posX = lx;
                  posY = ly;
                  //lx = ag.getxForString() + x - w / 2;
                  //ly = ag.getyForString() + y - height / 2;
              }
  
          } else if (type == VALUE_TEXT) {
  
              tstring = getValueText();
              lx = x;
              ly = y;
              posX = lx;
              posY = ly;
          }
  
  
          if (tstring == null) return;
          if (tstring.length() == 0) return;
  
  
          String[] sl = tstring.split("\n");
          g2.setFont(font);
          super.setDraw(g2);
          FontRenderContext frc = g2.getFontRenderContext();
          Font f = g2.getFont();
          LineMetrics lm = f.getLineMetrics(sl[0], frc);
          h = lm.getHeight();
          height = h * sl.length;
          w = 0;
  
          for (int i = 0; i < sl.length; i++) {
              Rectangle2D r2 = f.getStringBounds(sl[i], frc);
              if (r2.getWidth() > w)
                  w = r2.getWidth();
              g2.drawString(sl[i], (float) lx, (float) (ly + (i + 1) * h));
          }
  
      }
  
      public void draw(Graphics2D g2, boolean select) {
          if (visible == false) return;
  
          int lx, ly;
          lx = ly = 0;
  
          if (type == NORMAL_TEXT || type == VALUE_TEXT) {
              lx = x;
              ly = y;
          } else if (type == NAME_TEXT) {
              CPoint p = (CPoint) father;
              lx = (int) p.getx() + x;
              ly = (int) p.gety() + y;
          } else if (type == CNAME_TEXT) {
              CAngle ag = (CAngle) father;
              double r[] = CLine.Intersect(ag.lstart, ag.lend);
              if (r != null) {
                  double dx = ag.getxForString() - r[0];
                  double dy = ag.getyForString() - r[1];
                  double rad = Math.sqrt(w * w + height * height) / 2;
                  double len = Math.sqrt(dx * dx + dy * dy);
                  dx += rad * dx / len;
                  dy += rad * dy / len;
                  lx = (int) (r[0] + x + dx - w / 2);
                  ly = (int) (r[1] + y + dy - height / 2);
                  posX = lx;
                  posY = ly;
              }
          }
          Rectangle rc = new Rectangle(lx - 2, ly + 2, (int) w + 2, (int) height + 2);
          g2.setColor(new Color(255, 200, 200));
          g2.fill(rc);
          g2.setColor(Color.black);
          g2.setStroke(new BasicStroke(0.5f));
          g2.draw(rc);
      }
  
      public String TypeString() {
          if (str == null)
              return "";
  
          int n = str.length();
          if (n >= 5)
              n = 4;
          else n--;
          if (n < 0)
              n = 0;
  
          if (str == null) {
          }
  
          if (type == NORMAL_TEXT) {
              String st = Language.getLs(355, "text");
              return st + "(\"" + str.substring(0, n) + "..\")";
          } else if (type == NAME_TEXT || type == CNAME_TEXT) {
              String st = Language.getLs(245, "name");
              return st + "(\"" + str.substring(0, n) + "..\")";
          } else if (type == VALUE_TEXT) {
              if (m_name == null) {
                  String st = Language.getLs(355, "text");
                  return st + "(\"" + str.substring(0, n) + "..\")";
              } else
                  return m_name;
          }
          return null;
      }
  
      public String getDescription() {
          return this.TypeString();
      }
  
      public boolean inRect(double x0, double y0, double x1, double y1) {
          if (x0 > x1) {
              double r = x0;
              x0 = x1;
              x1 = r;
          }
  
          if (y0 > y1) {
              double r = y0;
              y0 = y1;
              y1 = r;
  
          }
          return x0 < x && y0 < y && x1 > x + w && y1 > y + height;
      }
  
      public boolean select(double x1, double y1) {
          if (visible == false) return false;
  
          if (type == NORMAL_TEXT || type == VALUE_TEXT) {
              double dx = x1 - x;
              double dy = y1 - y;
  
              if (dx > 0 && dx < w && dy > 0 && dy < height)
                  return true;
              else
                  return false;
          } else if (type == NAME_TEXT) {
              CPoint p = (CPoint) father;
              double dx = p.getx();
              double dy = p.gety();
              dx = x1 - dx - x;
              dy = y1 - dy - y;
              if (dx > 0 && dx < w && dy > 0 && dy < height)
                  return true;
              else
                  return false;
          } else if (type == CNAME_TEXT) {
              double dx = posX + w / 2 - x1;
              double dy = posY + height / 2 - y1;
              if (dx > -w / 2 && dx < w / 2 && dy > -height / 2 && dy < height / 2)
                  return true;
              else
                  return false;
          }
          return false;
      }
  
      public void drag(double dx, double dy) {
          x += dx;
          y += dy;
          if (type == NAME_TEXT) {
              if (x * x + y * y > CMisc.rlength * CMisc.rlength) {
                  double r = Math.sqrt(x * x + y * y);
                  x = (int) (x * CMisc.rlength / r);
                  y = (int) (y * CMisc.rlength / r);
              }
          } else if (type == CNAME_TEXT) {
              CAngle ag = (CAngle) father;
              double x0 = ag.getxForString();
              double y0 = ag.getyForString();
  
              double x1 = x - x0;
              double y1 = y - y0;
              if (x1 * x1 + y1 * y1 > CMisc.rlength * CMisc.rlength) {
                  double r = Math.sqrt(x1 * x1 + y1 * y1);
                  x1 = (int) (x1 * CMisc.rlength / r);
                  y1 = (int) (y1 * CMisc.rlength / r);
                  x -= dx + x1;
                  y -= dy + y1;
              }
  
          }
      }
  
      public void drag(double x0, double y0, double dx, double dy) {
          if (type == NORMAL_TEXT || type == VALUE_TEXT)
              drag(dx, dy);
          else if (type == NAME_TEXT) {
              CPoint p = (CPoint) father;
              double xx = p.getx();
              double yy = p.gety();
  
              double xp = x0 + dx - xx;
              double yp = y0 + dy - yy;
  
              double len = Math.sqrt(xp * xp + yp * yp);
  
              if (len > CMisc.rlength) {
                  this.x = (int) (xp * CMisc.rlength / len);
                  this.y = (int) (yp * CMisc.rlength / len);
  
              } else {
                  this.x += dx;
                  this.y += dy;
              }
          } else if (type == CNAME_TEXT) {
              CAngle p = (CAngle) father;
              double xx = p.getxForString() - w / 2;
              double yy = p.getyForString() - height / 2;
  
              double xp = x0 + dx - xx;
              double yp = y0 + dy - yy;
  
              double len = Math.sqrt(xp * xp + yp * yp);
  
              if (len > CMisc.rlength) {
                  this.x = (int) (xp * CMisc.rlength / len);
                  this.y = (int) (yp * CMisc.rlength / len);
  
              } else {
                  this.x += dx;
                  this.y += dy;
              }
          }
  
  
      }
  
      public void SavePS(FileOutputStream fp, int stype) throws IOException {
          if (!isdraw()) return;
          if (father != null && !father.isdraw()) return;
  
  
          String tstring = null;
  
          double lx, ly;
          lx = ly = 0;
          if (type == NORMAL_TEXT) {
              tstring = str;
              lx = x;
              ly = y;
          } else if (type == NAME_TEXT) {
              tstring = father.m_name;
              CPoint p = (CPoint) father;
              lx = p.getx() + x;
              ly = p.gety() + y;
          } else if (type == CNAME_TEXT) {
              CAngle ag = (CAngle) father;
              if (str == null || str.length() == 0)
                  tstring = svalue;
              else
                  tstring = str;
              lx = posX;
              ly = posY;
          } else if (type == VALUE_TEXT) {
              tstring = getValueText();
              lx = x;
              ly = y;
          }
  
          if (type == NORMAL_TEXT) {
              String s = "";
              if (font.getStyle() == Font.BOLD)
                  s += "/" + font.getName() + "-Bold";
              else
                  s += "/" + font.getName() + "-Plain";
  
              fp.write((s + " findfont " + font.getSize() + " scalefont setfont").getBytes());
              super.saveSuperColor(fp);
              fp.write("\n".getBytes());
  
              if (!tstring.contains("\n"))
                  fp.write(("" + (int) lx + " " + (int) (-ly - 15) + " moveto (" + tstring + ") " + "show\n").getBytes());
              else {
                  String[] str = tstring.split("\n");
                  int h = (int) height / str.length;
                  for (int i = 0; i < str.length; i++)
                      fp.write(((int) lx + " " + (int) (-ly - h * i - 15) + " moveto (" + str[i] + ") " + "show\n").getBytes());
              }
          } else {
              fp.write(("mf " + (int) lx + " " + (int) (-ly - 15) + " moveto (" + tstring + ") " + "show\n").getBytes());
          }
  
      }
  
      public void Save(DataOutputStream out) throws IOException {
  
          super.Save(out);
  
          out.writeInt(type);
          out.writeInt(x);
          out.writeInt(y);
  
          byte[] s = font.getName().getBytes();
          out.writeInt(s.length);
          out.write(s, 0, s.length);
          out.writeInt(font.getStyle());
          out.writeInt(font.getSize());
  
          if (type == NORMAL_TEXT) {
              s = str.getBytes();
              out.writeInt(s.length);
              out.write(s, 0, s.length);
          } else if (type == NAME_TEXT) {
              out.writeInt(father.m_id);
          } else if (type == CNAME_TEXT) {
              if (str == null)
                  str = "";
  
              s = str.getBytes();
              out.writeInt(s.length);
              out.write(s, 0, s.length);
              out.writeInt(father.m_id);
  
          } else if (type == VALUE_TEXT) {
              s = str.getBytes();
              out.writeInt(s.length);
              out.write(s, 0, s.length);
              if (father == null)
                  out.writeInt(-1);
              else out.writeInt(father.m_id);
          }
  
  
      }
  
      public void Load(DataInputStream in, drawProcess dp) throws IOException {
  
          if (CMisc.version_load_now < 0.010) {
              m_id = in.readInt();
              x = in.readInt();
              y = in.readInt();
              int size = in.readInt();
              byte[] s = new byte[size];
              in.read(s, 0, size);
              str = new String(s);
  
              if (CMisc.version_load_now >= 0.005) {
                  int n = in.readInt();
                  byte[] str = new byte[n];
                  in.read(str, 0, n);
                  String name = new String(str);
                  int type = in.readInt();
                  int sz = in.readInt();
                  int rgb = in.readInt();
  
                  font = new Font(name, type, sz);
  
                  if (CMisc.version_load_now == 0.006) {
                      if (rgb <= 0)
                          m_color = drawData.getColorIndex(Color.black);
                      else
                          m_color = rgb;
                  } else {
                      if (rgb < 0)
                          m_color = drawData.getColorIndex(Color.black);
                      else {
                          if (rgb == 9)
                              m_color = drawData.getColorIndex(Color.black);
                          else
                              m_color = (rgb);
                      }
                  }
              }
  
              {
                  if (m_color == 1)
                      m_color = 3;
                  else if (m_color == 2)
                      m_color = 5;
                  else if (m_color == 3)
                      m_color = 11;
                  else if (m_color == 7)
                      m_color = 8;
              }
          } else {
              super.Load(in, dp);
  
  
              type = in.readInt();
              x = in.readInt();
              y = in.readInt();
  
              int n = in.readInt();
              byte[] sstr = new byte[n];
              in.read(sstr, 0, n);
              String name = new String(sstr);
  
              int font_type = in.readInt();
              int sz = in.readInt();
              font = new Font(name, font_type, sz);
  
              if (type == NORMAL_TEXT) {
                  int size = in.readInt();
                  byte[] s = new byte[size];
                  in.read(s, 0, size);
                  str = new String(s);
              } else if (type == NAME_TEXT) {
                  int id = in.readInt();
                  CPoint p = dp.getPointById(id);
                  p.ptext = this;
                  father = p;
              } else if (type == CNAME_TEXT) {
                  int size = in.readInt();
                  byte[] s = new byte[size];
                  in.read(s, 0, size);
                  str = new String(s);
  
                  int id = in.readInt();
                  CAngle ag = dp.getAngleByid(id);
                  ag.ptext = this;
                  father = ag;
              } else if (type == VALUE_TEXT) {
                  int size = in.readInt();
                  byte[] s = new byte[size];
                  in.read(s, 0, size);
                  str = new String(s);
                  tvalue = CTextValue.parseString(str);
                  if (tvalue == null)
                      tvalue = new CTextValue();
                  if (CMisc.version_load_now >= 0.052) {
                      int id = in.readInt();
                      father = dp.getOjbectById(id);
                  }
              }
  
  
          }
  
      }
  
  }
  