import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.lang.*;  
import java.awt.image.*;
import java.net.*;
import java.text.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
//import java.util.Map;
//import java.util.Hashtable;
//import java.util.jar.Attributes;

// Chapter 3 Module 3
public class Mod4Info extends Panel {
    private static final Color bgcolor = new Color(236,236,236);
    //private static final Color bgcolor = Color.white;

    private Label titlelabel;
    Mod4State state;
    String s = null;
    int endingX;
    DecimalFormat dec = new DecimalFormat("#.#");
    //DecimalFormat decTheta = new DecimalFormat("###.###");

    static double piOver180 = Math.PI/180.0;

    public NewOutputCanvas2 outInfo;

    public Mod4Info(Mod4State state) {
        super();
        setBackground(bgcolor);
        setLayout(null);
        this.state = state;
	titlelabel = new Label("Output",Label.CENTER);
	//titlelabel.setFont(TheFonts.bold14);
	titlelabel.setFont(TheFonts.bold16);
	add(titlelabel);
	titlelabel.setBounds(15,5,70,18);
        titlelabel.setBackground(bgcolor);
        
        outInfo = new NewOutputCanvas2(state);
        add(outInfo);
        // total width = 285, height = 257

        ////infoPanel.setBounds(517,469,450,128);

        //outInfo.setBounds(0,24,285,233);
        //outInfo.setBounds(4,24,285,100);
        outInfo.setBounds(4,24,400,100);
    }
    
    public void displayCurl() {

        // 1. also need to check for FIRST param w/ coeff1 = -1 ...
        //   so just set s = "-sin..."  or "-x ..." or "-e ..."
        // 2. FIX slider so only goes up or down by .1 instead of .001!!!!


        boolean anyFirstTerm = true;
        state.sOutput = "  ";
        //s = STR.ZHAT+"z"+STR.ENDZHAT+STR.BOLD+"("+STR.ENDBOLD;

        switch(state.currentFunction) {
        case Mod4State.polynomial:
            if (state.coeff1 == 0) {
                anyFirstTerm = false;
                s = "";   // No 1st term
            } else if (Math.abs(state.coeff1) == 1.0) {
                if (state.coeff1 == -1.0) s = STR.BOLD+"-"+STR.ENDBOLD;
                if (state.exp1 == 0) {
                    s = STR.BOLD+"1"+STR.ENDBOLD; //x**0 = 1
                } else {
                    s = STR.BOLD+"x"+STR.ENDBOLD;
                    if (state.exp1 != 1.0)
                        s += STR.SUP+dec.format(state.exp1)+STR.ENDSUP;
                }
            } else {
                if (state.exp1 == 0) {
                    // x**0 = 1
                    s = STR.BOLD+dec.format(state.coeff1)+STR.ENDBOLD;
                } else {
                    s = STR.BOLD+dec.format(state.coeff1)+"x"+STR.ENDBOLD;
                    if (state.exp1 != 1.0)
                        s += STR.SUP+dec.format(state.exp1)+STR.ENDSUP+" ";
                }
            }

            if (state.coeff2 == 0) {
                // NO 2nd term
            } else if (Math.abs(state.coeff2) == 1.0) {
                if (state.coeff2 == -1) s += STR.BOLD+" -"+STR.ENDBOLD;
                else s += STR.BOLD+" +"+STR.ENDBOLD;
                if (anyFirstTerm) s += " ";
                if (state.exp2 == 0) {
                    //y**0 = 1
                    s += STR.BOLD+"1"+STR.ENDBOLD;
                } else {
                    s += STR.BOLD+"y"+STR.ENDBOLD;
                    if (state.exp2 != 1.0)
                        s += STR.SUP+dec.format(state.exp2)+STR.ENDSUP;
                }
            } else {
                if (state.exp2 == 0) {
                    if (state.coeff2 < 0)  s += STR.BOLD+" -"+STR.ENDBOLD;
                    else  s += STR.BOLD+" +"+STR.ENDBOLD;
                    if (anyFirstTerm) s += " ";
                    s += STR.BOLD+dec.format(Math.abs(state.coeff2))+
                        STR.ENDBOLD;  // y**0 = 1
                } else {
                    if (state.coeff2 < 0)  s += STR.BOLD+" -"+STR.ENDBOLD;
                    else  s += STR.BOLD+" +"+STR.ENDBOLD;
                    if (anyFirstTerm) s += " ";
                    s += STR.BOLD+dec.format(Math.abs(state.coeff2))+"y"+
                        STR.ENDBOLD;
                    if (state.exp2 != 1.0)
                        s += STR.SUP+dec.format(state.exp2)+STR.ENDSUP;
                }
            }
            break;
        case Mod4State.exponential:
            if (state.coeff1 == 0) {
                anyFirstTerm = false;
                s = "";
            } else if (Math.abs(state.coeff1) == 1.0) {
                if (state.coeff1 == -1.0) s = STR.BOLD+"-"+STR.ENDBOLD;
                if (state.exp1 == 0) {
                    s = STR.BOLD+"1"+STR.ENDBOLD; //e**0 = 1
                } else {
                    s = STR.BOLD+"e"+STR.ENDBOLD;
                    if (state.exp1 == 1.0)
                        s += STR.SUP+"x"+STR.ENDSUP;
                    else
                        s += STR.SUP+dec.format(state.exp1)+"x"+STR.ENDSUP;
                }
            } else {
                if (state.exp1 == 0) {
                    s = STR.BOLD+dec.format(state.coeff1)+STR.ENDBOLD;//e**0=1
                } else {
                    s = STR.BOLD+dec.format(state.coeff1)+"e"+STR.ENDBOLD;
                    if (state.exp1 == 1.0)
                        s += STR.SUP+"x"+STR.ENDSUP;
                    else
                        s += STR.SUP+dec.format(state.exp1)+"x"+STR.ENDSUP;
                }
            }

            if (state.coeff2 == 0) {
                // NO 2nd term !!
            } else if (Math.abs(state.coeff2) == 1.0) {
                if (state.coeff2 == -1) s += STR.BOLD+" -"+STR.ENDBOLD;
                else s += STR.BOLD+" +"+STR.ENDBOLD;
                if (anyFirstTerm) s += " ";
                if (state.exp2 == 0) {
                    s += STR.BOLD+"1"+STR.ENDBOLD; //e**0 = 1
                } else {
                    s += STR.BOLD+"e"+STR.ENDBOLD;
                    if (state.exp2 == 1.0)
                        s += STR.SUP+"y"+STR.ENDSUP;
                    else
                        s += STR.SUP+dec.format(state.exp2)+"y"+STR.ENDSUP;
                }
            } else {
                if (state.exp2 == 0) {
                    if (state.coeff2 < 0)  s += STR.BOLD+" -"+STR.ENDBOLD;
                    else  s += STR.BOLD+" +"+STR.ENDBOLD;
                    if (anyFirstTerm) s += " ";
                    s += STR.BOLD+dec.format(Math.abs(state.coeff2))+
                        STR.ENDBOLD; //e**0 = 1
                } else {
                    if (state.coeff2 < 0)  s += STR.BOLD+" -"+STR.ENDBOLD;
                    else  s += STR.BOLD+" +"+STR.ENDBOLD;
                    if (anyFirstTerm) s += " ";
                    s += STR.BOLD+dec.format(Math.abs(state.coeff2))+"e"+
                        STR.ENDBOLD;
                    if (state.exp2 == 1.0)
                        s += STR.SUP+"y"+STR.ENDSUP;
                    else
                        s += STR.SUP+dec.format(state.exp2)+"y"+STR.ENDSUP;
                }
            }
            break;
        //    
        // f =   xHat acos(my) + yHat bsin(nx)
        // DXf =  zHat(bncos(nx) + amsin(my))
        // coeff1 = bn   coeff2 = n     coeff3 = am   coeff4 = m
        //
        case Mod4State.sinusoidal:
            if (state.coeff1 == 0) {
                anyFirstTerm = false;
                s = "";
            } else if (Math.abs(state.coeff1) == 1.0) {
                if (state.coeff2 == 0) {
                    // Since cos(0) is 1:
                    s = STR.BOLD+"1"+STR.ENDBOLD;
                } else {
                    if (state.coeff1 == -1.0)
                        s = STR.BOLD+"-"+STR.ENDBOLD;
                    s = STR.BOLD+"cos("+STR.ENDBOLD;
                    if (state.coeff2 == 1.0)
                        s += STR.BOLD+"x)"+STR.ENDBOLD;
                    else s += STR.BOLD+dec.format(state.coeff2)+"x)"+
                             STR.ENDBOLD;
                }
            } else {
                if (state.coeff2 == 0) {
                    // Since cos(0) is 1:
                    s = STR.BOLD+dec.format(state.coeff1)+STR.ENDBOLD;
                } else {
                    s = STR.BOLD+dec.format(state.coeff1);
                    if (state.coeff2 == 1.0)
                        s += "cos(x)"+STR.ENDBOLD;
                    else s += "cos("+dec.format(state.coeff2)+"x)"+STR.ENDBOLD;
                }
            }

            if (state.coeff3 == 0) {
                // No 2nd term
            } else if (Math.abs(state.coeff3) == 1.0) {
                if (state.coeff3 == -1) s += STR.BOLD+" -"+STR.ENDBOLD;
                else s += STR.BOLD+" +"+STR.ENDBOLD;
                if (anyFirstTerm) s += " ";
                if (state.coeff4 == 0) {  // NOT possible - coeff3 also =0
                    // since sin(0) is 0:
                    s += "";
                } else {
                    s += STR.BOLD+"sin(";
                    if (state.coeff4 == 1.0)
                        s += "y)"+STR.ENDBOLD;
                    else s += dec.format(state.coeff4)+"y)"+STR.ENDBOLD;
                }
            } else {
                // Since sin(0) is 0:
                if (state.coeff4 != 0) {
                    if (state.coeff3 < 0)  s += STR.BOLD+" -"+STR.ENDBOLD;
                    else  s += STR.BOLD+" +"+STR.ENDBOLD;
                    if (anyFirstTerm) s += " ";
                    s += STR.BOLD+dec.format(Math.abs(state.coeff3));
                    if (state.coeff4 == 1.0)
                        s += "sin(y)"+STR.ENDBOLD;
                    else s += "sin("+dec.format(state.coeff4)+"y)"+STR.ENDBOLD;
                }
            }
        }   
        if (s.length() == 0) s = STR.BOLD+"0"+STR.ENDBOLD;

	// Peel off preceding character because CHEERPJ doesn't render
	//  it.  Later, will write 'nabla' image in front of sOutput
	/*
        state.sOutput = STR.PLUS2FONT+
            Character.toString((char)0x2207)+STR.ENDPLUS2FONT+STR.MULT+
            Character.toString((char)0x00D7)+STR.ENDMULT+
            STR.BOLDITAL+"f"+STR.ENDBOLDITAL+" = "+
            STR.ZHAT+"z"+STR.ENDZHAT+STR.BOLD+"("+STR.ENDBOLD + s +
            STR.BOLD+")"+STR.ENDBOLD;
	*/
        state.sOutput = STR.MULT+
            Character.toString((char)0x00D7)+STR.ENDMULT+
            STR.BOLDITAL+"f"+STR.ENDBOLDITAL+" = "+
            STR.ZHAT+"z"+STR.ENDZHAT+STR.BOLD+"("+STR.ENDBOLD + s +
            STR.BOLD+")"+STR.ENDBOLD;

        outInfo.repaint();        
    }
    
    	
    public void paint(Graphics g){
	
	g.setColor(bgcolor.darker());
	g.fillRect(0,getSize().height-2,getSize().width,2);
	g.fillRect(getSize().width-2,0,2,getSize().height);
	g.setColor(bgcolor.brighter());
	g.fillRect(0,0,2,getSize().height-1);
	g.fillRect(0,0,getSize().width-2,2);
	
    }
    

}

class NewOutputCanvas2 extends Canvas{
    private static  Font normalfont;
    private static  Font subfont;
    private static  Font boldfont;
    Mod4State state;
    private int endingX;
    private Image im;
    private Graphics buf;

    private BufferedImage nabla;
    
    public NewOutputCanvas2(Mod4State state){
        super();
        this.state = state;
        normalfont = state.sanSerifFont.deriveFont(12f);
        subfont = state.sanSerifFont.deriveFont(10f);
        boldfont = TheFonts.bold14;

	getImages();
    }


   
    private void getImages() {
        // read in the nabla images, because CHEERPJ does not render this
	//  symbol in any font!  (java to javascript converter)
        try {
            nabla = ImageIO.read(getClass().getResource("nabla.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void paint(Graphics g){
        if(im == null){
            im = createImage(getSize().width,getSize().height);
            buf = im.getGraphics();
            drawCanvas(buf);
        }
        else{
            drawCanvas(buf);
        }
        g.drawImage(im,0,0,null);
    }
    
    //Addition to reduce flicker new routine
    public void update(Graphics g){		// added to avoid clearing
        paint(g);
    }
    
    public void clear(){
        this.getGraphics().clearRect(0,0,getSize().width,getSize().height);
        repaint();
    }
    
    
    
    public void drawCanvas(Graphics g){
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        //g.setFont(state.ttfFont.deriveFont(14f));

        Color bgcolor = new Color(236,236,236);
       
        g.setColor(bgcolor);
        g.fillRect(0,0,getSize().width-6,getSize().height-6);

        g.setColor(Color.black);
        if (state.sOutput != null) {
            //g.setFont(TheFonts.sanSerif14);
            g.setFont(boldfont);
            //endingX = STR.displayString(state.sOutput,g,16,40);

	    // NEW: replacing above line, d/t CHEEPJ problems with spec. chars
	    //  (image goes -13 pixels on y-axis)
	    g.drawImage(nabla,16,27,this);
	    endingX = STR.displayString(state.sOutput,g,31,40);	    
        }
    }
}

