import java.applet.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.lang.Thread;
import javax.swing.*;

class Schwingung 
{
	double Runge[][] = new double[6][5];


	double Getmax(double mxAr[][])
	{
		int Grenze = mxAr.length;
		double maxWert = 0;
		for (int q = 0; q < Grenze; q++)
		{
			if (maxWert < Math.abs(mxAr[q][1]))
				maxWert = Math.abs(mxAr[q][1]);
			if (maxWert < Math.abs(mxAr[q][3]))
				maxWert = Math.abs(mxAr[q][3]);
		}
		return maxWert;
		
	}

	void Runge_Kutta(double[][] RErg, int t, double h,  double c1, double c2, double m1 , double m2, double d1, double d2, boolean stufe)
		{

			double F;
			double z;
			double Runge[][] = new double[11][5];
			Runge[0][0] =  RErg[t][0]; //x
			Runge[1][0] = RErg[t][1]; //q1
			Runge[2][0] = RErg[t][2];//q1'
			Runge[6][0] = RErg[t][3];//q2
			Runge[7][0] = RErg[t][4];//q2'
			
			for (int n = 0; n< 4; n++)
			{
				z = 2;
				if (n == 2)
					z = 1;
				
				Runge[3][n] = (double) -(d1+d2)/m1*Runge[2][n]+d2/m1*Runge[7][n]-(c1+c2)/m1*Runge[1][n]+ c2/m1* Runge[6][n];
				if(stufe){
				Runge[8][n] = (double) -d2*Runge[7][n]+d2*Runge[2][n]+c1/m2*Runge[1][n]- c2/m2 * Runge[6][n];
				Runge[9][n] = (double) h*Runge[7][n];
				Runge[10][n] = (double) h*Runge[8][n];
				Runge[7][n+1] = (double) Runge[7][0]+ Runge[10][n]/z;
				Runge[6][n+1] = (double) Runge[6][0]+ Runge[9][n]/z;
				}
				Runge[4][n] = (double) h*Runge[2][n];
				Runge[5][n] = (double) h*Runge[3][n];
				Runge[2][n+1] = (double) Runge[2][0] + Runge[5][n]/z;
				Runge[0][n+1] = (double) Runge[0][0]+ h/z;
				Runge[1][n+1] = (double) Runge[1][0]+ Runge[4][n]/z;
				
				
			}
			nx = (double) Runge[0][0]+h;
			ny = (double) 1/6 * (Runge[4][0]+Runge[4][1]+Runge[4][2]+Runge[4][3]) + RErg[t][1];
			ndy = (double)1/6 * (Runge[5][0]+Runge[5][1]+Runge[5][2]+Runge[5][3]) + RErg[t][2];
			nq = (double)1/6 * (Runge[9][0]+Runge[9][1]+Runge[9][2]+Runge[9][3]) + RErg[t][3];
			ndq = (double)1/6 * (Runge[10][0]+Runge[10][1]+Runge[10][2]+Runge[10][3]) + RErg[t][4];
		
		}
	double nx, ny, ndy, ndq, nq;


}


public class Cl_Schwingung_app extends Applet  {
	Scrollbar sb_Daempf1, sb_Daempf2, sb_Phase, sb_Masse1, sb_Masse2, sb_Federc1, sb_Federc2;
	Scrollbar	sb_Ay1, sb_Ay2, sb_Ady1, sb_Ady2;
	TextField tx_Kraft,tx_Masse1, tx_Masse2, tx_Federc1, tx_Federc2, tx_AnfY1, tx_AnfdY1,tx_AnfY2, tx_AnfdY2;
	CheckboxGroup bg_Wechsel = new CheckboxGroup();
	Checkbox rb_Ein = new Checkbox("ein Massen-Schwinger", false, bg_Wechsel);
	Checkbox rb_Zwei = new Checkbox("zwei Massen-Schwinger", true, bg_Wechsel);
	
	int Frequenz =1;
	double AnfY1 = -1;
	double AnfdY1 = 0;
	double AnfY2 = -1;
	double AnfdY2 = 0;
	double Betrachtw = 70 ;
    Graphics Buffergrafik;
    Image offscreen;
    
  
	double Feinheit = 0.01;
	
	double daempf1 = 0;
	double daempf2 = 0;
	double masse1 = 1;
	double masse2 = 1;
	double federc1 = 1;
	double federc2 = 1;
	
	
	
	int Punkte = new Double(Betrachtw/Feinheit).intValue();
	
	public class MyPanel extends JPanel {
	    double Arr_erg[][] = new double[Punkte][5];
	  
	    Schwingung schwing = new Schwingung();
	    

		
	    class Rungethread extends Thread
	    {
	        public void run()
	    	{

	        	if(rb_Ein.getState())
		        {
		        	federc2 = 0;
		        	daempf2 = 0;
		        	
		        	
		        }else{
				    federc2 = (double) sb_Federc2.getValue()/50;
				    daempf2 = (double) sb_Daempf2.getValue()/100;
		        }
	    		for (int n = 0; n < Punkte-1; n++)
	    			{
		        	
	    				schwing.Runge_Kutta(Arr_erg, n ,Feinheit, federc1, federc2, masse1, masse2, daempf1 , daempf2, rb_Zwei.getState());
	  	        	
	    				Arr_erg[n+1][0]= (double) schwing.nx;
	    				Arr_erg[n+1][1]= (double) schwing.ny;
	    				Arr_erg[n+1][2]= (double) schwing.ndy;
	    				Arr_erg[n+1][3]= (double) schwing.nq;
	    				Arr_erg[n+1][4]= (double) schwing.ndq;
	    				//System.out.println(ergebnis[n][1]);

	    			}
	    			this.stop();
	       	}
	    }

	    public void paint(Graphics g)
	    {
	    	int ym = getHeight()/2;
	        int xm = getWidth();
	        
	    	if (offscreen == null){
	    	offscreen  = createImage(getWidth(),getHeight());}
			Buffergrafik = offscreen.getGraphics(); 
	    	Buffergrafik.clearRect(2, 2, getWidth()-1, getHeight()-3);
	    	Buffergrafik.drawRect(1, 2, xm-2, ym*2-3);
	    	 //Koordinatensystem
	        Buffergrafik.setColor(new Color(250,50,50));
	        Buffergrafik.drawLine(xm/90, 2, xm/90, ym*2);
	        Buffergrafik.drawLine(0, ym, xm, ym);
	        //Anfangsbedingungen
	        Arr_erg[0][0]= 0;
	        Arr_erg[0][1]= -AnfY1;
	        Arr_erg[0][2]= -AnfdY1; 
	        Arr_erg[0][3]= -AnfY2;
	        Arr_erg[0][4]= -AnfdY2;

	        double xskal = Punkte/getWidth();
	        Thread thRunge = new Rungethread();
	        thRunge.run();
     
	        Buffergrafik.translate(xm/90, 0);
	        
	        double yskal = 0.4*getHeight()/schwing.Getmax(Arr_erg);
	         
  	     for (int z = 0; z < Punkte-1; z++)
	        {
  	    	 	Buffergrafik.setColor(new Color(0,150,100));
  	    	 	Buffergrafik.drawString("erste Masse", 490, 20);
  	    	 	Buffergrafik.drawLine( (int)(Arr_erg[z][0]*xskal) ,(int)( Arr_erg[z][1]*yskal+ym ), (int)( Arr_erg[z+1][0]*xskal),(int)  (Arr_erg[z+1][1]*yskal+ym));
  	    	 	if (rb_Zwei.getState()){
  	    	 	Buffergrafik.setColor(new Color(100,150,255));
  	    	 	Buffergrafik.drawString("zweite Masse", 490, 35);
	        	Buffergrafik.drawLine( (int)(Arr_erg[z][0]*xskal) ,(int)( Arr_erg[z][3]*yskal+ym ), (int)( Arr_erg[z+1][0]*xskal),(int)  (Arr_erg[z+1][3]*yskal+ym));
  	    	 		}
  	    	 	}
  	     if (offscreen != null)
  	    	 g.drawImage(offscreen, 0, 0, this);
 
  
	   }
	    public void upadate(Graphics g)
	    {
	    	
	    	paint(g);
	    }

	}
	public void init()
	{
		setLayout(null);
		
		MyPanel C_Panel = new MyPanel();
		C_Panel.setBounds(100, 10, 600, 440);
		add(C_Panel);
		
		Label l_Daempf = new Label("Daempfung:");
		l_Daempf.setBounds(8, 20, 120, 14);
		add(l_Daempf);
		
		Label l_Daempf1 = new Label("d 1");
		l_Daempf1.setBounds(8, 35, 40, 14);
		add(l_Daempf1);
		
		Label l_Daempf2 = new Label("d 2");
		l_Daempf2.setBounds(48, 35, 40, 14);
		add(l_Daempf2);
		
		Label l_Masse1 = new Label("Masse 1");
		l_Masse1.setBounds(8, 470, 120, 14);
		add(l_Masse1);
		
		Label l_Masse2 = new Label("Masse 2");
		l_Masse2.setBounds(8, 510, 120, 14);
		add(l_Masse2);
		
		Label l_Federc1 = new Label("Federkonstante 1");
		l_Federc1.setBounds(400, 470, 120, 14);
		add(l_Federc1);
		
		Label l_Federc2 = new Label("Federkonstante 2");
		l_Federc2.setBounds(400, 510, 120, 14);
		add(l_Federc2);
		
		Label l_Anfangsb = new Label("Anfangsbedingung:");
		l_Anfangsb.setBounds(710, 190, 120, 14);
		add(l_Anfangsb);
		
		Label l_Anfy1 = new Label("y 1");
		l_Anfy1.setBounds(710, 210, 80, 14);
		add(l_Anfy1);
		
		Label l_Anfdy1 = new Label("dy 1/dt");
		l_Anfdy1.setBounds(710, 280, 80, 14);
		add(l_Anfdy1);
		
		Label l_Anfy2 = new Label("y 2");
		l_Anfy2.setBounds(820, 210, 80, 14);
		add(l_Anfy2);
		
		Label l_Anfdy2 = new Label("dy 2/dt");
		l_Anfdy2.setBounds(820, 280, 80, 14);
		add(l_Anfdy2);
		
		tx_Masse1 = new TextField();
		tx_Masse1.setBounds(265, 490, 86, 20);
		tx_Masse1.setText(String.valueOf(masse1));
		add(tx_Masse1);
		tx_Masse1.disable();
		tx_Masse1.setColumns(10);
		
		tx_Masse2 = new TextField();
		tx_Masse2.setBounds(265, 530, 86, 20);
		tx_Masse2.setText(String.valueOf(masse2));
		add(tx_Masse2);
		tx_Masse2.disable();
		tx_Masse2.setColumns(10);
		
		tx_AnfY1 = new TextField();
		tx_AnfY1.setBounds(700, 230, 86, 20);
		tx_AnfY1.setText("-1");
		tx_AnfY1.disable();
		add(tx_AnfY1);

		tx_AnfdY1 = new TextField();
		tx_AnfdY1.setBounds(700, 300, 86, 20);
		tx_AnfdY1.setText("0");
		tx_AnfdY1.disable();
		add(tx_AnfdY1);
		
		tx_AnfY2 = new TextField();
		tx_AnfY2.setBounds(820, 230, 86, 20);
		tx_AnfY2.setText("-1");
		tx_AnfY2.disable();
		add(tx_AnfY2);

		tx_AnfdY2 = new TextField();
		tx_AnfdY2.setBounds(820, 300, 86, 20);
		tx_AnfdY2.setText("0");
		tx_AnfdY2.disable();
		add(tx_AnfdY2);
		
		tx_Federc1 = new TextField();
		tx_Federc1.setBounds(650, 490, 86, 20);
		tx_Federc1.setText(String.valueOf(federc1));
		add(tx_Federc1);
		tx_Federc1.disable();
		tx_Federc1.setColumns(10);
		
		tx_Federc2 = new TextField();
		tx_Federc2.setBounds(650, 530, 86, 20);
		tx_Federc2.setText(String.valueOf(federc2));
		add(tx_Federc2);
		tx_Federc2.disable();
		tx_Federc2.setColumns(10);
		
	
		sb_Daempf1 = new Scrollbar(Scrollbar.VERTICAL, 0,1,0,100);
		sb_Daempf1.setBounds(23, 60, 17, 231);
		sb_Daempf1.setValue(0);
		add(sb_Daempf1);
		class Daempf1Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    daempf1 = (double) sb_Daempf1.getValue()/100;
			    repaint();		      
			    }
			  }
		sb_Daempf1.addAdjustmentListener(new Daempf1Change());
		
		sb_Daempf2 = new Scrollbar(Scrollbar.VERTICAL, 0,1,0,100);
		sb_Daempf2.setBounds(60, 60, 17, 231);
		sb_Daempf2.setValue(0);
		add(sb_Daempf2);
		class Daempf2Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    daempf2 = (double) sb_Daempf2.getValue()/100;
			    repaint();		      
			    }
			  }
		sb_Daempf2.addAdjustmentListener(new Daempf2Change());
		
		sb_Masse1 = new Scrollbar(Scrollbar.HORIZONTAL, 0,1,1,100);
		sb_Masse1.setBounds(12, 490, 230, 17);
		sb_Masse1.setValue(50);
		add(sb_Masse1);
		class Mass1Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    masse1 = (double) sb_Masse1.getValue()/50;
			    repaint();
				tx_Masse1.setText(String.valueOf(masse1)); 
			    }
			  }
		sb_Masse1.addAdjustmentListener(new Mass1Change());
		
		sb_Masse2 = new Scrollbar(Scrollbar.HORIZONTAL, 0,1,1,100);
		sb_Masse2.setBounds(12, 530, 230, 17);
		sb_Masse2.setValue(50);
		add(sb_Masse2);
		class Mass2Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    masse2 = (double) sb_Masse2.getValue()/50;
			    repaint();
				tx_Masse2.setText(String.valueOf(masse2)); 
			    }
			  }
		sb_Masse2.addAdjustmentListener(new Mass2Change());
		
		sb_Federc1 = new Scrollbar(Scrollbar.HORIZONTAL, 0,1,1,100);
		sb_Federc1.setBounds(400, 490, 230, 17);
		sb_Federc1.setValue(50);
		add(sb_Federc1);
		class Fc1Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    federc1 = (double) sb_Federc1.getValue()/50;
			    repaint();
				tx_Federc1.setText(String.valueOf(federc1)); 
			    }
			  }
		sb_Federc1.addAdjustmentListener(new Fc1Change());
		
		sb_Federc2 = new Scrollbar(Scrollbar.HORIZONTAL, 0,1,1,100);
		sb_Federc2.setBounds(400, 530, 230, 17);
		sb_Federc2.setValue(50);
		add(sb_Federc2);
		class Fc2Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    federc2 = (double) sb_Federc2.getValue()/50;
			    repaint();
				tx_Federc2.setText(String.valueOf(federc2)); 
			    }
			  }
		sb_Federc2.addAdjustmentListener(new Fc2Change());
		
		sb_Ay1 = new Scrollbar(Scrollbar.HORIZONTAL, 0,1,1,22);
		sb_Ay1.setBounds(700, 255, 100, 17);
		sb_Ay1.setValue(0);
		add(sb_Ay1);
		class Ay1Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    	AnfY1 = (double) sb_Ay1.getValue()/10-1.1;
			    	AnfY1 = AnfY1*100;
			    	AnfY1 = Math.round(AnfY1);
			    	AnfY1 = AnfY1/100;
			    repaint();
			    tx_AnfY1.setText(String.valueOf(AnfY1)); 
			    }
			  }
		sb_Ay1.addAdjustmentListener(new Ay1Change());
	      
		sb_Ay2 = new Scrollbar(Scrollbar.HORIZONTAL, 0,1,1,22);
		sb_Ay2.setBounds(820, 255, 100, 17);
		sb_Ay2.setValue(0);
		add(sb_Ay2);
		class Ay2Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    	AnfY2 = (double) sb_Ay2.getValue()/10-1.1;
			    	AnfY2 = AnfY2*100;
			    	AnfY2 = Math.round(AnfY2);
			    	AnfY2 = AnfY2/100;
			    repaint();
			    tx_AnfY2.setText(String.valueOf(AnfY2)); 
			    }
			  }
		sb_Ay2.addAdjustmentListener(new Ay2Change());
		
		sb_Ady2 = new Scrollbar(Scrollbar.HORIZONTAL, 0,1,1,22);
		sb_Ady2.setBounds(820, 325, 100, 17);
		sb_Ady2.setValue(11);
		add(sb_Ady2);
		class Ady2Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    	AnfdY2 = (double) sb_Ady2.getValue()/10-1.1;
			    	AnfdY2 = AnfdY2*100;
			    	AnfdY2 = Math.round(AnfdY2);
			    	AnfdY2 = AnfdY2/100;
			    repaint();
			    tx_AnfdY2.setText(String.valueOf(AnfdY2)); 
			    }
			  }
		sb_Ady2.addAdjustmentListener(new Ady2Change());
		
		sb_Ady1 = new Scrollbar(Scrollbar.HORIZONTAL, 0,1,1,22);
		sb_Ady1.setBounds(700, 325, 100, 17);
		sb_Ady1.setValue(11);
		add(sb_Ady1);
		class Ady1Change implements AdjustmentListener{
			    public void adjustmentValueChanged(AdjustmentEvent ae){
			    	AnfdY1 = (double) sb_Ady1.getValue()/10-1.1;
			    	AnfdY1 = AnfdY1*100;
			    	AnfdY1 = Math.round(AnfdY1);
			    	AnfdY1 = AnfdY1/100;
			    repaint();
			    tx_AnfdY1.setText(String.valueOf(AnfdY1)); 
			    }
			  }
		sb_Ady1.addAdjustmentListener(new Ady1Change());
		
		class EinChange implements ItemListener{
			 public void itemStateChanged(ItemEvent arg0)
			{
				 sb_Masse2.disable();
				 sb_Federc2.disable();
				 tx_AnfdY2.disable();
				 tx_AnfY2.disable();
				 sb_Daempf2.disable();
				 sb_Ay2.disable();
				 sb_Ady2.disable();
				repaint();
			}
		}
		
		class ZweiChange implements ItemListener{
			 public void itemStateChanged(ItemEvent arg0)
			{
				 sb_Masse2.enable();
				 sb_Federc2.enable();
				 tx_AnfY2.enable();
				 tx_AnfdY2.enable();
				 sb_Daempf2.enable();
				 sb_Ay2.enable();
				 sb_Ady2.enable();
				repaint();
			}
		}
		rb_Zwei.setBounds(750, 100, 150, 20);
		add(rb_Zwei);
		rb_Ein.addItemListener(new EinChange());
		
		rb_Ein.setBounds(750, 122, 150, 20);
		add(rb_Ein);
		rb_Zwei.addItemListener(new ZweiChange());
		repaint();
	}

}
