//Mod3Input.java
/*
 * Panel with all input operations for Module1.1
 * Using null layout - positions of elements hard-coded
 * authors: Umberto Ravaioli, Janice Richards
 * version 1.0 - Copyright: Amanogawa.com - All Rights Reserved
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.text.*;
import java.util.Map;
import java.util.Hashtable;
import java.util.jar.Attributes;

public class Mod3Input extends Panel implements AdjustmentListener {
    private Mod3State state;
    private static final Color bgcolor = new Color(236,236,236);
    private Label titlelabel;
    public Checkbox ch2, ch3, ch4, ch5, ch6;
    public Checkbox ch01, ch02, ch03, ch04;
    private boolean oldCh01State, oldCh02State, oldCh03State, oldCh04State;
    public  Button reset;
    //public Choice chDeltaV;
    private Label ulabc, labc, ulabv, labv, ulabe, labe, ulabp, labp;
    private TextField textv, texte, textp;
    public TextField textc;
    public Scrollbar sliderc;
    public Scrollbar sliderdv;
    public ShowAngle sa;
    //public int ScrollMax = 10000;
    public int ScrollMax = 100;
    int  w2,w3,w4,w5,w6, w01,w02,w03,w04, wv1,wv2,we1,we2,wp1,wp2;
    int yLine;
    public boolean voltageAtCursorIsValid = false;  // initially
    //DecimalFormat dec = new DecimalFormat("#.##");
    DecimalFormat dec = new DecimalFormat("#.#");
    DecimalFormat dec2 = new DecimalFormat("#.###");
    DecimalFormat dec3 = new DecimalFormat("#.#####E0");
    //DecimalFormat decDEBUG = new DecimalFormat("#.######");
    private static final String emptyString = "                        ";
    //private boolean ignoreNextTextEvent = false;
    //private boolean ignoreNextSliderEvent = false;

    private boolean ignoreSliderAdjustment = false;


    public Mod3Input(Mod3State state){
	super();
	setLayout(null);
	setBackground(bgcolor);
	this.state = state;
    }


    public void initialize() {

	titlelabel = new Label("Input",Label.CENTER);
	titlelabel.setFont(TheFonts.bold16);
	
	reset = new Button("Clear");
        reset.setFont(TheFonts.sanSerif12);
        add(reset);

        //chDeltaV = new Choice();
        //chDeltaV.addItem("+");
        //chDeltaV.addItem("-");
        //chDeltaV.setFont(state.ttfFont.deriveFont(14f));
        //chDeltaV.setBackground(bgcolor);
        //add(chDeltaV);
        Label plusLabel = new Label("more");
        Label plusLabel2 = new Label("lines");
        Label minusLabel = new Label("less");
        Label minusLabel2 = new Label("lines");
        sliderdv = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,15);

        add(plusLabel);
        add(plusLabel2);
        add(minusLabel);
        add(minusLabel2);
        add(sliderdv);

	CheckboxGroup chgroup1 = new CheckboxGroup();
	//ch1 = new Checkbox("  place -ve charge",true,chgroup1);
        ch2 = new Checkbox("  place charge",true,chgroup1);
        ch3 = new Checkbox("  change charge value",false,chgroup1);
        ch4 = new Checkbox("  remove charge",false,chgroup1);
        ch5 = new Checkbox("  move charge",false,chgroup1);
        ch6 = new Checkbox("  show voltage, electric field,",
                           false,chgroup1);
        Label labch6 = new Label("     and charge density at cursor:");
        
        getLabelWidths();
	
        //ch1.setForeground(Color.black);
        //ch1.setFont(state.ttfFont.deriveFont(14f));
	ch2.setForeground(Color.black);
        ch2.setFont(state.ttfFont.deriveFont(14f));
	ch3.setForeground(Color.black);
        ch3.setFont(state.ttfFont.deriveFont(14f));
	ch4.setForeground(Color.black);
        ch4.setFont(state.ttfFont.deriveFont(14f));
	ch5.setForeground(Color.black);
        ch5.setFont(state.ttfFont.deriveFont(14f));
	ch6.setForeground(Color.black);
        ch6.setFont(state.ttfFont.deriveFont(14f));
        labch6.setFont(state.ttfFont.deriveFont(14f));
        
	//ch1.setBackground(bgcolor);
	ch2.setBackground(bgcolor);
	ch3.setBackground(bgcolor);
	ch4.setBackground(bgcolor);
	ch5.setBackground(bgcolor);
	ch6.setBackground(bgcolor);
	labch6.setBackground(bgcolor);

	labc = new Label("charge =  ",Label.RIGHT);
        labc.setFont(state.ttfFont.deriveFont(14f));
        labc.setForeground(Color.black);
	labv = new Label("v =  ",Label.RIGHT);
        labv.setFont(state.ttfFont.deriveFont(14f));
        labv.setForeground(Color.black);
	labe = new Label("E =  ",Label.RIGHT);
        labe.setFont(state.ttfFont.deriveFont(14f));
        labe.setForeground(Color.black);
        labp = new Label("\u03c1 = ",Label.RIGHT);
        labp.setFont(state.ttfFont.deriveFont(14f));
        labp.setForeground(Color.black);
        textc = new TextField(6);
        textc.setFont(state.ttfFont.deriveFont(14f));
        textc.setForeground(Color.black);
	textc.setText(""+dec.format(state.chargeToAdd));
        textv = new TextField(6);
        textv.setFont(state.ttfFont.deriveFont(14f));
        textv.setForeground(Color.black);
	textv.setText("");
	textv.setEditable(false);
        texte = new TextField(8);
        texte.setFont(state.ttfFont.deriveFont(14f));
        texte.setForeground(Color.black);
	texte.setText("");
	texte.setEditable(false);
        textp = new TextField(8);
        textp.setFont(state.ttfFont.deriveFont(14f));
        textp.setForeground(Color.black);
	textp.setText("");
	textp.setEditable(false);
	//ulabc = new Label("nCoulombs ",Label.LEFT);
	ulabc = new Label("e ",Label.LEFT);
        ulabc.setFont(state.ttfFont.deriveFont(14f));
	ulabv = new Label("Volts ",Label.LEFT);
        ulabv.setFont(state.ttfFont.deriveFont(14f));
	ulabe = new Label("V/m ",Label.LEFT);
        ulabe.setFont(state.ttfFont.deriveFont(14f));
	//ulabp = new Label("C/m2 ",Label.LEFT);
	//ulabp = new Label("",Label.LEFT);
        //ulabp.setFont(state.ttfFont.deriveFont(14f));
	sliderc = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,ScrollMax+1);
	//sliderc.setValue((int)((state.chargeToAdd-state.chargeMin)*
        //                       ScrollMax/(state.chargeMax-state.chargeMin)));

        sa = new ShowAngle(state);

	add(labc);
	add(textc);
	add(sliderc);
	add(ulabc);
        add(labv);
        add(textv);
        add(ulabv);
        add(labe);
        add(texte);
        add(ulabe);
        add(labp);
        add(textp);
        //add(ulabp);

        add(sa);

	//int vPosInit = 60, vPos, dvPos = 4, vHeight = 20; 
	int vPosInit = 40, vPos, dvPos = 4, vHeight = 20; 
	vPos = vPosInit;
        int col = 20;
        
	labc.setBounds(col+20,vPos,80,vHeight);
	textc.setBounds(col+100,vPos,80,vHeight);
	ulabc.setBounds(col+180,vPos,80,vHeight);
	
	    vPos += vHeight + dvPos; 
	   
	sliderc.setBounds(col+22,vPos+2,196,vHeight);
            Panel ps1 = new Panel();
            //ps1.setBackground(Color.cyan);
            ps1.setBackground(Color.orange);
	    add(ps1);
	    ps1.setBounds(col+21,vPos+1,198,vHeight+2);

            Panel ps10 = new Panel();
            ps10.setBackground(Color.black);
            add(ps10);
            ps10.setBounds(col+20,vPos,200,vHeight+4);



	add(titlelabel);

	//add(ch1);
	add(ch2);
	add(ch3);
	add(ch4);
	add(ch5);
	add(ch6);
	add(labch6);

        ch01 = new Checkbox("  Potential field",true);
        ch02 = new Checkbox("  Electric field",false);
        ch03 = new Checkbox("  Charge density",false);
        ch04 = new Checkbox("  Equipotential lines:",false);

        ch01.setForeground(Color.black);
        ch01.setFont(state.ttfFont.deriveFont(14f));
        ch02.setForeground(Color.black);
        ch02.setFont(state.ttfFont.deriveFont(14f));
        ch03.setForeground(Color.black);
        ch03.setFont(state.ttfFont.deriveFont(14f));
        ch04.setForeground(Color.black);
        ch04.setFont(state.ttfFont.deriveFont(14f));
	ch01.setBackground(bgcolor);
	ch02.setBackground(bgcolor);
	ch03.setBackground(bgcolor);
	ch04.setBackground(bgcolor);
	add(ch01);
	add(ch02);
	add(ch03);
	add(ch04);

	titlelabel.setBounds(20,5,50,18);

        int column1 = 40;
        int column2 = 200;
        int deltaY = 25;
        //int startingY = 40 + 3*deltaY;
        int startingY = 40 + 2*deltaY;
        int h = 20;
	ch2.setBounds(column1,startingY,w2,h);
	ch3.setBounds(column1,startingY+deltaY,w3,h);
	ch4.setBounds(column1,startingY+2*deltaY,w4,h);
	ch5.setBounds(column1,startingY+3*deltaY,w5,h);
	ch6.setBounds(column1,startingY+4*deltaY,w6,h);
	labch6.setBounds(column1,startingY+5*deltaY,w6+40,h);

        int newCol = column1-20;
        getCursorStuffWidths();
        labv.setBounds(newCol,startingY+6*deltaY+10,wv1,h);
        newCol+=wv1;
        textv.setBounds(newCol,startingY+6*deltaY+10,100,h);
        newCol+=100;
        ulabv.setBounds(newCol,startingY+6*deltaY+10,wv2,h);
        newCol = column1-20;
        labe.setBounds(newCol,startingY+7*deltaY+10,we1,h);
        newCol+=we1;
        texte.setBounds(newCol,startingY+7*deltaY+10,100,h);
        newCol+=100;
        ulabe.setBounds(newCol,startingY+7*deltaY+10,we2-20,h);


        newCol = column1-20;
        labp.setBounds(newCol,startingY+8*deltaY+10,wp1,h);
        newCol+=we1;
        textp.setBounds(newCol,startingY+8*deltaY+10,100,h);
        newCol+=100;
        //ulabp.setBounds(newCol,startingY+8*deltaY+10,wp2-20,h);



        //newCol = column1+160;
        newCol = column1+180;
        sa.setBounds(newCol,startingY+6*deltaY+20,40,40);

        yLine = startingY+9*deltaY + 18;
        /*
        ch01.setBounds(column1,startingY+11*deltaY + 15,w01,h);
        ch02.setBounds(column1,startingY+12*deltaY + 15,w02,h);
        ch03.setBounds(column1,startingY+13*deltaY + 15,w03,h);
        ch04.setBounds(column1,startingY+14*deltaY + 15,w04,h);
        */
        ch01.setBounds(column1,startingY+11*deltaY,w01,h);
        ch02.setBounds(column1,startingY+12*deltaY,w02,h);
        ch03.setBounds(column1,startingY+13*deltaY,w03,h);
        ch04.setBounds(column1,startingY+14*deltaY,w04,h);
        /*
        sliderdv.setBounds(column1+180,startingY+12*deltaY-12,15,75);

        plusLabel.setBounds(column1+200,startingY+11*deltaY,40,15);
        plusLabel2.setBounds(column1+200,startingY+11*deltaY+15,40,15);
        minusLabel.setBounds(column1+200,startingY+13*deltaY+20,40,15);
        minusLabel2.setBounds(column1+200,startingY+13*deltaY+35,40,15);
        */

        int yLine2 = startingY+15*deltaY;
        sliderdv.setBounds(column1+50,yLine2,140,15);

        minusLabel.setBounds(column1,yLine2,40,15);
        minusLabel2.setBounds(column1,yLine2+15,40,15);
        plusLabel.setBounds(column1+200,yLine2,40,15);
        plusLabel2.setBounds(column1+200,yLine2+15,40,15);


        //  band VI
	//int y_update =355;
	//int y_update =455;

        int y_update = 515;
	reset.setBounds(120,y_update,60,20);
	Panel ps7 = new Panel();
            //ps7.setBackground(Color.cyan);
            ps7.setBackground(Color.orange);
	    add(ps7);
	    ps7.setBounds(119,y_update-1,62,22);
	    
	Panel ps8 = new Panel();
	    ps8.setBackground(Color.black);
	    add(ps8);
	    ps8.setBounds(118,y_update-2,64,24);

            //sliderc.addAdjustmentListener(this);
        // NEW place for the setting the value of the sliders:
        sliderdv.setValue(10);
	sliderc.setValue((int)((state.chargeToAdd-state.chargeMin)*
                               ScrollMax/(state.chargeMax-state.chargeMin)));

        sliderc.addAdjustmentListener(this);
        sliderdv.addAdjustmentListener(this);
    }


    private void getLabelWidths() {
        setFont(state.ttfFont.deriveFont(14f));
        //Graphics g=getGraphics();
        //FontMetrics fm = g.getFontMetrics();

        FontMetrics fm = getFontMetrics(getFont());

        int extra = fm.stringWidth("gegegege");
        w2 = fm.stringWidth("place charge")+extra;
        w3 = fm.stringWidth("change charge value")+extra;
        w4 = fm.stringWidth("remove charge")+extra;
        w5 = fm.stringWidth("move charge")+extra;
        w6 = fm.stringWidth("show voltage, electric field,")+extra;

        w01 = fm.stringWidth("Potential field")+extra;
        w02 = fm.stringWidth("Electric field")+extra;
        w03 = fm.stringWidth("Charge density")+extra;
        w04 = fm.stringWidth("Equipotential lines:")+extra;
        
        //g.dispose();
    }

    private void getCursorStuffWidths() {
        setFont(state.ttfFont.deriveFont(14f));
        //Graphics g=getGraphics();
        //FontMetrics fm = g.getFontMetrics();

        FontMetrics fm = getFontMetrics(getFont());

        int extra = fm.stringWidth("gege");
        wv1 = fm.stringWidth("v = ")+extra;
        wv2 = fm.stringWidth("Volts")+extra;
        we1 = fm.stringWidth("E = ")+extra;
        we2 = fm.stringWidth("V/m")+extra;   
        wp1 = fm.stringWidth("E = ")+extra;
        wp2 = fm.stringWidth("\u03c1 = ")+0;   
        //g.dispose();
    }



    public void showVoltageAtCursor() {
        // read state.voltageAtCursor and state.efieldAtCursor
        // set flag that voltageAtCursorIsValid = true;
        // repaint();
	textv.setText(""+dec3.format(state.voltageAtCursor));
	texte.setText(""+dec3.format(state.efieldAtCursor));
	textp.setText(""+dec3.format(state.chargeDensityAtCursor));
        sa.draw();
        return;
    }


    //public synchronized void readTextUpdateSlider() {
    public void readTextUpdateSlider() {
        //if (ignoreNextTextEvent) {
        //    ignoreNextTextEvent = false;
        //    return;
        //}
        double charge=  0.0;
        ignoreSliderAdjustment = true;

        try { 
            //ignoreNextSliderEvent = true;
            if(Double.valueOf(textc.getText()).doubleValue()<=state.chargeMax &&
               Double.valueOf(textc.getText()).doubleValue()>=state.chargeMin){
                charge=Double.valueOf(textc.getText()).doubleValue();
                sliderc.setValue((int)(ScrollMax*(charge-state.chargeMin)
                                            /(state.chargeMax-state.chargeMin)));
                charge = rounder(charge,2);
            } else if(Double.valueOf(textc.getText()).doubleValue()>state.chargeMax){
                charge = state.chargeMax;
                textc.setText(""+dec.format(state.chargeMax));
                sliderc.setValue(ScrollMax);
            } else if(Double.valueOf(textc.getText()).doubleValue()<state.chargeMin){
                charge = state.chargeMin;
                textc.setText(""+dec.format(state.chargeMin));
                sliderc.setValue(0);
            }
        } catch(NumberFormatException e){
            charge =  0.0;
        }
        state.chargeToAdd = charge;
        //if (ch2.getState()) state.chargeToAdd = charge;
        //else if (chxx.getState()) state.chargeChangeValue = charge;
    }


    /*
    public synchronized void adjustmentValueChanged(AdjustmentEvent evt){
        if (ignoreNextSliderEvent) {
            ignoreNextSliderEvent = false;
            return;
        }
    */

    public void adjustmentValueChanged(AdjustmentEvent evt){
        if (evt.getSource()==sliderc) {

            // want to ignore the slider if it was changed PROGRAMMATICALLY,
            //  (done after user changed the charge value text-field.
            if (ignoreSliderAdjustment) {
                ignoreSliderAdjustment = false;
                // BUT don't want to remove event, so Mod1 can still see it,
                //  and draw the plot and display the output
                return;
            }


            if(sliderc.getValue()>=ScrollMax){
                state.chargeToAdd=state.chargeMax;
                sliderc.setValue((int)((state.chargeToAdd-state.chargeMin)*
                                       ScrollMax/(state.chargeMax-state.chargeMin)));
	    } else {
		state.chargeToAdd = state.chargeMin + 
		    (state.chargeMax-state.chargeMin)*
                    sliderc.getValue()/ScrollMax;
                //state.chargeToAdd = MaestroA.rounder(state.chargeToAdd,7);
                state.chargeToAdd = rounder(state.chargeToAdd,2);
	    }
	    textc.setText(""+dec.format(state.chargeToAdd));
        } else if (evt.getSource()==sliderdv) {
            state.deltaV = sliderdv.getValue();
        }
    }

    private double rounder(double dval, int places) {
        int multiplier = 1;
        for (int i=0; i<places ; i++)
            multiplier *= 10;
        int value = (int)(dval*multiplier);
        double newDval = 1.0*value/multiplier;
        return newDval;
    }


    public void disablePlotStuff() {
        state.displayPotentialField = false;
        state.displayEquiPotentialLines = false;
        state.displayElectricField = false;
        state.displayChargeDensity = false;
        oldCh01State = ch01.getState();
        oldCh02State = ch02.getState();
        oldCh03State = ch03.getState();
        oldCh04State = ch04.getState();
        ch01.setState(false);
        ch02.setState(false);
        ch03.setState(false);
        ch04.setState(false);
        ch01.setEnabled(false);
        ch02.setEnabled(false);
        ch03.setEnabled(false);
        ch04.setEnabled(false);
    }


    public void enablePlotStuff() {
        ch01.setEnabled(true);
        ch02.setEnabled(true);
        ch03.setEnabled(true);
        ch04.setEnabled(true);
        ch01.setState(oldCh01State);
        ch02.setState(oldCh02State);
        ch03.setState(oldCh03State);        
        ch04.setState(oldCh04State);        
        state.displayPotentialField = ch01.getState();
        state.displayElectricField = ch02.getState();
        state.displayChargeDensity = ch03.getState();
        state.displayEquiPotentialLines = ch04.getState();
    }


    public void reset() {
        sliderdv.setValue(10);
        ch2.setState(true);   // set to "Place Charge"
        ch01.setState(false);
        ch02.setState(false);
        ch03.setState(false);
        ch04.setState(false);
        state.displayPotentialField = false;
        state.displayEquiPotentialLines = false;
        state.displayElectricField = false;  
        state.displayChargeDensity = false;
        state.voltageAtCursor = 0.0;
        state.efieldAtCursor = 0.0;
        state.chargeDensityAtCursor = 0.0;
        textv.setText("0");
        texte.setText("0");
        textp.setText("0");
        state.chargeToAdd = state.chargeMax;
	textc.setText(""+dec.format(state.chargeToAdd));
	sliderc.setValue((int)((state.chargeToAdd-state.chargeMin)*
                               ScrollMax/(state.chargeMax-state.chargeMin)));
        sa.reset();
    }


    public void clearShowVoltageStuff() {
        textv.setText("0");
        texte.setText("0");
        textp.setText("0");
        sa.reset();
    }


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

	Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                             RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(Color.black);

        g.setFont(TheFonts.sanSerif14);
        String s = "C/m"+STR.SUP+"2"+STR.ENDSUP;
        //int endingX = STR.displayString(s,g,142,315);
        int endingX = STR.displayString(s,g,182,315);

        //g.setFont(TheFonts.bold16);
        //g.drawLine(5,yLine,455,yLine);
        //g.drawString("Plots",25,yLine+20);
        g.setFont(TheFonts.bold14);
        g.drawString("Plot Characteristics:",40,yLine+20);
    }
}
