import java.applet.Applet;
import java.awt.*;
//import OsmosisCanvas;
//import gjt.*;

/*
 *
 * Osmosis
 *
 */
public class OsmPressure8 extends Nernst {
	int Particles[] = {0,2,5,10,20,30};
    Button Rst;
    OsmPressureReportPanel8 pReport;
    OsmPressureControlPanel8 pControl;
    //OsmCanvas CDiff;
    Panel p;
    GraphCanvas8 c;
    int PLOT_AV=0, PLOT_REAL=0, PLT=0, Sum, i, j, N, ERR=0, n, is=0, is1=0, X[]= new int[10], Y[]= new int[10], ys[]= new int[600], zs[]=new int[600];
    double xs[] = new double[600], min, max;
    float X1, Y1, SX, SY, SXY, SX2, a, b;
    Thread t;
    boolean prun=false, rst=false, first=true;
	int NewNum = -1;
    public void init() {
		Panel pnl=new Panel();
		CDiff=new OsmPCanvas(this);
        //setLayout(new BorderLayout()); //
        //add("Center",CDiff);         //
        Panel pnl2=new Panel();
        tdbDisplay=new ThreeDBorder(pnl2,5);
        pnl2.setLayout(new BorderLayout());
        pnl2.add("Center",CDiff);
        pnl2.add("East", OutBar);

        //tdbDisplay=new ThreeDBorder(CDiff,5);
        //tdbDisplay.inset();
        pReport=new OsmPressureReportPanel8(this);
        pControl=new OsmPressureControlPanel8(this);
        setLayout(new BorderLayout());
        add("Center",new ThreeDBorder(pnl));
        pnl.setLayout(new BorderLayout());
        Panel pnl3=new Panel();
        pnl3.setLayout(new BorderLayout());
        pnl3.add("North", pReport);
        pnl3.add("Center",CDiff);
        pnl3.add("South", pControl);
//           c = new GraphCanvas8(this);
//           c.resize(300,300);
        pnl.add("Center", pnl3);
	}
//           pnl.add("East", c);
//           t= new PThread(this);
//           t.start();
//           t.suspend();
	public boolean action(Event event, Object what) {
		if(event.target==Start_Stop){
			if (running){
				if (NewNum > -1) {
					CDiff.stop();
					OutBar.stop();
				}
				running=false;
                Start_Stop.setLabel("Start");
                Plot.setLabel("StartPlot");
                if(prun) {
					prun=false;
				}
			}
			else {
				if (NewNum > -1) {
					CDiff.start();
					OutBar.start();
				}
                running=true;
                Start_Stop.setLabel("Stop");
			}
		}
		else if (event.target==Num_Particles){
			NewNum= Num_Particles.getSelectedIndex() < 6 ? Particles[Num_Particles.getSelectedIndex()] : NewNum;
            if (running) CDiff.stop();
            ((OsmPCanvas)CDiff).OutIon=NewNum;
            ((OsmPCanvas)CDiff).OutWater=150-(((OsmPCanvas)CDiff).Hydration+1)*NewNum;
            CDiff.init();
            if (running) CDiff.start();
		}
		else if (event.target==Plot){
			if(prun) {
				prun=false;
				Plot.setLabel("StartPlot");
			}
			else {
				if(first){
					first=false;
				}
				prun=true;
				Plot.setLabel("StopPlot");
			}
		}
		else if (event.target==Plot2){
			PLOT_REAL=1;
            c.repaint();
		}
		else if (event.target==Rst){
			if (running){
				CDiff.stop();
			}
			if(prun) {
//                                t.suspend();
			}
			rst=true;
            CDiff.init();
            is=0;
//                        for(i=0;i<7;i++){
//                                lines[i][0] = 0;
//                        }
            c.Str0=" ";
            c.Str1=" ";
            c.Str2=" ";
            c.repaint();
            if (running){
				CDiff.start();
			}
		}
		else if (event.target==Fit){
			N=0;
            for(i=0;i<6;i++){
				n=0; Sum=0;
				for(j=0;j<is;j++){
					if((10-Particles[i])==xs[j]){
						if(zs[j]==2){
							Sum=Sum+ys[j];
							n++;
						}
					}
				}
				if(n > 0){
					N++;
                    X[N]=10-Particles[i];
                    Y[N]=Sum/n;
				}
			}
			if (is < 2){
				ERR=1;
			}
			else{
				SX=0;
                SY=0;
                SXY=0;
                SX2=0;
                min=100000;
                max=-10000;
				for (i=0;i<is;i++){
					if(xs[i]>max) max=xs[i];
					if(xs[i]<min) min=xs[i];
                    SX=(float)(SX+xs[i]);
                    SY=(float)(SY+ys[i]);
                    SXY=(float)(SXY+xs[i]*ys[i]);
                    SX2=(float)(SX2+xs[i]*xs[i]);
                    //     SY2=SY2+Y[i]*Y[i];
				}
				X1=(float)SX/(float)is;
                Y1=(float)SY/(float)is;
                b=((float)SXY-(float)is*X1*Y1)/((float)SX2-(float)is*X1*X1);
                a=Y1-b*X1;
                PLT=1;
			}
			c.repaint();
		}
		return true;
	}
}


class OsmPressureReportPanel8 extends Panel{
        OsmPressure8 app;

        public OsmPressureReportPanel8(Applet applet){
                app=(OsmPressure8)applet;
                Label l_Vol_i=new Label("Vol.",Label.CENTER);
                Label l_Conc_i=new Label("Conc.",Label.CENTER);
                Label l_Vol_o=new Label("Vol.",Label.CENTER);
                Label l_Conc_o=new Label("Conc.",Label.CENTER);
                Label l_Voltage=new Label("Real",Label.CENTER);
                Label l_Average=new Label("Aver.",Label.CENTER);

                Panel pIn=new Panel();
                Label inside=new Label("Inside",Label.CENTER);
                app.bInside= new RBox(pIn,inside);
                pIn.setLayout(new GridLayout(2,2,2,0));
                pIn.add(l_Vol_i);
                pIn.add(l_Conc_i);
                pIn.add(app.CDiff.R_in);
                pIn.add(app.CDiff.B_in);

                Panel pOut=new Panel();
                Label outside=new Label("Outside",Label.CENTER);
                app.bOutside= new RBox(pOut,outside);
                pOut.setLayout(new GridLayout(2,2,2,0));
                pOut.add(l_Vol_o);
                pOut.add(l_Conc_o);
                pOut.add(app.CDiff.R_out);
                pOut.add(app.CDiff.B_out); 

                Panel pVoltage=new Panel();
                Label Volt=new Label("Pressure",Label.CENTER);
                app.bVoltage= new RBox(pVoltage,Volt);
                pVoltage.setLayout(new GridLayout(2,2,2,0));
                pVoltage.add(l_Voltage);
                pVoltage.add(l_Average);
                pVoltage.add(app.CDiff.Voltage);
                pVoltage.add(app.CDiff.Average);

             //   app.bInside.resize(90,5);
             //   app.bVoltage.resize(90,5);
             //   app.bOutside.resize(90,5);
                
              //  app.bVoltage= new RBox(app.CDiff.Voltage,"Pressure");
              //  app.bAverage= new RBox(app.CDiff.Average,"Average");
               setLayout(new GridLayout(1,3,0,0));

                add(new ThreeDBorder(app.bInside));
                add(new ThreeDBorder(app.bVoltage));
                add(new ThreeDBorder(app.bOutside));
                super.resize(300,5);
        }

        public Insets insets(){
                return new Insets(5,5,5,5);
        }

}

class OsmPressureControlPanel8 extends Panel{

       OsmPressure8 app;

        public OsmPressureControlPanel8(Applet applet){
              
                app=(OsmPressure8)applet;
                app.p=new Panel();
                app.Num_Particles= new Choice();
                app.Num_Particles.addItem("0 Particles");
                app.Num_Particles.addItem("2 Particles");
                app.Num_Particles.addItem("5 Particles");
                app.Num_Particles.addItem("10 Particles");
                app.Num_Particles.addItem("20 Particles");
                app.Num_Particles.addItem("30 Particles");
                app.Num_Particles.addItem("Choose Particles Num");
                app.Num_Particles.select(6);

                app.Start_Stop= new Button("Start");
                app.Plot= new Button("StartPlot");
                app.Rst = new Button("Reset");
                app.Fit= new Button("CurveFit");
                GridBagLayout gbl= new GridBagLayout();
                app.p.setLayout(gbl);
                GridBagConstraints c= new GridBagConstraints();
                c.gridwidth=1;
                c.gridheight=1;
                c.fill= GridBagConstraints.BOTH;
                c.weightx=1;
                c.weighty=1;
                ThreeDBorder b1= new ThreeDBorder(app.Start_Stop);
                gbl.setConstraints(b1,c);
                app.p.add(b1);
                ThreeDBorder b2= new ThreeDBorder(app.Num_Particles);
                gbl.setConstraints(b2,c);
                app.p.add(b2);
                ThreeDBorder b3= new ThreeDBorder(app.Plot);
                gbl.setConstraints(b3,c);
//                app.p.add(b3);
                ThreeDBorder b4= new ThreeDBorder(app.Fit);
                gbl.setConstraints(b4,c);
//                app.p.add(b4);
                ThreeDBorder b5= new ThreeDBorder(app.Rst);
                gbl.setConstraints(b5,c);
//                app.p.add(b5);
                setLayout(new BorderLayout());
                add("North",new ThreeDBorder(app.p));
              //  app.c= new GraphCanvas(app);
              //  app.c.resize(300,200);
              //  add("South",new ThreeDBorder(app.c));
        }

        public Insets insets(){
                return new Insets(5,5,5,5);
        }

}

class GraphCanvas8 extends Canvas {

        OsmPressure8 app1;        

        static final int POSX = 8;
        static final int NEGX = 5;
        static final int POSY = 70;
        static final int NEGY = 90;
        double a;
        int b,N,x1,x2,y1,y2;
        String Str0=" ";
        String Str1=" ";
        String Str2=" ";
        
        double xstep;
        double ystep;

        public GraphCanvas8 (Applet a){
                app1=(OsmPressure8)a;
        }
        
        public synchronized void paint (Graphics g) {
                Dimension dm=size();
                int x,y,i,j;
                xstep=(double)dm.width/(double)(POSX+NEGX);
                ystep=(double)dm.height/(double)(POSY+NEGY);
                int xax=(int)Math.round(ystep*POSY);
                int yax=(int)Math.round(xstep*NEGX);
                g.setColor(Color.blue);
                g.drawLine(yax,0,yax,dm.height);
                g.drawLine(0,xax,dm.width,xax);
                for(i=0;i<(NEGX+POSX+1);i++){
                        x=(int)Math.round(i*xstep);
                        g.drawLine(x,xax-2,x,xax+2);
                }
                for(i=0;i<(NEGY+POSY+1);i+=5){
                        y=(int)Math.round(xax+i*ystep);
                        g.drawLine(yax-2,y,yax+2,y);
                }         
                for(i=0;i<(POSY+1);i+=5){
                        y=(int)Math.round(xax-i*ystep);
                        g.drawLine(yax-2,y,yax+2,y);
                } 
                g.setColor(Color.black);
                Font f = new Font("TimesRoman",Font.PLAIN,11);
                g.setFont(f);
                for(i=-5;i<9;i++){
                        g.drawString(" "+i,yax+(int)Math.round(i*xstep)-2,xax+12);      
                }
                f = new Font("TimesRoman",Font.PLAIN+Font.BOLD,12);
                g.setFont(f);
                g.setColor(Color.magenta);
                g.drawString("dC",dm.width-13,xax+13);
                g.drawString("P",yax-12,12);
                f = new Font("TimesRoman",Font.PLAIN,11);
                g.setFont(f);
                g.setColor(Color.black);
                for(i=50;i>(-NEGY);i-=20){
                        g.drawString(" "+i,yax-22,(int)Math.round((POSY-i)*ystep)+5);
                }
                if(app1.PLOT_AV == 1){                
                        a=(app1.CDiff.tcontout-app1.CDiff.tcontin)/app1.CDiff.n_runs;
                        b=(int)Math.round(app1.CDiff.total_sum/app1.CDiff.n_runs);
                        app1.xs[app1.is]=a;
                        app1.ys[app1.is]=b;
                        app1.zs[app1.is]=1;
                        app1.is++;
                        app1.PLOT_AV=0;
                }
                if(app1.PLOT_REAL == 1){
                        a=app1.CDiff.Coutr-app1.CDiff.Cinr;
                        b=(int)Math.round(app1.CDiff.Rin-app1.CDiff.Rout);
                        app1.xs[app1.is]=a;
                        app1.ys[app1.is]=b;
                        app1.zs[app1.is]=2;
                        app1.is++;
                        app1.PLOT_REAL=0;
                }
                for(i=0;i<(app1.is);i++){
                        a=app1.xs[i];
                        b=app1.ys[i];
                        N=4;
                        int hit=0;
                        for(j=i;j>=0;j--){
                                if (a == app1.xs[j]){
                                        if(b == app1.ys[j]){
                                                if(j != i){
                                                        hit++;
                                                        if(hit == 3){
                                                                N++;
                                                                hit=0;
                                                        }        
                                                }       
                                        }
                                }
                        }
                        if(app1.zs[i] == 1){
                                g.setColor(Color.red);
                        }
                        if(app1.zs[i] == 2){ 
                                g.setColor(Color.green);
                        }
                        g.fillOval((int)Math.round((NEGX+a)*xstep-N/2),(int)Math.round((POSY-b)*ystep)-N/3,N,N);
                }
                if(app1.ERR == 1){
                        g.setColor(Color.black);
                        g.drawString("Not enough data",2,12);
                        app1.ERR=0;        
                }
                if(app1.PLT == 1){
                        g.setColor(Color.black);
                        Str2=Str1;
                        Str1=Str0;
                        Str0="P="+(float)((float)Math.round(app1.a*100)/(float)100.0)+"+"+(float)((float)Math.round(app1.b*100)/(float)100.0)+"dC";
                        x1=(int)Math.round((NEGX+app1.min)*xstep);
                        y1=(int)Math.round((POSY-(app1.a+app1.b*app1.min))*ystep);
                        x2=(int)Math.round((NEGX+app1.max)*xstep);
                        y2=(int)Math.round((POSY-(app1.a+app1.b*app1.max))*ystep);

                        g.drawLine(x1,y1,x2,y2);
                        app1.PLT=0;
                } 
                g.setColor(Color.black);
                g.drawString(Str0,dm.width-75,15);
                g.drawString(Str1,dm.width-75,30);
                g.drawString(Str2,dm.width-75,45);       
         }
}

class PThread extends Thread{
        OsmPressure7 a;
        
        public PThread(Applet a){
                this.a=(OsmPressure7)a;
        }

        public void run(){
//                try{
//                                        sleep(60000);
//                                }
//                                catch(InterruptedException e) {}
                while(true){
                        if (a.rst == true){
                                try{
                                        sleep(20000);
                                }
                                catch(InterruptedException e) {}
                                a.rst=false;
                        }    
                        if (a.running){
                                a.PLOT_REAL=1;
                                a.c.repaint();
                        }
                        try{
                                sleep(15000);
                        }
                        catch(InterruptedException e) {}
                }
        }
}






        
