/* This code defines polynomials in one variable with positive integer
exponents and real coefficients.  There is a class Term which represents a
single term in the polynomial but also contains the link to the next term.
Polynomials are always represented with a single term for each possible
exponent, with the terms in decreasing order of the exponent and with the
terms with zero coefficients removed from the representation.  The class
Poly contains the a private Term inside it.  Outside users of the package
are meant to work with Poly rather than with Term. */

public class Term{ 
  /* instance fields */
  private int expo;
  private double coef;
  private Term next;

  /* Constructors */
  public Term(){expo = 0; coef = 0.0; next = null;};
  public Term(int e, double c){
    if (c == 0.0) {expo = 0; coef = 0.0; next = null;}
    else if (e < 0) {expo = 0; coef = c; next = null;}
    else {expo = e; coef = c; next = null;}};

  /* Instance methods */
  public int degree(){ return expo;};
  public double lead(){ return coef;};
  public void show() {System.out.println("Coef = " + coef + "Exp = " + expo);};
  public void SetNext(Term t){ this.next = t;};
  public Term GetNext(){ return this.next;};
  public void SetCoef(double d){this.coef = d;};

  public double eval(double x){
    double result = 1.0;
    int n = expo;
    while (n != 0) {result *= x; n--;}
    return (coef * result);};

  public void insert(int e, double c){
      
    /* This assumes that the term being inserted is not the leading term. */
    Term trailer = this;
    while ((trailer.next != null) && (e < trailer.next.expo)) trailer = trailer.next;
    if (trailer.next == null) trailer.next = new Term(e,c);  //New term at the rear
    else if (trailer.next.expo == e) { //New term has to be added to the term pointed at
      double newcoef = c + trailer.next.coef;
      if (newcoef == 0.0) trailer.next = trailer.next.next;  //The term has to be removed
      else trailer.next.coef = newcoef;} 
    else { //The new term comes after trailer but before trailer.next
      Term temp = new Term(e,c);
      temp.next = trailer.next;
      trailer.next = temp;}
  };

  public String toString() {
      String s = "[ ";
      Term t = this; //Create temporary reference to this so we don't change it
      //For first term, put a negative sign (no space) if coef is -1, otherwise
      //just add the coefficient, unless it's 1:
      if (t.coef == -1) s+="-"; else if (t.coef != 1) s+=t.coef;
      while (t!=null) {
          if (t.expo > 0) { //Print variable if expo > 0
              s+="x";
              if (t.expo > 1) s+="^" + t.expo;} //Print expo if it's > 1
          //If expo is 0 and coef is 1 or -1, add a 1 (sign added previously):
          else if (Math.abs(t.coef) == 1) s+="1.0";
          t = t.next; //Go to the next term
          if (t!=null) { //If next term exists, do the following:
              if (t.coef < 0) s+=" - "; else s+=" + "; //Add proper sign
              if (Math.abs(t.coef) != 1) s+=Math.abs(t.coef);} //Add coef if not 1/-1
      }//back to beginning of loop (assuming t is not null)
      return s + " ]"; //Return result
  }
 
}
