code: package wprover;
  
  import maths.TMono;
  import maths.param;
  
  import java.awt.*;
  
  /**
   * Created by IntelliJ IDEA.
   * User: Ye
   * Date: 2005-7-28
   * Time: 13:31:13
   * To change this template use File | Settings | File Templates.
   */
  public class CTextValue {
  
      final static String SPI = "π";
      final static String SE = "e";
      final public static String[] sfunction = {"sin", "cos", "tan", "arcsin", "arccos", "arctan",
              "abs", "sqrt", "ln", "log", "sgn", "round", "trunc", "area"};
  
      final static int PLUS = 1;
      final static int MINUS = 2;
      final static int MUL = 3;
      final static int DIV = 4;
      final static int SQRT = 5;
      final static int SQURAR = 6;
      final static int CUBE = 7;
      final static int SIN = 8;
      final static int COS = 9;
      final static int TAN = 10;
      final static int CTAN = 11;
  
      final static int EXP = 12;
      final static int NODE = 13;
      final static int VALUE = 14;
      final static int FUNC = 15;
      final static int PARAM = 16;
      final static int AREA = 17;
  
  
      final static int PI = 20;
      final static int E = 21;
  
  
      int TYPE;
  
      String sname = "";
      int value = 1;
      int index = -1;
      double dvalue;
  
      CTextValue left;
      CTextValue right;
  
  
      public CTextValue() {
      }
  
      private CTextValue(int t) {
          TYPE = t;
      }
  
  
      public static CTextValue parseString(String str) {
          TMono index = new TMono(0, 0, 0);
  
          return parseEntityA(str.toCharArray(), index);
      }
  
      public static CTextValue parse(byte[] src, TMono index) {
          return null;
      }
  
      public static int getFunction(String s) {
          for (int i = 0; i < sfunction.length; i++) {
              if (s.equalsIgnoreCase(sfunction[i]))
                  return i;
          }
          return -1;
      }
  
      public static String parseFunction(char[] src, TMono index) {
          parseSpace(src, index);
          int i = index.x;
          String s = new String();
  
          if (src[i] == 'x' || src[i] == 'X') return s;
  
          while ((src[i] >= '0' && src[i] <= '9') || (src[i] >= 'a' && src[i] <= 'z') || (src[i] >= 'A' && src[i] <= 'Z')) {
              char[] bb = new char[1];
              bb[0] = src[i];
              s += new String(bb);
              i++;
              if (i >= src.length) break;
          }
          index.x = i;
          return s;
      }
  
  
      private static CTextValue parseEntityA(char[] src, TMono index) {
  
          CTextValue ct1 = parseEntityB(src, index);
          parseSpace(src, index);
  
          int i = index.x;
          if (i >= src.length)
              return ct1;
  
          char b = src[i];
          while (b == '+' || b == '-') {
  
              index.x++;
  
              CTextValue ct2 = parseEntityB(src, index);
              if (ct2 == null)
                  break;
  
              CTextValue ct = new CTextValue();
              if (b == '+')
                  ct.TYPE = PLUS;
              else if (b == '-')
                  ct.TYPE = MINUS;
              ct.left = ct1;
              ct.right = ct2;
              ct1 = ct;
              parseSpace(src, index);
              i = index.x;
              if (i >= src.length)
                  break;
              b = src[i];
          }
          return ct1;
      }
  
      private static CTextValue parseEntityB(char[] src, TMono index) {
  
          parseSpace(src, index);
          CTextValue ct1 = parseEntityC(src, index);
          parseSpace(src, index);
          if (index.x >= src.length)
              return ct1;
  
          char b = src[index.x];
          while (b == '*' || b == '/') {
              index.x++;
              CTextValue ct2 = parseEntityC(src, index);
              if (ct2 == null)
                  break;
  
              CTextValue ct = new CTextValue();
              if (b == '*')
                  ct.TYPE = MUL;
              else if (b == '/')
                  ct.TYPE = DIV;
  
              ct.left = ct1;
              ct.right = ct2;
              ct1 = ct;
              parseSpace(src, index);
              int i = index.x;
              if (i >= src.length)
                  break;
              b = src[i];
          }
          return ct1;
      }
  
      private static CTextValue parseEntityC(char[] src, TMono index) { // ^
          parseSpace(src, index);
          CTextValue t1 = parseEntityD(src, index);
          parseSpace(src, index);
          int i = index.x;
          if (i >= src.length)
              return t1;
  
          CTextValue vl = null;
  
          char b = src[i];
          while (b == '^') {
              index.x++;
              CTextValue t2 = parseEntityD(src, index);
  
              if (vl == null) {
                  vl = new CTextValue(EXP);
                  vl.left = t1;
                  vl.right = t2;
              } else {
                  CTextValue v = new CTextValue(EXP);
                  CTextValue t = vl;
                  while (t.right.right != null)
                      t = t.right;
                  v.left = t.right;
                  v.right = t2;
                  t.right = v;
              }
  
              parseSpace(src, index);
              i = index.x;
              if (i >= src.length)
                  break;
              b = src[i];
          }
          if (vl != null)
              return vl;
          else return t1;
      }
  
      private static CTextValue parseEntityD(char[] src, TMono index) { // (), x1,value.
  
  
          parseSpace(src, index);
          int i = index.x;
          if (i >= src.length)
              return null;
  
          if (src[i] == '(') {
              index.x = i + 1;
              CTextValue ct = parseEntityA(src, index);
              parseSpace(src, index);
              index.x++;
              return ct;
          } else if (src[i] == 'x' || src[i] == 'X') {
              index.x++;
              CTextValue t1 = new CTextValue(NODE);
              int v = (int) parseInt(src, index);
              t1.TYPE = NODE;
              t1.index = v;
              return t1;
          } else if (src[i] >= '0' && src[i] <= '9') {
              double v = parseInt(src, index);
              CTextValue t1 = new CTextValue(NODE);
              t1.dvalue = v;
              t1.TYPE = VALUE;
              return t1;
          } else if (src[i] == 960){
              CTextValue t1 = new CTextValue(PI);
              index.x++;
              return t1;
          } else if (src[i] == 'e') {
              CTextValue t1 = new CTextValue(E);
              index.x++;
              return t1;
          } else {
              String s = parseFunction(src, index);
              if (s.length() != 0) {
                  int fn = getFunction(s);
                  parseSpace(src, index);
  
                  int d = index.x;
  //                index.x++;
  //
  //                int d = index.x;
                  if (d < src.length && src[d] == '(') { // function.
                      CTextValue t1 = new CTextValue();
                      t1.TYPE = FUNC;
                      t1.value = fn;
                      index.x++;      //(
                      parseSpace(src, index);
                      t1.left = parseEntityA(src, index);
                      parseSpace(src, index);
                      index.x++;      //)
                      return t1;
                  } else // parameter.
                  {
                      CTextValue t1 = new CTextValue();
                      t1.TYPE = PARAM;
                      t1.sname = s;
                      return t1;
                  }
              }
          }
  
          CMisc.print("Error input polynomial type in CTextValue");
          return null;
  
      }
  
      private static char parseByte(char[] src, TMono index) {
          parseSpace(src, index);
          int i = index.x;
          if (i >= src.length) return 0;
  
          char b = src[i];
          if (b != '+' && b != '-') {
              index.x = i;
              return 0;
          }
          index.x++;
  
          parseSpace(src, index);
          return b;
      }
  
      private static char parseByteB(char[] src, TMono index) {
          parseSpace(src, index);
          int i = index.x;
          if (i >= src.length) return 0;
  
          if (src[i] == '*' || src[i] == '/') {
              index.x++;
              parseSpace(src, index);
              return src[i];
          }
          return 0;
      }
  
      private static double parseInt(char[] src, TMono index) {
  
          parseSpace(src, index);
  
          int i = index.x;
          if (i >= src.length)
              return 0.0;
  
          char b = src[i];
          double v = 0;
  
          double d = 0.1;
  
          int step = 0; // 0. Befor  1.after.
          while (b >= '0' && b <= '9' || b == '.') {
              if (b == '.')
                  step = 1;
              else if (step == 0) {
                  v *= 10;
                  v += (b - '0');
              } else {
                  v += (b - '0') * d;
                  d *= 0.1;
              }
  
              i++;
              index.x++;
              if (i >= src.length) break;
  
              b = src[i];
          }
  
          parseSpace(src, index);
          return v;
      }
  
      private static void parseSpace(char[] src, TMono index) {
  
          int i = index.x;
  
          if (i >= src.length) return;
  
          while (i < src.length && src[i] == ' ')
              i++;
  
          index.x = i;
  
      }
  
      private static String getAString(char[] src, TMono index) {
          parseSpace(src, index);
          int i = index.x;
          String s = new String();
  
          if (src == null || i >= src.length) return s;
  
          while ((src[i] >= 'a' && src[i] <= 'z') || (src[i] >= 'A' && src[i] <= 'Z')) {
              s += src[i];
              i++;
              if (i >= src.length) break;
          }
  
          if (s.length() != 0) {
              index.x = i;
              return s;
          }
  
  
          if (src[i] == '(' || src[i] == ')' || src[i] == '*' || src[i] == '/' || src[i] == '^') {
              s += src[i];
              index.x = i + 1;
              return s;
          }
  
          while (src[i] >= '0' && src[i] <= '9') {
              s += src[i];
              i++;
              if (i >= src.length) break;
  
          }
          if (s.length() != 0) {
              index.x = i;
              return s;
          }
          parseSpace(src, index);
  
          return s;
      }
  
      public static double roud3(double r) {
          return Math.round(r * 1000 + 0.1) / 1000.0;
      }
  
      public void calculate(drawProcess dp) {
          double r = calvalue(this, dp);
          this.dvalue = roud3(r);
      }
  
      public static double calvalue(CTextValue ct, drawProcess dp) {
          if (ct == null) return 0.0;
          return dp.calculate(ct);
      }
  
  //    "sin", "cos", "tan", "arcsin", "arccos", "arctan",
  
      //            "abs", "sqrt", "ln", "log", "sgn", "round", "trunc"}
  
      public static double cal_func(int n, double v) {
          switch (n) {
              case 0:
                  return Math.sin(v);
              case 1:
                  return Math.cos(v);
              case 2:
                  return Math.tan(v);
              case 3:
                  return Math.asin(v);
              case 4:
                  return Math.acos(v);
              case 5:
                  return Math.atan(v);
              case 6:
                  return Math.abs(v);
              case 7:
                  return Math.sqrt(v);
              case 8:
                  return Math.log10(v);
              case 9:
                  return Math.log(v);
              case 10:
                  return Math.signum(v);
              case 11:
                  return Math.round(v);
              case 12:
                  return v;//////???
          }
          return v;
      }
  }
  