package misc;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

// represents a polynomial function
public class PolyFunction implements Iterable<Entry<Integer, Double>>, Cloneable {
	private Map<Integer, Double> koeffMap = new HashMap<Integer, Double>();
	
	// in case of change from primitive
	// change equals() too
	private int maxGrade = 0;
	
	public Double getKoeff(Integer grade) {
		return koeffMap.get(grade);
	}
	
	public PolyFunction setKoeff(Integer grade, Double koeff) {
		// empty koeffs are useless
		if (koeff.equals(0.0)) {
			return this;
		}
		
		koeffMap.put(grade, koeff);
		if (grade > maxGrade) {
			maxGrade = grade;
		}
		
		return this;
	}
	
	public boolean hasKoeff(Integer grade) {
		return koeffMap.containsKey(grade);
	}
	
	public int getMaxGrade() {
		return maxGrade;
	}
	
	public double calculate(double x) {
		double result = 0;
		
		for (Entry<Integer, Double> entry : this) {
			result += entry.getValue() * Math.pow(x, entry.getKey());
		}
		
		return result;
	}
	
	@Override
	public String toString() {
		StringBuffer result = new StringBuffer();
		
		result.append("f(x) = ");
		
		for (int i = maxGrade; i >= 0; i--) {
			if (i != maxGrade) {
				result.append(" + ");
			}
			if (i == 0) {
				result.append(getKoeff(i));
				continue;
			}
			if (i == 1) {
				result.append(getKoeff(i) + "x");
				continue;
			}
			result.append(getKoeff(i) + "x^" + i);
		}
		
		return result.toString();
	}
	
	@Override
	public boolean equals(Object o) {
		return hashCode() == o.hashCode();
	}
	
	@Override
	public int hashCode() {
        final int prime = 31;
        int result = 1;
        
        for (Entry<Integer, Double> entry : this) {
        	result = prime * result + entry.getKey().hashCode();
        	result = prime * result + entry.getValue().hashCode();
        }
        
        return result;
	}
	
	public Iterator<Entry<Integer, Double>> iterator() {
		return koeffMap.entrySet().iterator();
	}
	
	@Override
	public PolyFunction clone() throws CloneNotSupportedException {
		PolyFunction f = (PolyFunction) super.clone();
		return f;
	}
}

@@ -1254,21 +1254,128 @@
 end(
-%22 + %22);
+(getKoeff(i) %3E= 0.0) ? %22 + %22 : %22 - %22);%0A%09%09%09%7D else %7B%0A%09%09%09%09if (getKoeff(i) %3C 0.0) %7B%0A%09%09%09%09%09result.append(%22-%22);%0A%09%09%09%09%7D
 %0A%09%09%09%7D%0A
+%09%09%09%0A
 %09%09%09i
@@ -1397,32 +1397,41 @@
 %09%09result.append(
+Math.abs(
 getKoeff(i));%0A%09%09
@@ -1426,16 +1426,17 @@
 oeff(i))
+)
 ;%0A%09%09%09%09co
@@ -1475,32 +1475,41 @@
 %09%09result.append(
+Math.abs(
 getKoeff(i) + %22x
@@ -1499,24 +1499,25 @@
 (getKoeff(i)
+)
  + %22x%22);%0A%09%09%09
@@ -1549,16 +1549,25 @@
 .append(
+Math.abs(
 getKoeff
@@ -1569,16 +1569,17 @@
 Koeff(i)
+)
  + %22x%5E%22 

improve display of functions