import java.awt.*;
import java.awt.geom.*;
import java.applet.*;
import javax.swing.JOptionPane;


public class GraficoFunzione extends Applet {
	private Rectangle2D.Double userBox = new Rectangle2D.Double(); // user window - l'utente seglie solo le ascisse
	private int nCampioni;

	
	private Line2D.Double asseX = new Line2D.Double(), 
	                      asseY = new Line2D.Double();

	private Line2D.Double lineetta = new Line2D.Double();
	
	private Color coloreAssi = Color.red;
	private Color coloreGrafico = Color.green;
	private Color coloreBox = Color.blue;
	private BasicStroke mioStroke;

	private static final double delta = 0.05; // normalizzazione user window
	private static final float S = 0.0f; // ampiezza BasicStroke

	private static String nomeFunz;
	
	public void init() {
		userBox.x = -5;
		userBox.width = 10;
		nCampioni = 5000;
		
		//aggiungere istruzioni per permettere all'utente di
		//specificare l'intervallo delle x ed il numero di campioni
		
		setBox(userBox);
		mioStroke = new BasicStroke(S);
	}

	public void paint(Graphics g) {
		Graphics2D g2 = (Graphics2D)g;
		g2.drawString(nomeFunz, 20, 30);
		trasforma(g2, userBox, 0, 0, 1, 1);
		grafica(g2, userBox);
	}
	
	public void trasforma(Graphics2D g2, Rectangle2D.Double box, double xmin, double ymin, double xmax, double ymax) {
		int w = getWidth(), h = getHeight();
		double x1 = box.x,
		       y1 = box.y,
		       x2 = box.x + box.width,
		       y2 = box.y + box.height;
		g2.translate(xmin * (w - 1), ymin * (h - 1));
		g2.scale(xmax - xmin, ymax - ymin);
		g2.scale((w - 1) / (x2 - x1), (h - 1) / (y1 - y2));
		g2.translate(-x1, -y2);

		g2.setStroke(mioStroke);
	}
	
	public void grafica(Graphics2D g2, Rectangle2D.Double box) {		
		double x1 = box.x,
		       y1 = box.y,
		       x2 = box.x + box.width,
		       y2 = box.y + box.height;
		g2.setColor(coloreAssi);
		/* asse X, se visibile */
		if(y1 * y2 <= 0) {
			asseX.setLine(x1, 0, x2, 0);
			g2.draw(asseX);
		}
		/* asse Y, se visibile */
		if(x1 * x2 <= 0) {
			asseY.setLine(0, y1, 0, y2);
			g2.draw(asseY);
		}
		
		g2.setColor(coloreBox);	
		g2.draw(box);
		
		g2.setColor(coloreGrafico);	
		
		//codice per graficare la funzione da realizzare
	}
	
	private static double f(double x) {
		nomeFunz = "Math.sin(1/x)";
		return Math.sin(1/x);
	}
	
	private void setBox(Rectangle2D.Double box) {
		double y2 = f(box.x);
		double y1 = y2;
		double passo = box.width / (nCampioni - 1); // intervalli = ncampioni - 1
		double x2 = box.x + box.width;
		for(double x = box.x + passo; x <= x2; x += passo) {
			double y = f(x);
			if(y > y2)
				y2 = y;
			else 
				if(y < y1)
					y1 = y;
		}
		if(y1 == y2) {
			y1 -= delta;
			y2 += delta;
		}
		box.y = y1;
		box.height = y2 - y1;
	}
}