import vrml.*;
import vrml.node.*;
import vrml.field.*;
import java.util.Random;

public class Walker extends Script {
  private SFRotation lowerArmL, upperArmL, lowerLegL, upperLegL;
  private float[][] lowerArmf, upperArmf, lowerLegf, upperLegf; 
  private float[] NulRot;
  private SFRotation lowerArmR, upperArmR, lowerLegR, upperLegR;
  private SFRotation wholebody;
  private float[] wholebodyf1,wholebodyf2,wholebodyf3;

  private SFVec3f move;
  private SFBool cont;
  float[] movers;
  int times;
  float orposx = 0.0f;
  float orposy = 0.0f;
  float orposz = 0.0f;
  float dx = 1.0f;
  float dz = 0.0f;
  int numberofTurns = 0;
  boolean goon = false;
  boolean continuous = false;
  boolean rotations = false;
  int start = 0;
  Random rnd;

	public void initialize() {
		lowerArmf = new float[6][4];
		upperArmf = new float[4][4];
		lowerArmL = (SFRotation) getEventOut("lowerArmL");
		lowerArmR = (SFRotation) getEventOut("lowerArmR");
		upperArmL = (SFRotation) getEventOut("upperArmL");
		upperArmR = (SFRotation) getEventOut("upperArmR");
		lowerLegf = new float[6][4];
		upperLegf = new float[6][4];
        NulRot    = new float[4];
	    wholebodyf1 = new float[4]; 
		wholebodyf2 = new float[4]; 
		wholebodyf3 = new float[4];
		lowerLegL = (SFRotation) getEventOut("lowerLegL");
		upperLegL = (SFRotation) getEventOut("upperLegL");
		lowerLegR = (SFRotation) getEventOut("lowerLegR");
		upperLegR = (SFRotation) getEventOut("upperLegR");
		wholebody = (SFRotation) getEventOut("wholebody");
		movers = new float[3];
		cont = (SFBool) getEventOut("cont");
		
		move = (SFVec3f) getEventOut ("move"); 
		rnd = new Random();
		help();
		

		
	}
	private void help() {
		
		lowerArmf[0][0] = lowerArmf[1][0] = lowerArmf[2][0] = lowerArmf[2][0] = 0.0f;
		lowerArmf[3][0] = lowerArmf[4][0] = lowerArmf[5][0] = 0.0f;
		lowerArmf[0][2] = lowerArmf[1][2] = lowerArmf[2][2] = lowerArmf[2][2] = 0.0f;
		lowerArmf[3][2] = lowerArmf[4][2] = lowerArmf[5][2] = 0.0f;
		lowerArmf[0][1] = lowerArmf[1][1] = lowerArmf[2][1] = lowerArmf[2][1] = 1.0f;
		lowerArmf[3][1] = lowerArmf[4][1] = lowerArmf[5][1] = 1.0f;
		lowerArmf[0][3] = 0.5f;
		lowerArmf[1][3] = 1.0f;
		lowerArmf[2][3] = 1.5f;
		lowerArmf[3][3] = 1.0f;
		lowerArmf[4][3] = 0.5f;
		lowerArmf[5][3] = 0.0f;
		times = 0;
		upperArmf[0][0] = upperArmf[1][0] = upperArmf[0][2] = upperArmf[1][2] = 0.0f;
		upperArmf[3][0] = upperArmf[2][0] = upperArmf[3][2] = upperArmf[2][2] = 0.0f;
		upperArmf[0][1] = upperArmf[1][1] = upperArmf[2][1] = upperArmf[3][1] = 1.0f;
		upperArmf[0][3] = -0.5f;
		upperArmf[1][3] = 0.0f;
		upperArmf[2][3] = 0.5f;
		upperArmf[3][3] = 0.0f;
		
		upperLegf[0][0] = upperLegf[1][0] = upperLegf[2][0] = upperLegf[3][0] = upperLegf[4][0] = 0.0f;
		upperLegf[0][2] = upperLegf[1][2] = upperLegf[2][2] = upperLegf[3][2] = upperLegf[4][2] = 0.0f;
		upperLegf[0][1] = upperLegf[1][1] = upperLegf[2][1] = upperLegf[3][1] = upperLegf[4][1] = 1.0f;
		upperLegf[4][1] = 1.0f;

		lowerLegf[0][0] = lowerLegf[1][0] = lowerLegf[2][0] = lowerLegf[3][0] = lowerLegf[4][0] = 0.0f;
		lowerLegf[0][2] = lowerLegf[1][2] = lowerLegf[2][2] = lowerLegf[3][2] = lowerLegf[4][2] = 0.0f;
		lowerLegf[0][1] = lowerLegf[1][1] = lowerLegf[2][1] = lowerLegf[3][1] = lowerLegf[4][1] = 1.0f;
		lowerLegf[4][1] = 1.0f;

		upperLegf[0][3] = 0.5f; 		lowerLegf[0][3] = -0.5f;
		upperLegf[1][3] = 0.5f; 		lowerLegf[1][3] = 0.0f;
		upperLegf[2][3] = 0.5f; 		lowerLegf[2][3] = -0.5f;
		upperLegf[3][3] = 0.0f; 		lowerLegf[3][3] = -0.5f;
		upperLegf[4][3] = -0.5f; 		lowerLegf[4][3] = 0.0f;
		upperLegf[5][3] = 0.0f; 		lowerLegf[5][3] = 0.0f;
		NulRot[1] = 1.0f;
		NulRot[2] = 1.0f;
		
		
		wholebodyf1[1] = wholebodyf2[1] = wholebodyf3[1] = 1.0f;
		
	}

	public void processEvent(Event e) {
		String eventName = e.getName();
		if(eventName.equals("timer")) { 
		  walk(((ConstSFFloat) e.getValue()).getValue());
		}
		else if (eventName.equals("turnin")) {
			rotations = true;
			BodyRotate();
			rotations = false;

		}
		else if (eventName.equals("stopin")) {
			goon = false;
			cont.setValue(goon);
			BodyStop();
		}
		else if (eventName.equals("playin")) {
			goon = true;
			continuous = true;
			cont.setValue(goon);
			goon = false;
		}
		else if (eventName.equals("walkin")) {
			goon = true;
			continuous = false;
			cont.setValue(goon);
		}
	}
    
	private void BodyRotate() {		
		switch(numberofTurns%4) 
		{
		case 0:
			wholebodyf1[3] = 0.524f;
			wholebodyf2[3] = 1.047f;
			wholebodyf3[3] = 1.571f;
			dx = 0.0f;
			dz = -1.0f;
			break;
		case 1:
			wholebodyf1[3] = 1.047f;
			wholebodyf2[3] = 2.094f;
			wholebodyf3[3] = 3.141f;
			dx = -1.0f;
			dz = 0.0f;
			break;
		case 2:
			wholebodyf1[3] = -0.52f;
			wholebodyf2[3] = -1.047f;
			wholebodyf3[3] = -1.571f;
			dx = 0.0f;
			dz = 1.0f;
			break;
		case 3:
			wholebodyf1[3] = 4.189f;
			wholebodyf2[3] = 8.378f;
			wholebodyf3[3] = 12.566f;
			dx = 1.0f;
			dz = 0.0f;
			break;
		}
		if (rotations)
			numberofTurns++;
		else
		{
		 numberofTurns = rnd.nextInt() + 1;
		 while((((orposx + 0.3) >= 16) && numberofTurns%4 == 3) || 
			  (((orposx - 0.3) <= -16) && numberofTurns%4 == 1) ||
			  (((orposz + 0.3) >= 6)  && numberofTurns%4 == 2) ||
			  (((orposz - 0.3) <= -6) && numberofTurns%4 == 0))
		 {
		 	numberofTurns = rnd.nextInt() + 1;
		 }
		}
		wholebody.setValue(wholebodyf1);
		wholebody.setValue(wholebodyf2);
		wholebody.setValue(wholebodyf3);
	}

	private void walk(float f) {
	 

	  System.out.println(f);
	  
	  lowerArmL.setValue(lowerArmf[times%6]);
	  lowerArmR.setValue(lowerArmf[(times+3)%6]);

	  if (times > 4)
	    {
	       upperArmL.setValue(upperArmf[(times-1)%4]);
	      upperArmR.setValue(upperArmf[(times+1)%4]);
	    }
	  else {
	    upperArmL.setValue(upperArmf[times%4]);
	    upperArmR.setValue(upperArmf[(times+2)%4]);
	  }
	   upperLegR.setValue(upperLegf[times%6]);
	   lowerLegR.setValue(lowerLegf[times%6]);
	   upperLegL.setValue(upperLegf[(times+3)%6]);
	   lowerLegL.setValue(lowerLegf[(times+3)%6]);
	   
	   orposx = orposx + 0.3f*dx;
	   orposz = orposz + 0.3f*dz;
	   movers[0] = orposx;
	   movers[1] = orposy;
	   movers[2] = orposz;
	   move.setValue(movers);
           times++;
	   start++; 
       if (times == 6)
	    times = 0;
	 
	   if ((start%10) == 0 && (start != 0))
	    {
		  BodyStop();
		  
		  if(continuous){
			  cont.setValue(goon);
		  //BodyStop();
		  }
		  else
		  {
			  BodyRotate();
		  }

		}
	   



	}

  
	private void BodyStop() {
		  upperLegR.setValue(NulRot);
	      lowerLegR.setValue(NulRot); 
	      upperLegL.setValue(NulRot); 
	      lowerLegL.setValue(NulRot);
          
		  upperArmR.setValue(NulRot);
	      lowerArmR.setValue(NulRot); 
	      upperArmL.setValue(NulRot); 
	      lowerArmL.setValue(NulRot);
		  
		  }
}