//Mod1Input.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.io.*;  // NEW
//import java.util.Map;
//import java.util.Hashtable;
//import java.util.jar.Attributes;

public class Mod1Input extends Panel implements AdjustmentListener {
    private Mod1State 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;
    public  Button reset;
    //public Choice chDeltaV;
    private Label ulabc, labc, ulabv, labv, ulabe, labe;
    private TextField textv, texte;
    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, wv1,wv2,we1,we2;
    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; // not really using anymore
    //private boolean ignoreNextAdjustmentEvent = false;

    private boolean ignoreSliderAdjustment = false;
    private Font labelfont;

    public Mod1Input(Mod1State state){
	super();
	setLayout(null);
	setBackground(bgcolor);
	this.state = state;
    }


    public void initialize() {
        labelfont = state.ttfFont.deriveFont(Font.BOLD,12f);

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

	Panel ps7 = new Panel();
        ps7.setBackground(Color.orange);
	Panel ps8 = new Panel();
        ps8.setBackground(Color.black);


	CheckboxGroup chgroup1 = new CheckboxGroup();
	//ch1 = new Checkbox("  place -ve charge",true,chgroup1);
        ch2 = new Checkbox("  add charge",true,chgroup1);
        ch3 = new Checkbox("  edit charge value",false,chgroup1);
        ch4 = new Checkbox("  delete charge",false,chgroup1);
        ch5 = new Checkbox("  drag charge",false,chgroup1);
        ch6 = new Checkbox("  display electric field",false,chgroup1);
        Label labch6 = new Label("     and voltage at cursor:");
	
        //ch1.setForeground(Color.black);
        //ch1.setFont(state.ttfFont.deriveFont(14f));
	ch2.setForeground(Color.black);
        ch2.setFont(labelfont);
	ch3.setForeground(Color.black);
        ch3.setFont(labelfont);
	ch4.setForeground(Color.black);
        ch4.setFont(labelfont);
	ch5.setForeground(Color.black);
        ch5.setFont(labelfont);
	ch6.setForeground(Color.black);
        ch6.setFont(labelfont);
        labch6.setFont(labelfont);
        
	//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 value: ",Label.RIGHT);
        labc.setFont(labelfont);
        labc.setForeground(Color.black);
	labv = new Label("V =  ",Label.RIGHT);
        labv.setFont(labelfont);
        labv.setForeground(Color.black);
	labe = new Label("E =  ",Label.RIGHT);
        labe.setFont(labelfont);
        labe.setForeground(Color.black);
        textc = new TextField(6);
        textc.setFont(labelfont);
        textc.setForeground(Color.black);
	textc.setText(""+dec.format(state.chargeToAdd));

        textv = new TextField(6);
        textv.setFont(labelfont);
        textv.setForeground(Color.black);
	textv.setText("");
	textv.setEditable(false);
        texte = new TextField(8);
        texte.setFont(labelfont);
        texte.setForeground(Color.black);
	texte.setText("");
	texte.setEditable(false);

	ulabc = new Label("e ",Label.LEFT);
        ulabc.setFont(labelfont);
	ulabv = new Label("nVolts ",Label.LEFT);
        ulabv.setFont(labelfont);
	ulabe = new Label("nV/m ",Label.LEFT);
        ulabe.setFont(labelfont);
	sliderc = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,ScrollMax+1);
	//sliderc.setValue((int)((state.chargeToAdd-state.chargeMin)*
        //                       ScrollMax/(state.chargeMax-state.chargeMin)));
        sliderdv = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,15);


        Panel ps1 = new Panel();
        ps1.setBackground(Color.orange);
        //add(ps1);
        Panel ps10 = new Panel();
        ps10.setBackground(Color.black);
        //add(ps10);

        Panel ps2 = new Panel();
        ps2.setBackground(Color.orange);
        //add(ps2);
        Panel ps11 = new Panel();
        ps11.setBackground(Color.orange);
        //add(ps11);



        Label plusLabel = new Label("more");
        Label plusLabel2 = new Label("lines");
        Label minusLabel = new Label("less");
        Label minusLabel2 = new Label("lines");

        sa = new ShowAngle(state);

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

        ch01.setForeground(Color.black);
        ch01.setFont(labelfont);
        ch02.setForeground(Color.black);
        ch02.setFont(labelfont);
        ch03.setForeground(Color.black);
        ch03.setFont(labelfont);
	ch01.setBackground(bgcolor);
	ch02.setBackground(bgcolor);
	ch03.setBackground(bgcolor);


        // ADD the components:

	add(labc);
	add(textc);
	add(sliderc);
        add(sliderdv);  //NEW  (ordering)

        add(ps1);       // NEW (ordering)
        add(ps10);
        add(ps2);
        add(ps11);

	add(ulabc);
        add(labv);
        add(textv);
        add(ulabv);
        add(labe);
        add(texte);
        add(ulabe);

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

        add(sa);

	add(titlelabel);

        add(reset);
        add(ps7);
        add(ps8);

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

	add(ch01);
	add(ch02);
	add(ch03);

        // End of adding components:

        getLabelWidths();

        // NOW position components:

	int vPosInit = 60, vPos, dvPos = 4, vHeight = 20; 
	vPos = vPosInit;
        // column = 240
        int col = 20;
        
	//labc.setBounds(col+20,vPos,80,vHeight);
	//textc.setBounds(col+100,vPos,80,vHeight);
	//ulabc.setBounds(col+180,vPos,80,vHeight);
	labc.setBounds(col+20,vPos,100,vHeight);
	textc.setBounds(col+120,vPos,80,vHeight);
	ulabc.setBounds(col+200,vPos,80,vHeight);
	
	    vPos += vHeight + dvPos; 

	sliderc.setBounds(col+22,vPos+2,196,vHeight);
        //Panel ps1 = new Panel();
        //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);

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

        int column1 = 40;
        //int column2 = 240;
        int column2 = 200;
        //int startingY = 40;
        int deltaY = 25;
        int startingY = 40 + 3*deltaY;
        int h = 20;
	//ch1.setBounds(column1,startingY,w1,h);
	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+160;
        newCol = column1+180;
        
        sa.setBounds(newCol,startingY+6*deltaY+20,40,40);

        yLine = startingY+9*deltaY + 8;

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

        /*
        //sliderdv.setBounds(column1+180,startingY+12*deltaY-12,15,75);
        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+14*deltaY + 15;
        sliderdv.setBounds(column1+50,yLine2,140,15);
        //Panel ps2 = new Panel();
        //ps2.setVisible(false);
        //add(ps2);
        ps2.setBounds(column1+49,yLine2-1,142,17);

        //Panel ps11 = new Panel();
        //ps11.setVisible(false);
        //add(ps11);
        ps11.setBounds(column1+48,yLine2-2,144,19);

        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;
        int y_update = 535; //4-14
	reset.setBounds(120,y_update,60,20);

	//Panel ps7 = new Panel();
        //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);



        // NEW place for the setting the value of the sliders:

	sliderc.setValue((int)((state.chargeToAdd-state.chargeMin)*
                               ScrollMax/(state.chargeMax-state.chargeMin)));
        sliderdv.setValue(7);

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


    private void getLabelWidths() {
        //setFont(state.ttfFont.deriveFont(14f));
        setFont(labelfont);
        //Graphics g=getGraphics();
        //FontMetrics fm = g.getFontMetrics();
        FontMetrics fm = getFontMetrics(getFont());
        int extra = fm.stringWidth("gegegege");
        w2 = fm.stringWidth("add charge")+extra;
        w3 = fm.stringWidth("edit charge value")+extra;
        w4 = fm.stringWidth("delete charge")+extra;
        w5 = fm.stringWidth("drag charge")+extra;
        w6 = fm.stringWidth("display electric field")+extra;

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

    private void getCursorStuffWidths() {
        //setFont(state.ttfFont.deriveFont(14f));
        setFont(labelfont);
        //Graphics g=getGraphics();
        //FontMetrics fm = g.getFontMetrics();
        FontMetrics fm = getFontMetrics(getFont());
        int extra = fm.stringWidth("gege");
        wv1 = fm.stringWidth("v = ")+extra;
        wv2 = fm.stringWidth("nVolts")+extra;
        we1 = fm.stringWidth("E = ")+extra;
        we2 = fm.stringWidth("nV/m")+extra;
        //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));
        sa.draw();
        return;
    }


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

        try { 
            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);
            }
            //ignoreNextAdjustmentEvent = true;
        } catch(NumberFormatException e){
            charge =  0.0;
        }
        state.chargeToAdd = charge;
        //if (ch2.getState()) state.chargeToAdd = charge;
        //else if (chxx.getState()) state.chargeChangeValue = charge;
    }


    
    public void adjustmentValueChanged(AdjustmentEvent evt){//NEED HERE
        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));
            //ignoreNextTextEvent = true;
        } else if (evt.getSource()==sliderdv) {
            if (sliderdv.getValue() >= 15) {
                state.deltaV = 14;
                sliderdv.setValue(14);
            } else if (sliderdv.getValue() < 0) {
                state.deltaV = 0;
                sliderdv.setValue(0);
            } else {
                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 reset() {
        ch2.setState(true);   // set to "Place Charge"
        ch01.setState(false);
        ch02.setState(false);
        ch03.setState(false);
        state.displayPotentialField = false;
        state.displayEquiPotentialLines = false;
        state.displayElectricField = false;        
        state.voltageAtCursor = 0.0;
        state.efieldAtCursor = 0.0; 
        textv.setText("0");
        texte.setText("0");
        state.chargeToAdd = state.chargeMax;
	textc.setText(""+dec.format(state.chargeToAdd));
	sliderc.setValue((int)((state.chargeToAdd-state.chargeMin)*
                               ScrollMax/(state.chargeMax-state.chargeMin)));
        sliderdv.setValue(7);
        sa.reset();
    }


    public void clearShowVoltageStuff() {
        textv.setText("0");
        texte.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.bold16);
        //g.drawLine(5,yLine,455,yLine);
        g.setFont(TheFonts.bold14);
        g.drawString("Plot Characteristics:",40,yLine+40);
    }
}
