/*
 * Test driver for Logitech3DMouse.java.
 * Author: Eric Engstrom
 * Copyright (C) 2000 Eric Engstrom.
 */

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.Frame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;
import javax.swing.*; //for timer
import java.util.Enumeration;

public class Driver extends Frame implements WindowListener, ActionListener {

    Logitech3DMouse mouse;
    PhysicalEnvironment physicalEnvironment;
    View view;
    
   public Driver(String zPortName)
   {
      setLayout(new BorderLayout());
      
      VirtualUniverse univ = new VirtualUniverse();
      Locale locale = new Locale(univ);

        BranchGroup bg = new BranchGroup();

        bg.addChild(buildScenegraph());

          TransformGroup viewTG = new TransformGroup();

            Transform3D transform = new Transform3D();

          viewTG.setTransform(transform);
            
            ViewPlatform viewPlatform = new ViewPlatform();

              viewPlatform.setViewAttachPolicy(View.NOMINAL_SCREEN);

            view = new View();
            view.setViewPolicy(View.SCREEN_VIEW);
            view.setUserHeadToVworldEnable(true);
            //view.setCoexistenceCenteringEnable(false);

              physicalEnvironment = new PhysicalEnvironment();

                mouse = new Logitech3DMouse();
                mouse.setPort("/dev/term/b");

                if (!mouse.initialize())
                    System.exit(1);

              physicalEnvironment.addInputDevice(mouse);

                Sensor sensor = mouse.getSensor(0);

              physicalEnvironment.setSensor(0, sensor);
              //physicalEnvironment.setHeadIndex(0);
              //physicalEnvironment.setSensorCount(1);
              //physicalEnvironment.setCoexistenceCenterInPworldPolicy(View.NOMINAL_SCREEN);

            view.setPhysicalEnvironment(physicalEnvironment);

              GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
              Canvas3D canvas = new MyCanvas3D(config);

                Screen3D screen = canvas.getScreen3D();
                screen.setPhysicalScreenWidth(0.36);
                screen.setPhysicalScreenHeight(0.28);

                //Transform3D trackerBaseToImagePlate = new Transform3D();
                //trackerBaseToImagePlate.setTranslation(new Vector3d(0.18, 0, 0.31));
                //screen.setTrackerBaseToImagePlate(trackerBaseToImagePlate);

            view.addCanvas3D(canvas);
            view.attachViewPlatform(viewPlatform);

              PhysicalBody physicalBody = new PhysicalBody();

            view.setPhysicalBody(physicalBody);

          viewTG.addChild(viewPlatform);

        bg.addChild(viewTG);

      locale.addBranchGraph(bg);

      view.setTrackingEnable(true);
      

      add("Center", canvas);


      Timer myTimer = new Timer(30, this);
      myTimer.start();
      
      addWindowListener(this); //so we can catch a window close
      setSize(500, 500);
      show();

      System.out.println(physicalEnvironment.getTrackingAvailable());
      Enumeration enum = physicalEnvironment.getAllInputDevices();
      while (enum.hasMoreElements()) {
        System.out.println(enum.nextElement());
      }
   }

    public void actionPerformed(ActionEvent event) {
        Transform3D transform = new Transform3D();
        view.getUserHeadToVworld(transform);
        //System.out.println(transform);
    }
    
    public Node buildScenegraph() {
        Group root = new Group();
        
        int i, j, k;

        for (i = -1; i <= 1; i+=1) {
            for (j = -1; j <= 1; j+= 1) {
                for (k = -1; k <= 1; k+= 1) {
                    TransformGroup tg = new TransformGroup();
                    Transform3D t = new Transform3D();
                    t.setTranslation(new Vector3d(k, j, i));
                    t.setScale(0.1);
                    tg.setTransform(t);
                    ColorCube cube = new ColorCube();
                    tg.addChild(cube);
                    root.addChild(tg);
                }
            }
        }

        return root;
    }
    

   /**
    * Main is called if Driver is run as an application.
    * @param args command line arguments
    */
   public static void main(String[] args)
   {
      Driver theDriver = new Driver(args[0]);
   }


   /**
    * Called if window is closed. Reset and close the 3D Mouse, quit.
    * @param e the event (ignored)
    */
   public void windowClosing(WindowEvent e) 
   {
       physicalEnvironment.removeInputDevice(mouse);
       mouse.close();
       System.exit(0);
   }


   public void windowActivated(WindowEvent e) {}
   public void windowDeactivated(WindowEvent e) {}
   public void windowDeiconified(WindowEvent e) {}
   public void windowIconified(WindowEvent e) {}
   public void windowOpened(WindowEvent e) {}
   public void windowClosed(WindowEvent e) {}
}

class MyCanvas3D extends Canvas3D {
  public MyCanvas3D(GraphicsConfiguration config) {
    super(config);
  }

  public void paint(java.awt.Graphics g) {
    System.out.println("paint()");
    super.paint(g);
  }

  public void postRender() {
    System.out.println("postRender()");
    super.postRender();
  }

  public void postSwap() {
    System.out.println("postSwap()");
    super.postSwap();
  }

  public void preRender() {
    System.out.println("preRender()");
    super.preRender();
  }

  public void renderField(int fieldDesc) {
    System.out.println("renderField()");
    super.renderField(fieldDesc);
  }

  public void swap() {
    System.out.println("swap()");
    super.swap();
  }
}
