import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class HelloUniverse extends Applet {
Shape3D createLand(){
        LineArray landGeom = new LineArray(44, GeometryArray.COORDINATES
                                            | GeometryArray.COLOR_3);
        float l = -50.0f;
        for(int c = 0; c < 44; c+=4){

            landGeom.setCoordinate( c+0, new Point3f( -50.0f, 0.0f,  l ));
            landGeom.setCoordinate( c+1, new Point3f(  50.0f, 0.0f,  l ));
            landGeom.setCoordinate( c+2, new Point3f(   l   , 0.0f, -50.0f ));
            landGeom.setCoordinate( c+3, new Point3f(   l   , 0.0f,  50.0f ));
            l += 10.0f;
        }

        Color3f c = new Color3f(0.1f, 0.8f, 0.1f);
        for(int i = 0; i < 44; i++) landGeom.setColor( i, c);

        return new Shape3D(landGeom);
    }

    public void createSceneGraph() {
  // Create the root of the branch graph
  BranchGroup objRoot = new BranchGroup();

  // Create the transform group node and initialize it to the
  // identity.  Enable the TRANSFORM_WRITE capability so that
  // our behavior code can modify it at runtime.  Add it to the
  // root of the subgraph.
  TransformGroup objTrans = new TransformGroup();
  objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
  objRoot.addChild(objTrans);

  objRoot.addChild(createLand());
  
  BoundingSphere bounds =
      new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
    // Set up the global lights
  Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
  Vector3f lDir1  = new Vector3f(-1.0f, -1.0f, -1.0f);
  Color3f alColor = new Color3f(0.8f, 0.8f, 0.8f);
  AmbientLight aLgt = new AmbientLight(alColor);
  aLgt.setInfluencingBounds(bounds);
  DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
  lgt1.setInfluencingBounds(bounds);
  objRoot.addChild(aLgt);
  objRoot.addChild(lgt1);

  // Create a simple shape leaf node, add it to the scene graph.
  Appearance app = new Appearance();
  app.setMaterial(new Material());
  objTrans.addChild(new Sphere(2.0f, app));

  Transform3D yAxis = new Transform3D();
  Alpha alpha = new Alpha(-1, Alpha.INCREASING_ENABLE | Alpha.DECREASING_ENABLE,
          0, 0,
          20000, 500, 200,
          20000, 500, 200);

  float knots[] = { 0.0f, 0.25f, 0.5f, 0.75f, 1.0f };
  Point3f positions[] = { new Point3f(-20,0,0), new Point3f(0,10,0), 
    new Point3f(20f,0f,0f), new Point3f(0f,10f,20f), new Point3f(0f,0f,20f) };
          
  PositionPathInterpolator interp = new PositionPathInterpolator(
    alpha,
    objTrans,
    new Transform3D(),
    knots,
    positions);
  interp.setSchedulingBounds(bounds);
  objTrans.addChild(interp);
  
  

        GraphicsConfiguration config =
           SimpleUniverse.getPreferredConfiguration();
  Canvas3D c = new Canvas3D(config);
  add("Center", c);
        
        
  // Create a simple scene and attach it to the virtual universe
  SimpleUniverse u = new SimpleUniverse(c);


  Transform3D trans = new Transform3D();
  trans.set(new Vector3f(30,10,-10));
  u.getViewingPlatform().getViewPlatformTransform().setTransform(trans);
  
  LookAtBehavior look = new LookAtBehavior(u.getViewingPlatform().getViewPlatformTransform(),
         objTrans,
         bounds);

      objRoot.addChild(look);
        // Have Java 3D perform optimizations on this scene graph.
        objRoot.compile();
         u.addBranchGraph(objRoot);

    }

    public HelloUniverse() {
  setLayout(new BorderLayout());

  createSceneGraph();

    }

    //
    // The following allows HelloUniverse to be run as an application
    // as well as an applet
    //
    public static void main(String[] args) {
  new MainFrame(new HelloUniverse(), 256, 256);
    }
}
