import java.awt.*;
import java.awt.event.*;
import java.applet.*;
//import java.lang.*;

public class InputPanel extends Panel implements ActionListener, AdjustmentListener, ItemListener{
        PlaneWave_State state;
        
	protected static final Color bgcolor = new Color(246,246,246);
	protected TextField text1[];
	protected Label lab1[], lab2[];
	public Label titlelabel;
	public Button b1, about;
        private Image im;
        private Graphics buf;
        public Scrollbar slider1,sliderx0, slidery0;
        public Scrollbar slidervx0, slidervy0;
        public Scrollbar slidermass, slidercharge;
        public Scrollbar sliderEx, sliderEy;
        public Scrollbar sliderHz;
        public Scrollbar sliderTime1, sliderTime2;
        
        public Checkbox c1, c2, c3, c_trace, c_field;
        public CheckboxGroup cgrid;
        
        public Checkbox c_open, c_closed;
        public CheckboxGroup cbound;
        
        public int SCROLLMIN=750, SCROLLMAX=1001;
        public int SCROLLMIN2=0, SCROLLMAX2=20001;
        public int SCROLLMIN3=0, SCROLLMAX3=1001;
        
        // CHANGE ==============================================================
        public Button b2a, b2b, b3a, b3b, b4a, b4b;
        //======================================================================
        
        private int SleepTime = 50;
        
	protected String titulo="Unknown Title";
	protected String[] nome;
	protected String[] unidade;
	protected static final Font labfont=new Font("SanSerif",Font.PLAIN,12);
	protected static final Font titlefont=new Font("SanSerif",Font.BOLD,16);
        protected double[] DValue;
	protected int indexsize = 9;
	
	//public InputPanel(String[] nome, String[] unidade){
	public InputPanel(PlaneWave_State state){
		super();
		setLayout(null);
                this.state = state;
                
		DValue=new double[indexsize];
		text1=new TextField[indexsize];
		int i;
		
                for(i=0;i<indexsize;i++){
			this.DValue[i]=0.0;
			this.text1[i]=new TextField("0.0",8);
		}
		
		setBackground(bgcolor);
                
                int startx = 184;
                int starty = 40;
                int textwidth = 60;
                int textheight = 20;
                int yplus = 25;
                
                text1[0].setBounds(startx,starty,textwidth,textheight);
		//add(text1[0]);
                
                starty += yplus;
                text1[1].setBounds(startx,starty,textwidth,textheight);
		//add(text1[1]);
                
                starty += yplus;
                text1[2].setBounds(startx,starty,textwidth,textheight);
		//add(text1[2]);
                
                starty += yplus;
                text1[3].setBounds(startx,starty,textwidth,textheight);
		//add(text1[3]);
                
                starty += yplus;
                text1[4].setBounds(startx,starty,textwidth,textheight);
		//add(text1[4]);
                
                starty += yplus;
                text1[5].setBounds(startx,starty,textwidth,textheight);
		//add(text1[5]);

                starty += yplus;
                text1[6].setBounds(startx,starty,textwidth,textheight);
		//add(text1[6]);
                
                starty += yplus;
                //text1[7].setBounds(startx,starty,textwidth,textheight);
		//add(text1[7]);
                
                starty += yplus+93;
		about = new Button("Instructions");
		about.setBackground(Color.white);
		about.setBounds(startx,376,100,textheight);
                add(about);
                
                c_field=new Checkbox("Show Fields",true);
                add(c_field);
		c_field.setFont(new Font("SanSerif",Font.PLAIN,12));
		c_field.setBackground(bgcolor);
		c_field.setForeground(Color.red.darker());
		c_field.setBounds(90,5,100,20);
                c_field.setVisible(true);
                
                c_trace=new Checkbox("Show Trace",false);
                add(c_trace);
		c_trace.setFont(new Font("SanSerif",Font.PLAIN,12));
		c_trace.setBackground(bgcolor);
		c_trace.setForeground(Color.red.darker());
		c_trace.setBounds(200,5,100,20);
                c_trace.setVisible(true);
                
                
                cgrid = new CheckboxGroup();
                c1=new Checkbox("electron",cgrid,true);
                c2=new Checkbox("proton",cgrid,false);
                c3=new Checkbox("neutron",cgrid,false);
                
                //add(c1); // electron
		c1.setFont(new Font("SanSerif",Font.PLAIN,12));
		c1.setBackground(bgcolor);
		c1.setForeground(Color.red.darker());
		c1.setBounds(20,165,80,20);
                c1.setVisible(true);
                
                //add(c2); // proton
		c2.setFont(new Font("SanSerif",Font.PLAIN,12));
		c2.setBackground(bgcolor);
		c2.setForeground(Color.magenta.darker());
                c2.setBounds(120,165,80,20);
                c2.setVisible(true);
                
                //add(c3); // neutron
		c3.setFont(new Font("SanSerif",Font.PLAIN,12));
		c3.setBackground(bgcolor);
		c3.setForeground(Color.black);
		c3.setBounds(220,165,80,20);
                c3.setVisible(true);
             
                cbound = new CheckboxGroup();
                c_open = new Checkbox("open boundary",cbound,false);
                c_closed = new Checkbox("closed boundary",cbound,true);
                
                add(c_closed);
		c_closed.setFont(new Font("SanSerif",Font.PLAIN,12));
		c_closed.setBackground(bgcolor);
		c_closed.setForeground(Color.red.darker());
                c_closed.setBounds(170,240,150,20);
                c_closed.setVisible(true);
                
                add(c_open);
		c_open.setFont(new Font("SanSerif",Font.PLAIN,12));
		c_open.setBackground(bgcolor);
		c_open.setForeground(Color.red.darker());
		c_open.setBounds(170,260,150,20);
                c_open.setVisible(true);
                
                // Animation speed slider
                slider1 = new Scrollbar(Scrollbar.HORIZONTAL,SCROLLMAX-1-SleepTime,1,SCROLLMIN,SCROLLMAX);
                slider1.setBounds(12,378,150,15);
                slider1.setBackground(Color.white);
                add(slider1);
                Panel p1 = new Panel();
                    p1.setBackground(Color.black);
                    add(p1);
                    p1.setBounds(11,377,152,17);
                
                sliderx0 = new Scrollbar(Scrollbar.HORIZONTAL,(SCROLLMAX2-1)/2,1,SCROLLMIN2,SCROLLMAX2);
                sliderx0.setBounds(12,50,120,15);
                sliderx0.setBackground(Color.white);
                add(sliderx0);
                Panel px = new Panel();
                    px.setBackground(Color.black);
                    add(px);
                    px.setBounds(11,49,122,17);
                
                slidery0 = new Scrollbar(Scrollbar.HORIZONTAL,(SCROLLMAX2-1)/2,1,SCROLLMIN2,SCROLLMAX2);
                slidery0.setBounds(162,50,120,15);
                slidery0.setBackground(Color.white);
                add(slidery0);
                Panel py = new Panel();
                    py.setBackground(Color.black);
                    add(py);
                    py.setBounds(161,49,122,17);
                
                slidervx0 = new Scrollbar(Scrollbar.HORIZONTAL,(SCROLLMAX2-1)/2+1000,1,SCROLLMIN2,SCROLLMAX2);
                slidervx0.setBounds(12,95,120,15);
                slidervx0.setBackground(Color.white);
                add(slidervx0);
                Panel pvx = new Panel();
                    pvx.setBackground(Color.black);
                    add(pvx);
                    pvx.setBounds(11,94,122,17);
                
                slidervy0 = new Scrollbar(Scrollbar.HORIZONTAL,(SCROLLMAX2-1)/2+1000,1,SCROLLMIN2,SCROLLMAX2);
                slidervy0.setBounds(162,95,120,15);
                slidervy0.setBackground(Color.white);
                add(slidervy0);
                Panel pvy = new Panel();
                    pvy.setBackground(Color.black);
                    add(pvy);
                    pvy.setBounds(161,94,122,17);
                
                slidermass = new Scrollbar(Scrollbar.HORIZONTAL,1,1,1,11);
                slidermass.setBounds(12,140,120,15);
                slidermass.setBackground(Color.white);
                //add(slidermass);
                Panel pvm = new Panel();
                    pvm.setBackground(Color.black);
                    //add(pvm);
                    pvm.setBounds(11,139,122,17);
                
                slidercharge = new Scrollbar(Scrollbar.HORIZONTAL,(21-1)/2-1,1,0,21);
                slidercharge.setBounds(162,140,120,15);
                slidercharge.setBackground(Color.white);
                //add(slidercharge);
                Panel pvc = new Panel();
                    pvc.setBackground(Color.black);
                    //add(pvc);
                    pvc.setBounds(161,139,122,17);
                    
                // CHANGE  =====================================================
                b2a = new Button("<");
                b2a.setBackground(bgcolor);        
                b2b = new Button(">");
                b2b.setBackground(bgcolor);
                b3a = new Button("<");
                b3a.setBackground(bgcolor);
                b3b = new Button(">");
                b3b.setBackground(bgcolor);
                b4a = new Button("<");
                b4a.setBackground(bgcolor);
                b4b = new Button(">");
                b4b.setBackground(bgcolor);
                add(b2a); add(b2b); add(b3a); add(b3b); add(b4a); add(b4b);
                //==============================================================
                
                // CHANGE  =====================================================
                b2a.setBounds(12,215,14,15);
                b2b.setBounds(118,215,14,15);
                b3a.setBounds(162,215,14,15);
                b3b.setBounds(268,215,14,15);
                b4a.setBounds(12,260,14,15);
                b4b.setBounds(118,260,14,15);
                //==============================================================
        
                sliderEx = new Scrollbar(Scrollbar.HORIZONTAL,(SCROLLMAX3-1)/2+100,1,SCROLLMIN3,SCROLLMAX3);
                sliderEx.setBounds(12,215,120,15);
                sliderEx.setBackground(Color.white);
                add(sliderEx);
                Panel pEx = new Panel();
                    pEx.setBackground(Color.red);
                    add(pEx);
                    pEx.setBounds(11,214,122,17);
                
                sliderEy = new Scrollbar(Scrollbar.HORIZONTAL,(SCROLLMAX3-1)/2+100,1,SCROLLMIN3,SCROLLMAX3);
                sliderEy.setBounds(162,215,120,15);
                sliderEy.setBackground(Color.white);
                add(sliderEy);
                Panel pEy = new Panel();
                    pEy.setBackground(Color.red);
                    add(pEy);
                    pEy.setBounds(161,214,122,17);
                
                sliderHz = new Scrollbar(Scrollbar.HORIZONTAL,(SCROLLMAX3-1)/2+100,1,SCROLLMIN3,SCROLLMAX3);
                sliderHz.setBounds(12,260,120,15);
                sliderHz.setBackground(Color.white);
                add(sliderHz);
                Panel pHz = new Panel();
                    pHz.setBackground(Color.blue);
                    add(pHz);
                    pHz.setBounds(11,259,122,17);
                    
                sliderTime1 = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,90);
                sliderTime1.setBounds(12,295,120,15);
                sliderTime1.setBackground(Color.white);
                add(sliderTime1);
                Panel pT1 = new Panel();
                    pT1.setBackground(Color.green);
                    add(pT1);
                    pT1.setBounds(11,294,122,17);
                
                sliderTime2 = new Scrollbar(Scrollbar.HORIZONTAL,12,1,1,21);
                sliderTime2.setBounds(12,313,120,15);
                sliderTime2.setBackground(Color.white);
                add(sliderTime2);
                Panel pT2 = new Panel();
                    pT2.setBackground(Color.green);
                    add(pT2);
                    pT2.setBounds(11,312,122,17);
                    
                // draw line with panel to avoid flicker
                    Panel pLine = new Panel();
                    pLine.setBackground(Color.black);
                    add(pLine);
                    pLine.setBounds(0,187,306,1);
                    
                //Listeners
		about.addActionListener(this);
                c1.addItemListener(this);
                c2.addItemListener(this);
                c3.addItemListener(this);
                c_open.addItemListener(this);
                c_closed.addItemListener(this);
                sliderx0.addAdjustmentListener(this);
                slidery0.addAdjustmentListener(this);
                slidervx0.addAdjustmentListener(this);
                slidervy0.addAdjustmentListener(this);
                slidermass.addAdjustmentListener(this);
                slidercharge.addAdjustmentListener(this);
                sliderEx.addAdjustmentListener(this);
                sliderEy.addAdjustmentListener(this);
                sliderHz.addAdjustmentListener(this);
                sliderTime1.addAdjustmentListener(this);
                sliderTime2.addAdjustmentListener(this);
                
                // CHANGE ======================================================
                b2a.addActionListener(this);
                b2b.addActionListener(this);
                b3a.addActionListener(this);
                b3b.addActionListener(this);
                b4a.addActionListener(this);
                b4b.addActionListener(this);
                //==============================================================
        
	}
	
        @Override
        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 drawCanvas(Graphics g){
            
            Graphics2D g2d = (Graphics2D)g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            
	    g.clearRect(0,0,getSize().width-2,getSize().height);
	                
            int startx = 12;
            int starty = 40;
            int yplus = 25;         // y step down
            
            g.setColor(Color.gray);
            MaestroG.subscripterBold("Input","","",g,14,startx+1,startx+6);
            g.setColor(Color.red.darker());
            MaestroG.subscripterBold("Input","","",g,14,startx,startx+5);
            
            g.setColor(Color.blue.darker());
            //MaestroG.subscripter("Initial Position","","",g,12,startx,starty);
            MaestroG.subscripter("x","0"," = "+MaestroA.rounder(state.xpos_0,4)+" [ m ]",g,12,startx,starty);
            MaestroG.subscripter("y","0"," = "+MaestroA.rounder(state.ypos_0,4)+" [ m ]",g,12,startx+150,starty);
            
            starty = 85;
            MaestroG.subsup("u","x 0"," = "+MaestroA.rounder(state.vx_0,4)+" x 10","5","m/s",g,12,startx,starty);
            MaestroG.subsup("u","y 0"," = "+MaestroA.rounder(state.vy_0,4)+" x 10","5","m/s",g,12,startx+150,starty);
            
            g.setColor(Color.black);
            g.drawLine(0,120,getSize().width,120);
            
            starty = 157;
            
            if(state.particle == 1){
                g.setColor(Color.red.darker());
                MaestroG.subscripter("Electron","","",g,12,startx+10,starty-20);
                MaestroG.superscripter("mass = 9.10938188 x 10","-31"," [ Kg ]",g,12,startx+10,starty);
                MaestroG.superscripter("charge = - 1.60217646 x 10","-19"," [ C ] ",g,12,startx+10,starty+20);
            }
            else if(state.particle == 2){
                g.setColor(Color.magenta.darker());
                MaestroG.superscripter("mass = 1.67262158 x 10","-27"," [ Kg ]",g,12,startx+10,starty);
                MaestroG.superscripter("charge = 1.60217646 x 10","-19"," [ C ] ",g,12,startx+10,starty+20);
            }
            if(state.particle == 3){
                g.setColor(Color.black);
                MaestroG.superscripter("mass = 1.67492729 x 10","-27"," [ Kg ]",g,12,startx+10,starty);
                MaestroG.superscripter("charge = 0.0",""," [ C ] ",g,12,startx+10,starty+20);
            }
            
            g.setColor(Color.black);
            //g.drawLine(0,187,getSize().width,187);
            
            g.setColor(Color.red);
            starty = 205;
            MaestroG.subscripter("E","x"," = "+MaestroA.rounder(state.Ex,4)+" [ V /m ]",g,12,startx+10,starty);
            MaestroG.subscripter("E","y"," = "+MaestroA.rounder(state.Ey,4)+" [ V /m ]",g,12,startx+160,starty);
            
            g.setColor(Color.blue);
            starty = 250;
            MaestroG.subscripter("H","z"," = "+MaestroA.rounder(state.Hz,4)+" [ A /m ]",g,12,startx+10,starty);
            
            g.setColor(Color.black);
            g.drawLine(0,285,getSize().width,285);
            
            g.setColor(Color.green.darker());
            starty = 305;
            MaestroG.subscripter("Time step","","",g,12,startx+145,starty);
            
            starty = 320;
            MaestroG.superscripter("\u0394 t = "+MaestroA.rounder(1.0+(double)sliderTime1.getValue()*0.1,2)+ 
                    " x 10","-"+(int)(21.0-(double)sliderTime2.getValue())," [s]",g,13,startx+145,starty);
            
            g.setColor(Color.blue.darker());
            MaestroG.subscripter("Maximum recommended time step","","",g,12,20,345);
            //MaestroG.subscripter("dt = "+state.dt_suggested,"","",g,12,20,350);
            
            
            MaestroG.superscripter("\u0394 t = "+state.mantissa+" x 10",""+state.exponent," [s]",g,13,20,363);
            
            
            int textwidth = 80;
            int textheight = 20;
            
            starty = 10*yplus+85;
            startx = 180;
               //box around update button
            g.drawRect(startx+1,373,104,textheight+5);
            //------------------------------------------------------------------
            g.setColor(Color.black);
            MaestroG.subscripter("Animation speed","","",g,10,45,405);
            
            g.setColor(Color.blue.darker());
            MaestroG.drawArrowtip(20,400,8,g);
            MaestroG.drawArrowtip(27,400,8,g);

            g.setColor(Color.red.darker());
            MaestroG.drawArrowtip(147,400,7,g);
            MaestroG.drawArrowtip(154,400,7,g);
            //------------------------------------------------------------------
        }
    
        public void adjustmentValueChanged(AdjustmentEvent evt){
	
            if(evt.getSource()==sliderx0){
                state.xpos_0 = MaestroA.rounder(state.Deltax*((double)sliderx0.getValue()-(double)(SCROLLMAX2-1)/2.0),5);
                state.xpos = state.xpos_0;
                state.xpos_old = state.xpos_0;
                state.ypos = state.ypos_0;
                state.ypos_old = state.ypos_0;
                state.ignition();
                repaint();
            }
            if(evt.getSource()==slidery0){
                state.ypos_0 = MaestroA.rounder(state.Deltax*((double)slidery0.getValue()-(double)(SCROLLMAX2-1)/2),5);
                state.ypos = state.ypos_0;
                state.ypos_old = state.ypos_0;
                state.xpos = state.xpos_0;
                state.xpos_old = state.xpos_0;
                state.ignition();
                repaint();
            }
            
            if(evt.getSource()==slidervx0){
                state.vx_0 = MaestroA.rounder(state.Deltavx*((double)slidervx0.getValue()-(double)(SCROLLMAX2-1)/2.0),5);
                state.vx = state.vx_0;
                state.vx_old = state.vx_0;
                state.ignition();
                repaint();
            }
            if(evt.getSource()==slidervy0){
                state.vy_0 = MaestroA.rounder(state.Deltavx*((double)slidervy0.getValue()-(double)(SCROLLMAX2-1)/2),5);
                state.vy = state.vy_0;
                state.vy_old = state.vy_0;
                state.ignition();
                repaint();
            }
            
            if(evt.getSource()==slidermass){
                state.mass = MaestroA.rounder(((double)slidermass.getValue()),2);
                state.ignition();
                repaint();
            }
            if(evt.getSource()==slidercharge){
                state.charge = MaestroA.rounder(((double)slidercharge.getValue()-(double)(21-1)/2),5);
                state.ignition();
                repaint();
            }
            
            if(evt.getSource()==sliderEx){
                state.Ex = 0.01*MaestroA.rounder(((double)sliderEx.getValue()-(double)(SCROLLMAX3-1)/2),5);
                state.ignition();
                repaint();
            }
            if(evt.getSource()==sliderEy){
                state.Ey = 0.01*MaestroA.rounder(((double)sliderEy.getValue()-(double)(SCROLLMAX3-1)/2),5);
                state.ignition();
                repaint();
            }
            if(evt.getSource()==sliderHz){
                state.Hz = 0.01*MaestroA.rounder(((double)sliderHz.getValue()-(double)(SCROLLMAX3-1)/2),5);
                state.ignition();
                repaint();
            }
            
            if(evt.getSource()==sliderTime1){
                state.dt = MaestroA.rounder(1.0+(double)sliderTime1.getValue()*0.1,5)
                           * Math.pow(10.0,-(21.0-(double)sliderTime2.getValue()));
                state.ignition();
                repaint();
            }
            if(evt.getSource()==sliderTime2){
                state.dt = MaestroA.rounder(1.0+(double)sliderTime1.getValue()*0.1,5)
                           * Math.pow(10.0,-(21.0-(double)sliderTime2.getValue()));
                state.ignition();
                repaint();
            }
        }
        
        public void itemStateChanged(ItemEvent evt){
	    ItemSelectable ie = evt.getItemSelectable();
            if(evt.getSource() == c1){
		  state.particle = 1;
                  repaint();
            }
                
            else if(evt.getSource() == c2){
		  state.particle = 2;
                  repaint();
            }
                
            else if(evt.getSource() == c3){
		  state.particle = 3;
                  repaint();
            }
            
            if(evt.getSource() == c_open){
		  state.IsOpen = true;
                  repaint();
            }
            else if(evt.getSource() == c_closed){
		  state.IsOpen = false;
                  repaint();
            }
        }	
    
        	
	public void actionPerformed(ActionEvent evt){
		if(evt.getSource() == b1){//  not used
		  for(int i=0;i<indexsize;i++){
		  	DValue[i]=Double.valueOf(text1[i].getText()).doubleValue();
                  }
		}
                if(evt.getSource()==b2a){
                    sliderEx.setValue(sliderEx.getValue()-1);
                    state.Ex = 0.01*MaestroA.rounder(((double)sliderEx.getValue()-(double)(SCROLLMAX3-1)/2),5);
                    state.ignition();
                    repaint();
                }
                if(evt.getSource()==b2b){
                    sliderEx.setValue(sliderEx.getValue()+1);
                    state.Ex = 0.01*MaestroA.rounder(((double)sliderEx.getValue()-(double)(SCROLLMAX3-1)/2),5);
                    state.ignition();
                    repaint();
                }
                if(evt.getSource()==b3a){
                    sliderEy.setValue(sliderEy.getValue()-1);
                    state.Ey = 0.01*MaestroA.rounder(((double)sliderEy.getValue()-(double)(SCROLLMAX3-1)/2),5);
                    state.ignition();
                    repaint();
                }
                if(evt.getSource()==b3b){
                    sliderEy.setValue(sliderEy.getValue()+1);
                    state.Ey = 0.01*MaestroA.rounder(((double)sliderEy.getValue()-(double)(SCROLLMAX3-1)/2),5);
                    state.ignition();
                    repaint();
                }
                if(evt.getSource()==b4a){
                    sliderHz.setValue(sliderHz.getValue()-1);
                    state.Hz = 0.01*MaestroA.rounder(((double)sliderHz.getValue()-(double)(SCROLLMAX3-1)/2),5);
                    state.ignition();
                    repaint();
                }
                if(evt.getSource()==b4b){
                    sliderHz.setValue(sliderHz.getValue()+1);
                    state.Hz = 0.01*MaestroA.rounder(((double)sliderHz.getValue()-(double)(SCROLLMAX3-1)/2),5);
                    state.ignition();
                    repaint();
                }
	}
	
        public double getValue(int i){
		return DValue[i];	
        }

        public synchronized void setValue(double D,int i){
		text1[i].setText(String.valueOf(D));
	}
}

