//
//  polynomial.java
//  
//
//  Created by Chris Thiel on November 4, 2005.
//  Copyright (c) 2005 Chris Thiel. 
//  Free for Educational Use (with permission). All rights reserved.
//  A simple Java applet (620 x 400) 
//  that uses one slider to control the six coeefs of a polynomial function
//  with click-and drag zoom window features

import java.awt.*;
import java.awt.event.*;
import java.awt.Event;
import java.applet.*;
import java.lang.*;

public class polynomial extends Applet   {

    boolean Selecting;	
	int beginX, beginY, endX, endY;
	double xfactor, yfactor;
	double xmin, ymin, xmax, ymax;
	double A[] = new double[7]; //polynomial coeffs
	Rectangle Slider = new Rectangle (10,370,610,30);
	Rectangle StdViewBtn= new Rectangle (10, 311, 125, 15); 
	Rectangle FitViewBtn= new Rectangle (485, 311, 125, 15); 
	Rectangle UpViewBtn= new Rectangle (260, 311, 50, 15); 
	Rectangle DnViewBtn= new Rectangle (320, 311, 50, 15); 
	Rectangle LtViewBtn= new Rectangle (200, 311, 50, 15); 
	Rectangle RtViewBtn= new Rectangle (380, 311, 50, 15); 
	Rectangle Screen= new Rectangle(10,10,600,300);
	Rectangle CoeffBtn[] = new Rectangle[7]; // Location of Coeef Buttons
	int SelectedCoeff=0; // The selected coeff
    private Font font = new Font("sansserif", Font.ITALIC + Font.BOLD, 12);
	int knob;
	double mouseX,mouseY;
   
   
    public void StdView(){
		xfactor=10;
		yfactor=10;
		xmin=-30;
		xmax=30;
		ymin=-15;
		ymax=15;
	}
	public void UpView(){
		ymax+=1.0;
		ymin+=1.0;
	}
	public void DnView(){
		ymax-=1.0;
		ymin-=1.0;
	}
	public void LtView(){
		xmin-=1.0;
		xmax-=1.0;
	}
	public void RtView(){
		xmin+=1.0;
		xmax+=1.0;
	}
	public void FitView(){
		xmax=.5+Math.abs(A[0]);
		xmin=-1.0*xmax;
		ymin=-5;
		ymax=5;
		for (double i=xmin;i<xmax;i+=.2) {
			if (f(i)<ymin) {ymin=f(i)*1.25;}
			if (f(i)>ymax) {ymax=f(i)*1.25;}
		}
		xfactor=600/(xmax-xmin);
		yfactor=300/(ymax-ymin);
	}
    public void init() {
       Selecting=false;
		setLayout (null);
        this.setBackground(new Color(0xFFEEAA));
		StdView();
		//initialize the coeffs
        for(int i=0;i<7;i++){ 
			A[i]=0.0;
			CoeffBtn[6-i]=new Rectangle(50+80*i, 330, 60, 40);
			
		}
		knob=210;	
		A[2]=1.0; A[1]=4.0; A[0]=-5.0;
       
    }
    private double f(double x){
		double p=0;
		for (int i=0;i<7;i++){p+=Math.pow(x,i)*A[i];}
        return p;
    }
    private int screenX (double x){
		//(300= half the screen width 10=offset)
        return (int)(xfactor*(x-xmin)+10); //converts xmin<x<xmax to screen coords
    }
    private int screenY (double y){
        return (int)(yfactor*(ymax-y)+10); //converts -15<y<15 to screen coords
    }
     private double GrafX (int x){
        return (int)(100*((x-10)/(xfactor)+xmin))/100.0; //converts screen coords to coords of the graph
    }
    private double GrafY (int y){
        return (int)(100*((y-10)/(-1*yfactor)+ymax))/100.0; //converts screen coords to graph
    }
	private int ho(int x){ // horizontal offset for numbering the x axis
		int d=-1;
		if (x>9) {d=-4;}
		if (x<-9) {d=-7;}
		return d;
	}
    public void paint (Graphics g) {
		//Draw Coeffs
				g.setColor( Color.black);
		//g.setFont (new Font("sansserif", Font.BOLD, 10));
		//g.drawString("xmin="+xmin+" xmax="+xmax+" xfac="+xfactor+" ymin="+ymin+" ymax="+ymax+" yfac="+yfactor,10,10);
		g.setFont (new Font("sansserif", Font.BOLD, 16));
		for (int i=0;i<7;i++){
			if (i==SelectedCoeff){
				g.setColor(Color.yellow);
				g.fillRect(CoeffBtn[i].x,CoeffBtn[i].y,CoeffBtn[i].width,CoeffBtn[i].height);
				g.setColor( Color.red);
			}else{g.setColor( Color.black);}
			g.drawRect(CoeffBtn[i].x, CoeffBtn[i].y, CoeffBtn[i].width, CoeffBtn[i].height);
			g.drawString(A[i]+"",60+80*(6-i),355);
		}
		g.setColor( Color.black);
		g.setFont (new Font("serif", Font.ITALIC+Font.BOLD, 14));
		g. drawString("f(x)=",10,355);
		for(int i=0;i<6;i++){ 
			
			g.drawString("x    +",95+80*i, 355);
					} 
		g.setColor( Color.black);
		g.setFont (new Font("serif", Font.BOLD, 10));
		for(int i=0;i<5;i++){ g.drawString((6-i)+" ",103+80*i, 349);} 
		
		//Draw Controls
		g.setColor(Color.black);
		g.drawLine(10,385,610,385);
		for(int i=10;i<620;i+=50){g.drawLine(i,387,i,383);}
		g.drawLine(310,390,310,380);
		g.setColor(Color.red);
		g.fillOval(knob-4,382,7,8);
		
        //Draw Grid
		
        g.setColor(new Color(0x108000));
        g.fillRect(Screen.x, Screen.y, Screen.width, Screen.height);
        g.setColor(new Color(0x08602F)); //lines
        for(int i = (int)(xmin); i< xmax; i++){
         g.drawLine( screenX(i),10,screenX(i) ,310); // verticals
        }
        for(int i = (int)(ymin); i< ymax; i++) {
         g.drawLine( 10, screenY(i), 610, screenY(i) ); //horizontals
        }
        g.setColor(Color.black); 
        g.drawLine( screenX(xmin), screenY(0), screenX(xmax), screenY(0) ); // x-axis
        g.drawLine( screenX(0),screenY(ymin),screenX(0), screenY(ymax));  // y=axis
        g.setFont (new Font("serif", 0, 9));
	// horizontal numbers
		int step=(int)((xmax-xmin)/40)+1;
        for(int i = (int)(xmin); i< xmax; i+=step) g.drawString(i+" ", screenX(i)+ho(i), screenY(0)+9); 
	//vertical numbers
		step=(int)((ymax-ymin)/20)+1;
		for(int i = 1; i< (int)(ymax); i+=step) g.drawString(i+" ", screenX(0)+2, screenY(i)+4);
		for(int i = (int)(ymin); i< 0; i+=step) g.drawString(i+" ", screenX(0)+2, screenY(i)+4);
       
        
         
        //Draw Curve
       
		g.setColor(Color.orange);
		g.setFont (new Font("sansserif", Font.BOLD, 16));
		g.drawString("x="+mouseX, 20,40);
		g.drawString("y="+mouseY, 20,60);

		g.setColor(Color.cyan);
		double xdiff=.01*(xmax-xmin);
		for (double i=xmin;i<xmax;i=i+xdiff){
			g.drawLine(screenX(i),screenY(f(i)),screenX(i+xdiff), screenY(f(i+xdiff)));
		}
		//
		// Draw Selection
		if(Selecting){
		g.setColor(Color.yellow);
		g.drawRect(beginX,beginY,endX-beginX,endY-beginY);
		}
		g.setColor(Color.red);
		g.fillRect(StdViewBtn.x,StdViewBtn.y,StdViewBtn.width,StdViewBtn.height);
		g.fillRect(FitViewBtn.x,FitViewBtn.y,FitViewBtn.width,FitViewBtn.height);
		g.fillRect(UpViewBtn.x,UpViewBtn.y,UpViewBtn.width,UpViewBtn.height);
		g.fillRect(DnViewBtn.x,UpViewBtn.y,UpViewBtn.width,UpViewBtn.height);
		g.fillRect(LtViewBtn.x,UpViewBtn.y,UpViewBtn.width,UpViewBtn.height);
		g.fillRect(RtViewBtn.x,UpViewBtn.y,UpViewBtn.width,UpViewBtn.height);

		g.setColor(Color.white);
		g.drawString("Standard Veiw", StdViewBtn.x+8, StdViewBtn.y+13);
		g.drawString("Fit Curve", FitViewBtn.x+29,FitViewBtn.y+13);
		g.drawString(" Up  ", UpViewBtn.x+9,UpViewBtn.y+13);
		g.drawString("Down ", DnViewBtn.x+3,DnViewBtn.y+13);
		g.drawString("Left ", LtViewBtn.x+10,LtViewBtn.y+13);
		g.drawString("Right", RtViewBtn.x+2,RtViewBtn.y+13);
		
		//end of polynomial drawing
		
		}
	
	/*
     * Mouse methods
     */
    public boolean mouseDown(java.awt.Event evt, int x0, int y0) {
	 for(int i=0;i<7;i++){
		if ( CoeffBtn[i].inside(x0,y0) ) {
			SelectedCoeff=i;
			knob=310+(int)(A[i]*10.0);
			}
		}
	if (StdViewBtn.inside(x0,y0) ) { StdView(); }
	if (FitViewBtn.inside(x0,y0) ) { FitView(); }	
	if (UpViewBtn.inside(x0,y0) ) { UpView(); }	
	if (DnViewBtn.inside(x0,y0) ) { DnView(); }	
	if (LtViewBtn.inside(x0,y0) ) { LtView(); }	
	if (RtViewBtn.inside(x0,y0) ) { RtView(); }	
		repaint();
	 return true;
	 }
	public boolean mouseUp(java.awt.Event evt, int x, int y) {
	if((Screen.inside(x,y)) && (Selecting)){
		endY=y;
		endX=x;
		xmax=GrafX(endX);
		xmin=GrafX(beginX);
		ymax=GrafY(beginY);
		ymin=GrafY(endY);
		xfactor=600/(xmax-xmin);
		yfactor=300/(ymax-ymin);
		repaint();
		Selecting=false;
		
		repaint();
	}
	 return true;
	 }
	 
	public boolean mouseMove(java.awt.Event evt, int x, int y) {
	if(Screen.inside(x,y)){
		mouseX=GrafX(x);
		mouseY=GrafY(y);
		repaint();
	}
	return false;
   }
   
	public boolean mouseDrag(java.awt.Event evt, int x0, int y0) {
	int x=x0;
	int y=y0;
	if (Slider.inside(x,y)){
		knob=x;
		A[SelectedCoeff]=.5*(int)((knob-310)/5.0);
		repaint();
    }
	if ((Screen.inside(x,y))&&(!Selecting)) {
	Selecting=true;
	beginX = x;
	beginY = y;
	repaint();
	}
	if((Screen.inside(x,y)) && (Selecting)){
		endY=y;
		endX=x;
		repaint();
	}

   	return true;
	}
	}
