/*
 *  @(#)Cube.java
 *  Written by Jyoti Sin
 */


import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.behaviors.keyboard.*;

// Cube4.java renders a box and keyNavigation Behavior for user represented as a box

public class Cube extends Applet implements KeyListener {

  TransformGroup targetTG;
  double rotAngle = 0.0;
  double rotInc = 10 * Math.PI / 180;
  float zTrans = 0.0f;
  float zInc = 0.05f;


  public void keyReleased(KeyEvent e) {

  }

  public void keyTyped(KeyEvent e) {

  }



  public void keyPressed(KeyEvent e) {
    // System.out.println(e);
    int c = e.getKeyCode();

    if (c == KeyEvent.VK_RIGHT)
      rotate(rotInc);

    if (c == KeyEvent.VK_LEFT)
      rotate(-rotInc);

    if (c == KeyEvent.VK_UP)
      translate(zInc);

    if (c == KeyEvent.VK_DOWN)
      translate(-zInc);

    System.out.println("keyDirection: " + c);
  }

  public void rotate(double inc) {
    rotAngle += inc;
    Transform3D rotation = new Transform3D();
    rotation.rotY(rotAngle);
		targetTG.setTransform(rotation);
		System.out.println("Rotating in Y-axis by a further "+ inc);
		printTransform3D(targetTG);
  }

  public void translate(double inc){
    Transform3D translation = new Transform3D();
    zTrans += inc;
    Vector3f moveVec = new Vector3f(0.0f, 0.0f, zTrans);
    translation.setTranslation(moveVec);
    targetTG.setTransform(translation);
    System.out.println("Translating in Z-dir by a further "+ inc);
		printTransform3D(targetTG);

  }

	public void printTransform3D(TransformGroup TG){
		Transform3D transform = new Transform3D();
		TG.getTransform(transform);
		System.out.println("The transform at the moment is "+transform);	
		
	}
  public BranchGroup createSceneGraph(SimpleUniverse su) {

	  // Create the root of the branch graph
	  BranchGroup objRoot = new BranchGroup();
	  createLights(objRoot);
	  //Create other scene graph content

	  TransformGroup cubeGroup = createWall(objRoot);
    objRoot.addChild(cubeGroup);


    //The targettg is the transform group on which changes take place on keyevent up down left right
    targetTG = su.getViewingPlatform().getViewPlatformTransform(); 
    printTransform3D(targetTG);

	  // Set up the background
	  BoundingSphere bgbounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
    Color3f bgColor = new Color3f(0.05f, 0.5f, 0.5f);
    Background bgNode = new Background(bgColor);
    bgNode.setApplicationBounds(bgbounds);
    objRoot.addChild(bgNode);


	// Let Java 3D perform optimizations on this scene graph.
    objRoot.compile();

	  return objRoot;
  } // end of CreateSceneGraph method


  private void createLights(BranchGroup scene) {
    AmbientLight lightA = new AmbientLight();
    lightA.setInfluencingBounds(new BoundingSphere());
    scene.addChild(lightA);

    DirectionalLight lightD1 = new DirectionalLight();
    lightD1.setInfluencingBounds(new BoundingSphere());
    Vector3f direction1 = new Vector3f(-1.0f, -1.0f, -0.5f);
    direction1.normalize();
    lightD1.setDirection(direction1);
    lightD1.setColor(new Color3f(0.0f, 0.0f, 1.0f));
    scene.addChild(lightD1);

    DirectionalLight lightD2 = new DirectionalLight();
    lightD2.setInfluencingBounds(new BoundingSphere());
    Vector3f direction2 = new Vector3f(1.0f, -1.0f, -0.5f);
    direction2.normalize();
    lightD2.setDirection(direction2);
    lightD2.setColor(new Color3f(1.0f, 0.0f, 0.0f));
    scene.addChild(lightD2);

  }



  private TransformGroup createWall(BranchGroup parent){


	 // rotate object has composited transformation matrix
	 Transform3D rotate = new Transform3D();
	 rotate.rotY(Math.PI/4.0d);



	 Appearance app = new Appearance();
	 ColoringAttributes ca = new ColoringAttributes();
	 ca.setColor(0.6f, 0.5f, 1.0f); //brown
	 app.setCapability(app.ALLOW_COLORING_ATTRIBUTES_WRITE);
	 app.setColoringAttributes(ca);

	// Box shape = new Box(0.1, 0.4, 0.2,app);
	 Shape3D shape = new Wall( 0.1f, 0.1f, 0.4f, 0.1f, app );

	 TransformGroup transform = new TransformGroup();

   transform.addChild(shape);

	 transform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
	 transform.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

	 return transform;
  }//end of createRotatedCube



  // Create a simple scene and attach it to the virtual universe
  public Cube() {
	  setLayout(new BorderLayout());
    Canvas3D canvas3D = new Canvas3D(null);
    add(BorderLayout.CENTER, canvas3D);
    canvas3D.addKeyListener(this);


    // SimpleUniverse is a Convenience Utility class
    // Sets up a Universe with a single view
    SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


	 BranchGroup scene = createSceneGraph(simpleU);


	// This will move the ViewPlatform back a bit so the
	// objects in the scene can be viewed.
    simpleU.getViewingPlatform().setNominalViewingTransform();

    simpleU.addBranchGraph(scene);
  } // end of Cube4 (constructor)



  //  The following allows this to be run as an application
  //  as well as an applet

  public static void main(String[] args) {
	Frame frame = new MainFrame(new Cube(), 500, 500);
  } // end of main (method of Cube4)

}


