import java.awt.*;
import java.applet.*;
import vrml.external.*;
import vrml.external.field.*;

public class Zeit extends Applet implements Runnable {
  private Thread Timer;
  private long   lastTime = 0;
  private long   cycleTime = 30;


		private long deltat = 0;
	private float faktor = 0;
	private float radheinz = 0.2f;
	private final static float reib = 1f;

	private float[] dingli = new float[3];
	private float raddingli = 0.3f;
  	private boolean coll;
	private float[] adli = new float[3];

	private float[] dingre = new float[3];
	private float raddingre = 0.3f;
	private float[] adre = new float[3];

	private float[] viertel = new float[3];
	private float radviertel = 2.0f;
	private float[] aviertel = new float[3];

	private float[] zentli = new float[3];
	private float[] schlvoli = new float[3];
	private float[] aschlli = new float[3];
	private float[] ortli = new float[3];
	private float[] ortl = new float[3];
	private float[] geli = new float[3];
	private float[] gere = new float[3];

	private float[] zentre = new float[3];
	private float[] schlvore = new float[3];
	private float[] aschlre = new float[3];
	private float[] ortre = new float[3];
	private float[] ortr = new float[3];


  private Button buttonStart;
  private Button buttonStop;
  private Button buttonFlitsch;
  private Button buttonForward;
  private Button buttonTest;
  private Checkbox checkBoxLoop;
  private Scrollbar scrlPosition;
  private Scrollbar scrlZieher;

  private EventInSFVec3f position;
  private EventInSFRotation links;
  private EventInSFRotation view;
  private EventInSFRotation rechts;
  private EventInSFVec3f ziehe;
  private EventInSFVec3f druck;

private float[] schlvoli2 = new float[3];
private float[] dev = new float[3];

private float[] schlvore2 = new float[3];
private float[] devr = new float[3];

private float[] ort = new float[3];
private float[ ] geschw = new float[3];
private float[ ] vie = new float[4];
private float[ ] zi = new float[3];
private float[ ] dr = new float[3];
private float[ ] li = new float[4];
private float[ ] re = new float[4];
private float beschleunigung  = 0;
private boolean t = true;
private boolean j = true;
private int tasteli = -1;
private int tastere = -1;

public void init() {

    	vie[0]=0; vie[1]=1; vie[0]=0;

	geschw[0]=0f; geschw[1]=0; geschw[2]=0f;
    	ort[0]=4.4f; ort[1]=0.5f; ort[2]=3.15f;

	li[0]=0; li[1]=1; li[2]=0;
     	re[0]=0; re[1]=1; re[2]=0;

	zi[0]=1.9f; zi[1]=0.7f;
     	dr[0]=1; dr[1]=1; dr[2]=1;

    dingli[0]=1.3f; dingli[1]=0.0f; dingli[2]=-2.0f; //DING links
    dingre[0]=3.7f; dingre[1]=0.0f; dingre[2]=-2.0f; //DING rechts
    viertel[0]=2.6f; viertel[1]=0.0f; viertel[2]=-2.6f; //Mittelpunkt Viertelkreis rechts oben

	zentli[0]=1.4f; zentli[1]=0.0f; zentli[2]=3.0f;
    	zentre[0]=3.4f;zentre[1]=0.0f;zentre[2]=3.0f;

	// Steuerelemente initialisieren:

    setLayout(null);
    addNotify();

    setBackground(Color.lightGray);

    buttonStop = new Button("Stop"); add(buttonStop);
    buttonStop.reshape(5, 24, 40, 20);
    buttonForward = new Button(">"); add(buttonForward);
    buttonForward.reshape(45, 24, 40, 20);
    buttonStart = new Button("Neu"); add(buttonStart);
    buttonStart.reshape(5,44,40,20);
    buttonFlitsch = new Button("Flitsch"); add(buttonFlitsch);
    buttonFlitsch.reshape(45,44,40,20);
    buttonTest = new Button("Test"); add(buttonTest);
    buttonTest.reshape(5, 64, 40, 20);

    scrlPosition = new Scrollbar(Scrollbar.HORIZONTAL, 0, 50, 0, 100);
    add(scrlPosition); scrlPosition.reshape(100, 24, 280, 20);

    scrlZieher = new Scrollbar(Scrollbar.HORIZONTAL,0, 100, 44,57 );
    add(scrlZieher); scrlZieher.reshape(100,70 , 280,20);

    Label l; l = new Label("Beschleunigung:"); l.reshape(100,4,100,20); add(l);
    l = new Label("Kraft:"); l.reshape(100, 50, 60,20); add(l);

    checkBoxLoop = new Checkbox("Sound");
    add(checkBoxLoop);
    checkBoxLoop.reshape(5, 4, 50, 20);

    // Referenz auf den VRML-Browsers erhalten:

    Browser browser = Browser.getBrowser(this);

    // VRML-Nodes als Java-Instanzen erhalten:

    position = (EventInSFVec3f) browser.getNode("Heinz").getEventIn("set_translation"); //Kugel
    links = (EventInSFRotation) browser.getNode("Eins").getEventIn("set_rotation");     //linker Schl„ger
    rechts = (EventInSFRotation) browser.getNode("Zwei").getEventIn("set_rotation");    //rechter Schl„ger
    druck = (EventInSFVec3f) browser.getNode("Feder").getEventIn("set_scale");
    ziehe = (EventInSFVec3f) browser.getNode("Zieher").getEventIn("set_translation");
    view  = (EventInSFRotation) browser.getNode("Start2").getEventIn("set_orientation"); //Viewpoint in Kugel

   }

  public void start() {
    Timer = new Thread(this);
    Timer.start();
    lastTime = System.currentTimeMillis();
  }

  public void run() {
    while (true) {
/*      deltat = System.currentTimeMillis() - lastTime;
	if ((deltat>= cycleTime) & t ) {
       	      lastTime = System.currentTimeMillis();
	      faktor = deltat / 30;
              harald();
      	}  */
      if (t) {harald();}
      Timer.yield();
    }
  }

  public void harald() {
	coll = false;

	adli[0] = dingli[0]-ort[0]; adli[2]=dingli[2]-ort[2];
	float adlib = ((adli[0])*(adli[0]))+((adli[2])*(adli[2]));
	adre[0] = dingre[0]-ort[0]; adre[2]=dingre[2]-ort[2];
	float adreb = ((adre[0])*(adre[0]))+((adre[2])*(adre[2]));
	aviertel[0] = viertel[0]-ort[0]; aviertel[2]=viertel[2]-ort[2];
	float aviertelb = (float) Math.sqrt(((aviertel[0])*(aviertel[0]))+((aviertel[2])*(aviertel[2])));

	ortl[0]=ort[0]-zentli[0];
	ortl[2]=-ort[2]+zentli[2];
	ortli[0]=((float)Math.cos(li[3]))*ortl[0]-((float)Math.sin(li[3]))*ortl[2];
	ortli[2]=((float)Math.cos(li[3]))*ortl[2]+((float)Math.sin(li[3]))*ortl[0];
	                geli[0]=((float)Math.cos(li[3]))*geschw[0]-((float)Math.sin(li[3]))*(-1)*geschw[2];//-geschw[2] !
	                geli[2]=((float)Math.cos(li[3]))*(-1)*geschw[2]+((float)Math.sin(li[3]))*geschw[0];//-geschw[2] !




	schlvoli[0]=zentli[0]+((float)Math.cos(li[3]))*0.8f;
	schlvoli[2]=zentli[2]-((float)Math.sin(li[3]))*0.8f;
	aschlli[0] = schlvoli[0]-ort[0]; aschlli[2]=schlvoli[2]-ort[2];
	float aschllib = ((aschlli[0])*(aschlli[0]))+((aschlli[2])*(aschlli[2]));//Betragsquadrat
	schlvoli2[0]=(0.4f/(float)Math.sqrt(aschllib))*(-1)*aschlli[0]; //Vektor MP Kugel nach MP Schl„ger links
	schlvoli2[2]=(0.4f/(float)Math.sqrt(aschllib))*(-1)*aschlli[2]; //im System Flipper (0-Achse: li nach re, 2-Achse: ob nach un)
	dev[0]=0;
	dev[2]=0;



	if (li[3]*li[3]<0.49){

	float der=(float)Math.abs(ortli[0]*faktor*0.1f);
	dev[2]=(-1)*tasteli*(der);

	}

	geli[0]=geli[0]-dev[0];
	geli[2]=geli[2]-dev[2];

	if (ortli[0]>0.8f) {
	if (aschllib<=radheinz+0.1f) {


		float vmala = (geli[0]*schlvoli2[0])+(geli[2]*schlvoli2[2]);
		if (vmala>0) {
		float fak = 2*(vmala/aschllib);
		geli[0]=geli[0]-(fak*aschlli[0]);
		geli[2]=geli[2]-(fak*aschlli[2]);
		coll=true;
		}
	}
	}
	if ((ortli[0]<0.8)&(ortli[0]>0)&(ortli[2]*ortli[2]<(0.2+radheinz-ortli[0]/8)*(0.2+radheinz-ortli[0]/8))) {
		float vorz=-((float)Math.sqrt(geli[2]*geli[2]))/geli[2];

		float vmala2 = (geli[0]*vorz*0.124f)+(geli[2]*0.9923f);
		float fak = 2f*(vmala2); // eig. 2, also Schubbs
		geli[0]=0.9f*(geli[0]-(fak*0.124f));
		geli[2]=0.9f*(geli[2]-(fak*0.9923f));
	coll=true;
	}

	geli[0]=geli[0]+dev[0];
	geli[2]=geli[2]+dev[2];

                    geschw[0]=((float)Math.cos(li[3]))*geli[0]+((float)Math.sin(li[3]))*geli[2];
                    geschw[2]=-((float)Math.cos(li[3]))*geli[2]+((float)Math.sin(li[3]))*geli[0];



ortr[0]=ort[0]-zentre[0];
	ortr[2]=-ort[2]+zentre[2];
	ortre[0]=((float)Math.cos(re[3]))*ortr[0]-((float)Math.sin(re[3]))*ortr[2];
	ortre[2]=((float)Math.cos(re[3]))*ortr[2]+((float)Math.sin(re[3]))*ortr[0];
                  	gere[0]=((float)Math.cos(re[3]))*geschw[0]-((float)Math.sin(re[3]))*geschw[2];
                    gere[2]=-((float)Math.cos(re[3]))*geschw[2]-((float)Math.sin(re[3]))*geschw[0];


schlvore[0]=zentre[0]+((float)Math.cos(re[3]))*0.8f;
	schlvore[2]=zentre[2]-((float)Math.sin(re[3]))*0.8f;
	aschlre[0] = schlvore[0]-ort[0]; aschlre[2]=schlvore[2]-ort[2];
	float aschlreb = ((aschlre[0])*(aschlre[0]))+((aschlre[2])*(aschlre[2]));
	schlvore2[0]=0.4f/(float)Math.sqrt(aschlreb)*aschlre[0];
	schlvore2[2]=0.4f/(float)Math.sqrt(aschlreb)*aschlre[2];
	devr[0]=0;
	devr[2]=0;


if ((-re[3]-3.14)*(-re[3]-3.14)<0.49){

	float derr=(float)Math.abs(ortre[0]*faktor*0.1f);
	devr[2]=(-1)*tastere*(derr);

	}

	gere[0]=gere[0]-devr[0];
	gere[2]=gere[2]-devr[2];


	if (ortre[0]>0.8f) {
	if (aschlreb<=radheinz+0.1f) {


		float vmala = (gere[0]*schlvore2[0])+(gere[2]*schlvore2[2]);
		if (vmala>0) {
		float fak = 2*(vmala/aschlreb);
		gere[0]=gere[0]-(fak*aschlre[0]);
		gere[2]=gere[2]-(fak*aschlre[2]);
		coll=true;
		}
	}
	}
	if ((ortre[0]<0.8)&(ortre[0]>0)&(ortre[2]*ortre[2]<(radheinz+0.2-ortre[0]/8)*(radheinz+0.2-ortre[0]/8))) {
		float vorz=-((float)Math.sqrt(gere[2]*gere[2]))/gere[2];

		float vmala2 = (gere[0]*0.124f)+(gere[2]*0.9923f);
		float fak = 2f*(vmala2); // eig. 2, also Schubbs
		gere[0]=0.9f*(gere[0]-(fak*0.124f));
		gere[2]=0.9f*(gere[2]-(fak*0.9923f));
		coll=true;
	}

	gere[0]=gere[0]+devr[0];
	gere[2]=gere[2]+devr[2];

	            geschw[0]=((float)Math.cos(re[3]))*gere[0]-((float)Math.sin(re[3]))*gere[2];  //li=re
	            geschw[2]=-((float)Math.cos(re[3]))*gere[2]-((float)Math.sin(re[3]))*gere[0];  //li=re


	if (ort[0]>=4.6f) {
		geschw[0]=-0.9f*(float)Math.abs(geschw[0]); //D„mpfung
		coll = true;
	}
	if (ort[0]<=0.6f) {
		geschw[0]=0.9f*(float)Math.abs(geschw[0]); //D„mpfung
		coll = true;
	}
	if ((ort[0]<=1.4f)||(ort[0]>=3.4f)) {
		if (ort[2]>=2.8f) {
			geschw[2]=-0.9f*(float)Math.abs(geschw[2]);
			coll = true;
		}
	}
	else {
		if (ort[2]>=4.6f) {
			geschw[2]=-0.9f*(float)Math.abs(geschw[2]);
			coll = true;
		}
	}
	if (ort[2]<=-4.6f) {
		geschw[2]=1f*(float)Math.abs(geschw[2]);
		coll = true;
	}
	if ((float)Math.sqrt(adlib)<=radheinz+raddingli) {
		float vmala = (geschw[0]*adli[0])+(geschw[2]*adli[2]);
		if (vmala>0) {
		float fak = 2.5f*(vmala/adlib); // eig. 2, also Schubbs
		geschw[0]=geschw[0]-(fak*adli[0]);
		geschw[2]=geschw[2]-(fak*adli[2]);
		}
	}
	if ((float)Math.sqrt(adreb)<=radheinz+raddingre) {
		float vmala = (geschw[0]*adre[0])+(geschw[2]*adre[2]);
		if (vmala>0) {
		float fak = 2.5f*(vmala/adreb); // eig. 2, also Schubbs
		geschw[0]=geschw[0]-(fak*adre[0]);
		geschw[2]=geschw[2]-(fak*adre[2]);
		}
	}
	if ((ort[0]>=2.6)&(ort[2]<=-2.6)&(aviertelb>=radviertel-radheinz)) {
		float vmala = (geschw[0]*aviertel[0])+(geschw[2]*aviertel[2]);
		if (vmala<0) {
		float fak = 2*(vmala/(aviertelb*aviertelb));
		geschw[0]=geschw[0]-(fak*aviertel[0]);
		geschw[2]=geschw[2]-(fak*aviertel[2]);
		}
	}



	faktor=((float)(System.currentTimeMillis()-lastTime))/30.6f;
	lastTime = System.currentTimeMillis();
	if (!coll) {
	geschw[0]=reib*geschw[0]; // Rollreibung
	geschw[2]=reib*geschw[2]+beschleunigung*faktor;
	}
//	System.out.println(faktor);
	if(faktor > 7){faktor = 7;}
	ort[0]=ort[0]+geschw[0]*faktor;
	ort[2]=ort[2]+geschw[2]*faktor;
	if (geschw[0]<=0) {
	vie[3]=(float)Math.acos(-geschw[2]/((float)Math.sqrt((geschw[0]*geschw[0])+(geschw[2]*geschw[2]))));
	}
	else {
	vie[3]=-(float)Math.acos(-geschw[2]/((float)Math.sqrt((geschw[0]*geschw[0])+(geschw[2]*geschw[2]))));
	}
	li[3]=li[3]+tasteli*faktor*0.3f;
	if (li[3]>0.7f) {li[3]=0.7f;}
	if (li[3]<-0.7f) {li[3]=-0.7f;}

	re[3]=re[3]-tastere*faktor*0.3f;
	if (re[3]>-2.44f) {re[3]=-2.44f;}
	if (re[3]<-3.84f) {re[3]=-3.84f;}

	rechts.setValue(re);
	links.setValue(li);
	view.setValue(vie);
	position.setValue(ort);
  }



  private void setBeschl() {
	beschleunigung = ((float) scrlPosition.getValue()) / 5000;
  }

  private void setZieher() {
	zi[2]=((float) scrlZieher.getValue())/10 ;
	ziehe.setValue(zi);
	dr[1]=(1/((float) scrlZieher.getValue())-0.0175f)*192.923f;
	druck.setValue(dr);
	if(j) { ort[2] = (float) scrlZieher.getValue()/10f-1.25f; position.setValue(ort);}
  }

  public boolean keyDown(Event e, int key) {
	if ( (char) key == '<' ) {
		tasteli = 1;
		return true;
	}
	if( (char) key == '-') {
		tastere = 1;
		return true;
	}
    return false;
  }

  public boolean keyUp(Event e, int key) {
	if ( (char) key == '<' ) {
		tasteli = -1;
		return true;
	}
	if( (char) key == '-') {
		tastere = -1;
		return true;
	}
    return false;
  }

  public boolean handleEvent(Event e) {
    if ((e.id == Event.SCROLL_LINE_UP) || (e.id == Event.SCROLL_LINE_DOWN) ||
        (e.id == Event.SCROLL_PAGE_UP) || (e.id == Event.SCROLL_PAGE_DOWN) ||
        (e.id == Event.SCROLL_ABSOLUTE)) {
		if(e.target == scrlPosition) {
			setBeschl();
		}
		if(e.target == scrlZieher) {
			setZieher();
		}
    }
    if (e.id == Event.ACTION_EVENT) {
      		if (e.target == buttonStop) {
		t = false;
      		}
      		if (e.target == buttonForward) {
		t = true;
      		}
      		if (e.target == buttonStart) {
		j = true;
		scrlZieher.setValue(44);
		zi[2]=4.4f; ziehe.setValue(zi);
		dr[1]=1f;druck.setValue(dr);
		geschw[0]=0; geschw[2]=0;
		ort[0]=4.4f; ort[1]=0.5f; ort[2]=3.15f;
		position.setValue(ort);
      		}
      		if (e.target == buttonFlitsch) {
			if((j) & (scrlZieher.getValue() > 44)) {
				geschw[2] =((float) scrlZieher.getValue()-44)/26;
				scrlZieher.setValue(44);
				zi[2]=4.4f;ziehe.setValue(zi);
				dr[1]=1;druck.setValue(dr);
				ort[2] = 3.15f; position.setValue(ort);
				j = false;
			}
			else {
	        		zi[2]=4.4f; ziehe.setValue(zi);
				dr[1]=1; druck.setValue(dr);
				scrlZieher.setValue(44);
			}
      		}
		if (e.target == buttonTest) {
		ort[0]=2.0f;ort[2]=0.0f;
		geschw[0]=0;geschw[2]=0.1f;
		t = true;
      		}
    }
    return super.handleEvent(e);
  }
}