package figure;

import java.awt.*;
import java.awt.geom.*;

public class GraphicalFunction extends Plotable {
    public static final int Y_OF_X = 0;
    public static final int X_OF_Y = 1;
    int orientation = Y_OF_X;
    Function function;
    Stroke stroke;
    int steps = 50;
    double[] params;
    double x0, x1;
    boolean domainSet = false;

    public GraphicalFunction(Function f, double[] p) {
        function = f;  params = p;
        stroke = new BasicStroke(1f);
    }

    public void setOrientation(int o) {
	orientation = o;
    }

    public void setSteps(int s) { steps = s; }

    public void setStroke(Stroke s) { stroke = s; }

    public void setDomain(double xp0, double xp1) {
	domainSet = true;
	x0 = xp0;  x1 = xp1;
    }

    public void plot(Graphics2D g, BoundingBox bbox,
		     AffineTransform transform) {
	if (!domainSet) {
	    if (orientation == Y_OF_X) {
		x0 = bbox.llx;  x1 = bbox.urx;
	    } else {
		x0 = bbox.lly;  x1 = bbox.ury;
	    }
	}
        double stepsize = (x1 - x0)/steps;
        GeneralPath path = new GeneralPath();
	Point2D.Float point;
	if (orientation == Y_OF_X) 
	    point = 
	    new Point2D.Float((float)x0, (float) function.valueAt(x0, params));
	else point = 
	    new Point2D.Float((float) function.valueAt(x0, params), (float)x0);
	transform.transform(point, point);
        path.moveTo(point.x, point.y);
        for (int i = 1; i <= steps; i++) {
            double x = x0 + i*stepsize;
	    if (orientation == Y_OF_X) 
		point = new Point2D.Float((float) x,
					  (float) function.valueAt(x, params));
	    else 
		point = new Point2D.Float((float) function.valueAt(x, params),
					  (float) x);
					  
	    transform.transform(point, point);
            path.lineTo(point.x, point.y);
	}
        g.setPaint(color);
        Stroke savedStroke = g.getStroke();
	g.setStroke(stroke);
	g.draw(path);
        g.setStroke(savedStroke);
    }
}
        
        
        
