import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.net.URL;
import java.text.*;
import java.util.Map;
import java.util.Hashtable;
import java.util.jar.Attributes;
//import javax.swing.*;

// Chapter 4 Module 1
public class Mod1 extends Frame implements AdjustmentListener,
                                           ItemListener,
                                           ActionListener,
                                           MouseListener, 
                                           MouseMotionListener,
                                           WindowListener {

    private static final long serialVersionUID = 352378;
    TitlePanel titlePanel;
    Instructions instructions;
    //Mod1Choice choicePanel;
    Mod1Input inputPanel;  // Polar to rectangular
    Mod1State state;
    Mod1Plot plotPanel;

    Font ttfFont, phiFont, italicFont;

    private static final boolean useOldFonts = true;    


  public void start() {
  }

  public void stop(){}

  public void destroy(){}


    public static void main(String[] args){
        Mod1 f = new Mod1();
        int xmove = 20;
        int ymove = 41;
        f.setSize(991+xmove,680+ymove);
        //f.setSize(960,712);
        f.setVisible(true);
        f.setLayout(null);
    }

  public Mod1() { 
    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 Mod1State();
        state.ttfFont = ttfFont;
        state.sanSerifFont = ttfFont;
        state.serifFont = ttfFont;
        state.symbolFont = phiFont;
        state.italicFont = phiFont;
        TheFonts.setNewFonts(ttfFont, phiFont, italicFont);
    } else {
        state = new Mod1State();
        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;

    instructions = new Instructions(state);
    instructions.setBounds(346+xmove,78+ymove,635,581);
    //instructions.setVisible(false);

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

    //titlePanel = new TitlePanel(state.ttfFont.deriveFont(Font.BOLD,15f),
    //                            "Module 5.2","Magnetic Fields due to Line Sources");
    titlePanel = new TitlePanel("Module 5.2","Magnetic Fields due to Line Sources");
    titlePanel.setBounds(10+xmove,10+ymove,326,60);

    //choicePanel = new Mod1Choice(state);
    Panel choicePanel = new Panel();
    choicePanel.setBackground(Color.gray.brighter());
    choicePanel.setBounds(344+xmove,11+ymove,637,58);
	
    inputPanel = new Mod1Input(state);
    inputPanel.setBounds(14+xmove,79+ymove,320,579);

    plotPanel = new Mod1Plot(state);
    plotPanel.setBounds(346+xmove,78+ymove,635,581);
    plotPanel.setVisible(true);

    // backpanels for choice,input, and plot
    ////choicePanel.setBounds(517,13,461,34);
    //Panel p_c_w  = new Panel();
    //p_c_w.setBackground(Color.white);
    //p_c_w.setBounds(516,12,463,37);
    //Panel p_c_b = new Panel();
    //p_c_b.setBackground(Color.black);
    //p_c_b.setBounds(515,11,465,39);

    ////plotPanel.setBounds(12,58,635,581);
    //Panel p_p_w = new Panel();
    //p_i_w.setBackground(Color.white);
    //p_i_w.setBounds(11,57,631,541);
    Panel p_p_b = new Panel();
    p_p_b.setBackground(Color.black);
    p_p_b.setBounds(345+xmove,77+ymove,637,583);
    ////inputPanel.setBounds(658,59,320,579);
    Panel p_i_w = new Panel();
    p_i_w.setBackground(Color.white);
    p_i_w.setBounds(13+xmove,78+ymove,322,581);
    Panel p_i_b = new Panel();
    p_i_b.setBackground(Color.black);
    p_i_b.setBounds(12+xmove,77+ymove,324,583);

    //backpanels for applet
    Panel p0 = new Panel();
    p0.setBackground(Color.cyan);
    p0.setBounds(3+xmove,3+ymove,985,663);
	    
    Panel p00 = new Panel();
    p00.setBackground(Color.black);
    p00.setBounds(xmove,ymove,991,669);
   
    add(nullPanel);
    add(choicePanel);
    add(titlePanel);
    add(inputPanel);
    add(instructions);
    add(plotPanel);

    //add(p_c_w);
    //add(p_c_b);
    add(p_i_w);
    add(p_i_b);
    //add(p_p_w);
    add(p_p_b);
    
    inputPanel.initialize();
    plotPanel.initialPlot();

    add(p0);
    add(p00);


    //Listeners
    this.addWindowListener(this);
    inputPanel.reset.addActionListener(this);
    //choicePanel.ch.addItemListener(this);
    //inputPanel.ch1.addItemListener(this);
    inputPanel.ch2.addItemListener(this);
    inputPanel.ch3.addItemListener(this);
    inputPanel.ch4.addItemListener(this);
    inputPanel.ch5.addItemListener(this);
    inputPanel.ch6.addItemListener(this);
    inputPanel.sliderc.addAdjustmentListener(this);
    //inputPanel.textc.addTextListener(this);
    inputPanel.textc.addActionListener(this);
    plotPanel.addMouseListener(this);
    plotPanel.addMouseMotionListener(this);
    plotPanel.small.addActionListener(this);
    instructions.closeIt.addActionListener(this);

    nullButton.requestFocus();
  }


/*
    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);

        g.setColor(Color.magenta);
        g.fillRect(13,495,492,50);
    }


    public void mouseDragged(MouseEvent evt){mouseDragging(evt);}
    public void mouseMoved(MouseEvent evt){mouseMoving(evt);}
    public void mouseClicked(MouseEvent evt){;}//dbl: also when mousePressed
    public void mouseEntered(MouseEvent evt){;}
    public void mouseExited(MouseEvent evt){;}
    public void mousePressed(MouseEvent evt){mActionDone(evt);}

    // user must press, drag, and release to move a charge
    public void mouseReleased(MouseEvent evt){
        if (state.currentAction == Mod1State.moveCharge) {
            state.moveToPoint = evt.getPoint();
            plotPanel.moveCharge();
            plotPanel.drawPlot();
        }
    }

    // mouse dragged
    private void mouseDragging(MouseEvent evt) {
        if (state.currentAction == Mod1State.moveCharge) {
            state.moveToPoint = evt.getPoint();
            plotPanel.moveCharge();
            state.moveFromPoint = state.moveToPoint;
            plotPanel.drawPlot();
        }

    }


    // mouse moved
    private void mouseMoving(MouseEvent evt) {
        if (state.currentAction == Mod1State.showBFieldAtCursor) {
            plotPanel.getBFieldAtCursor(evt.getPoint());
            inputPanel.showBFieldAtCursor();
        }
    }

    // mouse pressed or clicked
    private void mActionDone(MouseEvent evt) {
        switch (state.currentAction) {
           case (Mod1State.placeCharge):
               plotPanel.placeCharge(evt.getPoint());
               plotPanel.drawPlot();
               break;
           case (Mod1State.changeChargeValue):
               state.highlightedPoint = new Point(evt.getPoint());
               // These 2 WERE commented out: see what they say
               //plotPanel.changeCharge(evt.getPoint());
               //plotPanel.drawPlot();
               break;
           case (Mod1State.removeCharge):
               plotPanel.removeCharge(evt.getPoint());
               plotPanel.drawPlot();
               break;
           case (Mod1State.moveCharge):
               state.moveFromPoint = evt.getPoint();
               break;
           case (Mod1State.showBFieldAtCursor):
               plotPanel.getBFieldAtCursor(evt.getPoint());  // sets state var
               inputPanel.showBFieldAtCursor();    // displays the state var
               break;
           default:
               break;
        }
    }



    public void windowClosing(WindowEvent e) {      
        dispose();
        System.exit(0);
    }
    public void windowOpened(WindowEvent e){ }
    public void windowIconified(WindowEvent e){ }
    public void windowClosed(WindowEvent e){ }
    public void windowDeiconified(WindowEvent e){ }
    public void windowActivated(WindowEvent e){ }
    public void windowDeactivated(WindowEvent e){ }
    


    /*
    public void textValueChanged(TextEvent evt) {
        if (evt.getSource()==inputPanel.textc) {
            inputPanel.readTextUpdateSlider();
            if (state.currentAction == Mod1State.changeChargeValue &&
                state.highlightedPoint != null) {
                Point pt = new Point(state.highlightedPoint);
                plotPanel.changeCharge(pt);
                plotPanel.drawPlot();
            }
        }
    }
    */


    public void actionPerformed(ActionEvent evt){
        if (evt.getSource()==instructions.closeIt) {
            instructions.setVisible(false);
            plotPanel.setVisible(true);           
        } else if (evt.getSource()==plotPanel.small) {
            instructions.setVisible(true);
            plotPanel.setVisible(false);

        //
        } else if(evt.getSource()==inputPanel.reset){
            state.currentAction = state.placeCharge;
            inputPanel.reset();  // reset #equi-pot-lines slider
            plotPanel.reset();
            plotPanel.drawPlot();
        // NEW: 3/22/14 ... see if works better on older Mac systems ...
        } else if (evt.getSource()==inputPanel.textc) {
            inputPanel.readTextUpdateSlider();
            if (state.currentAction == Mod1State.changeChargeValue &&
                state.highlightedPoint != null) {
                Point pt = new Point(state.highlightedPoint);
                plotPanel.changeCharge(pt);
                plotPanel.drawPlot();
            }
        }

    }



    public void adjustmentValueChanged(AdjustmentEvent evt){

        String eventInfo = evt.paramString();
        if (eventInfo.indexOf("isAdjusting=true") != -1) return;

	if (evt.getSource()==inputPanel.sliderc) {
            //inputPanel.adjustmentValueChanged(evt);
            if (state.currentAction == Mod1State.changeChargeValue &&
                state.highlightedPoint != null) {
                Point pt = new Point(state.highlightedPoint);
                plotPanel.changeCharge(pt);
                plotPanel.drawPlot();
            }
        }
    }

    public void itemStateChanged(ItemEvent evt){
	
        // NOTE: do all this extra stuff when switching from cartesian <->
        //       cylindrical, because user may have changed text entries w/o
        //       pressing <ENTER> or <UPDATE> button.

        // Some input panel choice was changed; clear out the input panel
        //  display voltage/efield text areas:
        inputPanel.clearShowBFieldStuff();

        if (evt.getSource() == inputPanel.ch2) {
            state.highlightedPoint = (Point)null;
            state.currentAction = state.placeCharge;
        } else if (evt.getSource() == inputPanel.ch3) {
            state.currentAction = state.changeChargeValue;            
        } else if (evt.getSource() == inputPanel.ch4) {
            state.highlightedPoint = (Point)null;
            state.currentAction = state.removeCharge;
        } else if (evt.getSource() == inputPanel.ch5) {
            state.highlightedPoint = (Point)null;
            state.currentAction = state.moveCharge;
        } else if (evt.getSource() == inputPanel.ch6) {
            state.highlightedPoint = (Point)null;
            state.currentAction = state.showBFieldAtCursor;
            /*
        } else if (evt.getSource() == inputPanel.ch01) {
            state.displayPotentialField = inputPanel.ch01.getState();
            plotPanel.drawPlot();
        } else if (evt.getSource() == inputPanel.ch02) {
            state.displayEquiPotentialLines = inputPanel.ch02.getState();
            plotPanel.drawPlot();
        } else if (evt.getSource() == inputPanel.ch03) {
            state.displayElectricField = inputPanel.ch03.getState();
            plotPanel.drawPlot();
            */
        } 
        
        //if(evt.getSource() == choicePanel.ch) {
        //    ItemSelectable ie = evt.getItemSelectable();
        //    if(ie.getSelectedObjects()[0]==" Instructions"){
        //        instructions.setVisible(true);
        //        plotPanel.setVisible(false);
        //    }else if (ie.getSelectedObjects()[0]==" Show Fields"){
        //        instructions.setVisible(false);
        //        plotPanel.setVisible(true);
        //    }                   
        //}
    }
    
}
