 import java.applet.Applet;
 import java.awt.BorderLayout;
 import java.awt.Frame;
 import java.awt.event.*;
 import java.awt.event.WindowAdapter;
 import java.awt.*;
 import javax.swing.*;
 import com.sun.j3d.utils.applet.MainFrame;
 import com.sun.j3d.utils.universe.*;
 import com.sun.j3d.utils.geometry.Sphere;
 import com.sun.j3d.utils.behaviors.keyboard.*;
 import javax.media.j3d.*;
 import javax.vecmath.*;
 import java.awt.event.*;
 import java.util.Enumeration;
 import javax.media.j3d.*;

class SimpleBehavior extends Behavior implements ActionListener 
{
    private TransformGroup transformGroup;
    private Transform3D trans = new Transform3D();
    private WakeupCriterion criterion;
    private float angle = 0.0f;

    public SimpleBehavior(TransformGroup tg) 
    {
        transformGroup = tg;
    }

    public void initialize() 
    {
        criterion = new WakeupOnBehaviorPost(this,MouseEvent.MOUSE_CLICKED);
        wakeupOn(criterion);
    }

    public void processStimulus(Enumeration criteria) 
    {
        angle += Math.toRadians(10.0);
        trans.rotY(angle);
        transformGroup.setTransform(trans);
        wakeupOn(criterion);
    }

    public void actionPerformed(ActionEvent e) 
    {
        postId(MouseEvent.MOUSE_CLICKED);
    }
}


public class BasicTerrain extends Applet 
{
        private JButton btnRotate=null;
        public BranchGroup createSceneGraph(SimpleUniverse su) 
        {
         BranchGroup objRoot = new BranchGroup();
	
         //// add the terrain to the scene graph
         TransformGroup objTrans = new TransformGroup();
         objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
         objRoot.addChild(objTrans);
         objTrans.addChild(new Terrain());

         //// add the button click behavior to the scene graph
         SimpleBehavior simpleBehavior = new SimpleBehavior(objTrans);
         BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),100.0);
         simpleBehavior.setSchedulingBounds(bounds);
         objRoot.addChild(simpleBehavior);

         //// add the keyboard behavior to the scene graph
         TransformGroup vpTrans = su.getViewingPlatform().getViewPlatformTransform();
         Transform3D T3D= new Transform3D();
         Vector3f translate = new Vector3f( 0.0f, 0.3f, 0.0f); // 3 meter elevation
         T3D.setTranslation(translate); // set as translation
         vpTrans.setTransform(T3D); // used for initial position
         KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(vpTrans);
         keyNavBeh.setSchedulingBounds(new BoundingSphere(new Point3d(),1000.0));
         objRoot.addChild(keyNavBeh);

         ///// add a spot light         	
         PointLight aLight = new PointLight(new Color3f(1.0f,0.0f,0.0f),
                                                        new Point3f(-1.0f,-1.0f,-1.0f),
                                                        new Point3f(1.0f,0.0f,0.0f));
         aLight.setInfluencingBounds(new BoundingSphere());
         objRoot.addChild(aLight);

         ///// register the button handler to receive button clicks
         btnRotate.addActionListener(simpleBehavior);

         return objRoot;
      } // end of createSceneGraph method of HelloJava3Da

        public void init() 
        {
         setLayout(new BorderLayout());
         Canvas3D canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
         add("Center", canvas3D);
         btnRotate = new JButton("Rotate!");   
         add("South",btnRotate);

         SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
         BranchGroup scene = createSceneGraph(simpleU);

         simpleU.getViewingPlatform().setNominalViewingTransform();
         //scene.compile();
	
         simpleU.addBranchGraph(scene);
        } // end of init
        public static void main(String args[])
        {
                new MainFrame(new BasicTerrain(),256,256);
        }
}


class Terrain extends Shape3D
{
        private Geometry tGeometry;
        private Appearance tAppearance;
	
        public Terrain()
        {
                tGeometry = createGeometry();
                tAppearance = createAppearance();
                this.setGeometry(tGeometry);
                this.setAppearance(tAppearance);
        }
        private Geometry createGeometry()
        {
                Point3f p[]  = new Point3f[];
                p[0] = new Point3f(-1.0f,0.0f,0.0f);
                p[1] = new Point3f(0.0f,0.0f,2.0f);
                p[2] = new Point3f(0.0f,1.0f,2.0f);
                p[3] = new Point3f(0.0f,0.0f,2.0f);
                p[4] = new Point3f(0.0f,1.0f,2.0f);
                p[5] = new Point3f(1.0f,0.0f,0.0f);
                TriangleArray ta = new TriangleArray(p.size,TriangleArray.COORDINATES);
                ta.setCoordinates(0,p);
                return ta; 
/*              return new Sphere().getShape().getGeometry();                           */
        }	
        private Appearance createAppearance()
        {
                ColoringAttributes ca = null; /*new ColoringAttributes();*/
                /*ca.setColor (0.0f, 0.0f, 0.0f); */
                Appearance app = new Appearance();
                app.setColoringAttributes(ca);  
                Material m = new Material(    new Color3f(1.0f,0.0f,0.0f),
                                                        new Color3f(0.0f,0.0f,1.0f),
                                                        new Color3f(0.0f,0.0f,1.0f),
                                                        new Color3f(1.0f,0.0f,0.0f),
                                                        128.0f);
                m.setLightingEnable(true);
                app.setMaterial(m);
                return app;
        }
}
