import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.text.*;
import javax.swing.*;
import javax.swing.event.*;

// Chapter 3 Module 3
public class Mod3 extends Frame implements ChangeListener,
                                           ActionListener,
                                           ItemListener,
                                           FocusListener {
    TitlePanel titlePanel;
    Panel choicePanel;
    Mod3Input inputPanel;  // Polar to rectangular
    Mod3State state;
    Mod3Plot plotPanel;
    Mod3Info infoPanel;

    Font ttfFont, phiFont, italicFont;

    private static final boolean useOldFonts = true;    

    DecimalFormat dec = new DecimalFormat("###.#");
    DecimalFormat dec2 = new DecimalFormat("##");
    
    //private Panel instrFrame;


  public void start() {
  }

  public void stop(){}

  public void destroy(){}

    
    public static void main(String[] args){
        Mod3 f = new Mod3();
        int xmove = 20;
        int ymove = 41;
        f.setSize(1063+xmove,620+ymove);
        f.setVisible(true);
        f.setLayout(null);
    }


  public Mod3() { 
    setLayout(null);    
    String lcOSName = System.getProperty("os.name").toLowerCase();
    boolean MAC_OS_X = lcOSName.startsWith("mac os x");
    boolean PC_OS = lcOSName.startsWith("windows");
    //System.out.println(lcOSName);
    TheFonts.setMAC_OS_X(MAC_OS_X);
    TheFonts.setPC_OS(PC_OS);

    if (!useOldFonts) {
        //getUlabyFonts();
        state = new Mod3State();
        state.ttfFont = ttfFont;
        state.sanSerifFont = ttfFont;
        state.serifFont = ttfFont;
        state.symbolFont = phiFont;
        state.italicFont = phiFont;
        TheFonts.setNewFonts(ttfFont, phiFont, italicFont);
    } else {
        state = new Mod3State();
        state.ttfFont = new Font("SanSerif",Font.PLAIN,12);
        state.sanSerifFont = new Font("SanSerif",Font.PLAIN,12);
        state.serifFont = new Font("Serif",Font.PLAIN,12);
        state.symbolFont = new Font("Symbol",Font.PLAIN,12);
        state.italicFont = new Font("Serif",Font.ITALIC,12);
        TheFonts.setOldFonts();
    }

    int xmove = 10;
    int ymove = 34;

    // Get focus off any visible component ... looks nicer.
    Panel nullPanel = new Panel();
    Button nullButton = new Button();
    nullPanel.add(nullButton);
    nullPanel.setVisible(true);

    titlePanel = new TitlePanel(state.ttfFont.deriveFont(Font.BOLD,15f),
                                "Module 3.3","Divergence");
    titlePanel.setBounds(10+xmove,10+ymove,578,40);

    //choicePanel = new Mod3Choice(state);
    choicePanel = new Panel();
    choicePanel.setBounds(596+xmove,12+ymove,452,36);
    choicePanel.setBackground(Color.lightGray);
	
    inputPanel = new Mod3Input(state);
    inputPanel.setVisible(true);
    inputPanel.setBounds(597+xmove,58+ymove,450,401);

    plotPanel = new Mod3Plot(state);
    plotPanel.setVisible(true);
    plotPanel.setBounds(11+xmove,57+ymove,576,541);

    infoPanel = new Mod3Info(state);
    infoPanel.setVisible(true);
    infoPanel.setBounds(597+xmove,469+ymove,450,128);

    // backpanels for choice,input, plot and info
    ////choicePanel.setBounds(557,13,450,34);
    Panel p_c_b = new Panel();
    p_c_b.setBackground(Color.black);
    p_c_b.setBounds(596+xmove,12+ymove,452,37);
    ////inputPanel.setBounds(557,58,450,539);
    Panel p_i_w = new Panel();
    p_i_w.setBackground(Color.white);
    p_i_w.setBounds(596+xmove,57+ymove,452,403);
    Panel p_i_b = new Panel();
    p_i_b.setBackground(Color.black);
    p_i_b.setBounds(595+xmove,56+ymove,454,405);
    ////plotPanel.setBounds(11,57,536,541);
    Panel p_p_b = new Panel();
    p_p_b.setBackground(Color.black);
    p_p_b.setBounds(10+xmove,56+ymove,578,543);
    //
    // infoPanel.setBounds(557,469,450,128);
    Panel p_inf_w = new Panel();
    p_inf_w.setBackground(Color.white);
    p_inf_w.setBounds(596+xmove,468+ymove,452,130);
    Panel p_inf_b = new Panel();
    p_inf_b.setBackground(Color.black);
    p_inf_b.setBounds(595+xmove,467+ymove,454,132);



    //backpanels for applet
    Panel p0 = new Panel();
    p0.setBackground(Color.cyan);
    p0.setBounds(3+xmove,3+ymove,1055,603);
	    
    Panel p00 = new Panel();
    p00.setBackground(Color.black);
    p00.setBounds(xmove,ymove,1061,609);
   


    add(nullPanel);
    add(choicePanel);
    add(titlePanel);
    add(inputPanel);
    add(plotPanel);
    add(infoPanel);

    add(p_c_b);
    add(p_i_w);
    add(p_i_b);
    add(p_p_b);
    add(p_inf_w);
    add(p_inf_b);

    plotPanel.initialPlot();
    infoPanel.displayDivergence();
    add(p0);
    add(p00);


    //Listeners
    //this.addWindowListener(this);
    inputPanel.sliderA.addChangeListener(this);
    inputPanel.sliderB.addChangeListener(this);
    inputPanel.sliderM_other.addChangeListener(this);
    inputPanel.sliderN_other.addChangeListener(this);
    inputPanel.sliderM_sin.addChangeListener(this);
    inputPanel.sliderN_sin.addChangeListener(this);

    inputPanel.textA.addActionListener(this);
    inputPanel.textB.addActionListener(this);
    inputPanel.textM.addActionListener(this);
    inputPanel.textN.addActionListener(this);

    inputPanel.textA.addFocusListener(this);
    inputPanel.textB.addFocusListener(this);
    inputPanel.textM.addFocusListener(this);
    inputPanel.textN.addFocusListener(this);

    inputPanel.ch.addItemListener(this);

    //plotPanel.drawPlot();  already did from initialPlot() call

  }



/*
    private void getUlabyFonts() {
        String path1 = getCodeBase().getPath() + "times.ttf";
        String path2 = getCodeBase().getPath() + "palai.ttf";
        String path3 = getCodeBase().getPath() + "timesi.ttf";

        try {

            // SWAP COMMENT TO OTHER fi= STATEMENT WHEN FINAL VERSION OK
            //  TO RUN ON THE BROWSER (use the other one when debugging ...)

            //File fi = new File ("/home/jar/newcd/fonts/times.ttf");
            File fi = new File (path1);
            FileInputStream in = new FileInputStream (fi);
            ttfFont = Font.createFont (Font.TRUETYPE_FONT, in);

            //fi = new File ("/home/jar/newcd/fonts/palai.ttf");
            fi = new File (path2);
            in = new FileInputStream (fi);
            phiFont = Font.createFont (Font.TRUETYPE_FONT, in);
            phiFont = phiFont.deriveFont (14f);  // SAVE

            fi = new File (path3);
            in = new FileInputStream (fi);
            italicFont = Font.createFont (Font.TRUETYPE_FONT, in);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
*/

    
    public void paint(Graphics g){
	Graphics2D g2d = (Graphics2D)g;
        g.setColor(Color.white);	
	g.fillRect(0,0,626,585);  	
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    }



    public void stateChanged(ChangeEvent evt){
	if(evt.getSource()==inputPanel.sliderA){
            inputPanel.updateParamA();
            plotPanel.drawPlot();
            infoPanel.displayDivergence();
        } else if(evt.getSource()==inputPanel.sliderB){
            inputPanel.updateParamB();
            plotPanel.drawPlot();
            infoPanel.displayDivergence();
	} else if(evt.getSource()==inputPanel.sliderM){
            inputPanel.updateParamM();
            plotPanel.drawPlot();
            infoPanel.displayDivergence();
	} else if(evt.getSource()==inputPanel.sliderN){
            inputPanel.updateParamN();
            plotPanel.drawPlot();
            infoPanel.displayDivergence();
        }
    }



    public void itemStateChanged(ItemEvent evt){
        if (evt.getSource() == inputPanel.ch) {
            ItemSelectable ie = evt.getItemSelectable();
            if (ie.getSelectedObjects()[0]==" polynomial"){
                state.currentFunction = Mod3State.polynomial;
                state.mMin = -3; state.mMax = 3;
                state.nMin = -3; state.nMax = 3;
                inputPanel.layoutPolynomialEqn();
            } else if (ie.getSelectedObjects()[0]==" exponential"){
                state.currentFunction = Mod3State.exponential;
                state.mMin = -3; state.mMax = 3;
                state.nMin = -3; state.nMax = 3;
                inputPanel.layoutExponentialEqn();
            } else if (ie.getSelectedObjects()[0]==" sinusoidal"){
                state.currentFunction = Mod3State.sinusoidal;
                state.mMin = -10; state.mMax = 10;
                state.nMin = -10; state.nMax = 10;
                inputPanel.layoutSinusoidalEqn();
            }
            inputPanel.displayFunction();
            infoPanel.displayDivergence();
            //plotPanel.resetPlot();       
            plotPanel.drawPlot();       
        }
    }



    public void actionPerformed(ActionEvent evt){
       if (evt.getSource()==inputPanel.textA) {
            inputPanel.adjustSliderA();
            plotPanel.drawPlot();
            infoPanel.displayDivergence();
        } else if (evt.getSource()==inputPanel.textB) {
            inputPanel.adjustSliderB();
            plotPanel.drawPlot();
            infoPanel.displayDivergence();
        } else if (evt.getSource()==inputPanel.textM) {
            inputPanel.adjustSliderM();
            plotPanel.drawPlot();
            infoPanel.displayDivergence();
        } else if (evt.getSource()==inputPanel.textN) {
            inputPanel.adjustSliderN();
            plotPanel.drawPlot();
            infoPanel.displayDivergence();
        }
    }


    public void focusGained(FocusEvent e) {
        if (e.getSource() == inputPanel.textA)
            inputPanel.textA.selectAll();
        else if (e.getSource() == inputPanel.textB)
            inputPanel.textB.selectAll();
        else if (e.getSource() == inputPanel.textM)
            inputPanel.textM.selectAll();
        else if (e.getSource() == inputPanel.textN)
            inputPanel.textN.selectAll();
    }


    public void focusLost(FocusEvent e) {
        if (e.getSource() == inputPanel.textA) {
            if (inputPanel.textA.getText().trim() != dec.format(state.aVal)) {
                inputPanel.adjustSliderA();
                plotPanel.drawPlot();
                infoPanel.displayDivergence();
            }
        } else if (e.getSource()==inputPanel.textB) {
            if (inputPanel.textB.getText().trim() != dec.format(state.bVal)) {
                inputPanel.adjustSliderB();
                plotPanel.drawPlot();
                infoPanel.displayDivergence();
            }
        } else if (e.getSource()==inputPanel.textM) {
            if (inputPanel.textM.getText().trim() != dec2.format(state.mVal)) {
                inputPanel.adjustSliderM();
                plotPanel.drawPlot();
                infoPanel.displayDivergence();
            }
        } else if (e.getSource()==inputPanel.textN) {
            if (inputPanel.textN.getText().trim() != dec2.format(state.nVal)) {
                inputPanel.adjustSliderN();
                plotPanel.drawPlot();
                infoPanel.displayDivergence();
            }
        }
    }
}
