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.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;


public class LineTest extends Applet {

    private SimpleUniverse u = null;

    public BranchGroup createSceneGraph() {
      // Create the root of the branch graph
      BranchGroup objRoot = new BranchGroup();

      // Create a new line and add it to the scene
      Java3dLine line = new Java3dLine();
      objRoot.addChild( line );

      // Create a new behavior that adds a point to the line every 50 ms
      BoundingSphere bounds =
          new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
      TimerBehavior tb = new TimerBehavior( line );
      tb.setSchedulingBounds(bounds);
      objRoot.addChild( tb );

      return objRoot;
    }

    public LineTest() {
    }

    public void init() {
      setLayout(new BorderLayout());
           GraphicsConfiguration config =
              SimpleUniverse.getPreferredConfiguration();

      Canvas3D c = new Canvas3D(config);
      add("Center", c);

      // Create a simple scene and attach it to the virtual universe
      BranchGroup scene = createSceneGraph();
      u = new SimpleUniverse(c);

      // This will move the ViewPlatform back a bit so the
      // objects in the scene can be viewed.
      u.getViewingPlatform().setNominalViewingTransform();

      OrbitBehavior orbit = new OrbitBehavior(c,
                OrbitBehavior.REVERSE_ALL);
      BoundingSphere bounds =
          new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
      orbit.setSchedulingBounds(bounds);
      u.getViewingPlatform().setViewPlatformBehavior(orbit);

      u.addBranchGraph(scene);
    }

    public void destroy() {
      u.removeAllLocales();
    }

    //
    // The following allows PolygonTest to be run as an application
    // as well as an applet
    //
    public static void main(String[] args) {
      new MainFrame(new LineTest(), 256, 256);
    }
}


// Behavior class
// It wakes up every 50 ms and adds a new point to the line
class TimerBehavior  extends Behavior
{
   int wakeupTimeMS = 50;
   double time_m = 0.0;
   Java3dLine line = null;


   public TimerBehavior( Java3dLine line )
   {
      this.line = line;
   }


   public void  initialize()
   {
      wakeupOn( new WakeupOnElapsedTime(wakeupTimeMS) );
   }


   public void processStimulus(java.util.Enumeration criteria)
   {
      time_m+= Math.PI*0.01;

      // Calculate next point on a circlular path
      double s = Math.sin(time_m);
      double c = Math.cos(time_m);
      double x=0.0, y=0.0, z=0.0;
      double radius = 0.5;

      x = c*radius;
      y = s*radius;
      z = -1.0;

      // Add the new point to the line
      line.addPoint(new Point3d(x, y, z));

      wakeupOn( new WakeupOnElapsedTime(wakeupTimeMS) );
   }
}
