package alive;

/**
 * <ALIVE Project>
 * ViewWindow start class
 * By Rogerio Neves
 * LSI - POLI - USP
 */

import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.Point3d;
import com.sun.j3d.utils.universe.*;

public class ViewWindow extends Frame {
  Environment env;
  Canvas3D c = null;
  View v = new View();
  TransformGroup tg = new TransformGroup();
  ViewPlatform vp = new ViewPlatform();
  PhysicalBody pb = new PhysicalBody();
  PhysicalEnvironment pe = new PhysicalEnvironment();
  GraphicsConfiguration cfg = null;
  Window w = null;
  String title;
  public int xSize,ySize,xScreenSize,yScreenSize,divs;
  public boolean stereo = true;
  public boolean fullScreen = true;
  public boolean envCall = false;
  public double field = 1.22;
  public double separation = 0.132;
  public boolean cave = false;

  public ViewWindow(Environment env, String title, int divs) {
    envCall = true;
    this.title = title;
    this.env = env;
    this.stereo = env.config.STEREO;
    this.fullScreen = env.config.FULL_SCREEN;
    this.field = env.config.CAM_FIELD;
    this.separation = env.config.EYE_SEPARATION;
    this.divs = divs;
    construct();
  }
  public ViewWindow(String title) {
    this.title = title;
    divs = 1;
  }
  public void construct() {
    if (stereo) {
      GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
      template.setStereo(template.REQUIRED);
      cfg = GraphicsEnvironment.getLocalGraphicsEnvironment()
          .getLocalGraphicsEnvironment().getDefaultScreenDevice()
          .getBestConfiguration(template);
    } else cfg = SimpleUniverse.getPreferredConfiguration();
    if (cfg==null) cfg = SimpleUniverse.getPreferredConfiguration();
    c = new Canvas3D(cfg);
    c.setStereoEnable(stereo);
    if (cave) fitCave();
    v.setFieldOfView(field);
    v.setBackClipDistance(50000f);
    pb.setLeftEyePosition(new Point3d(-1*separation/2, .0, .0));
    pb.setRightEyePosition(new Point3d(separation/2, .0, .0));
    setLayout(new BorderLayout());
    xScreenSize = (int)c.getScreen3D().getSize().getWidth();
    yScreenSize = (int)c.getScreen3D().getSize().getHeight();
    xSize = xScreenSize/divs;
    ySize = xSize;
    setSize(xSize,ySize);
    setTitle(title);
    if (fullScreen) {
      w = new Window(new Frame());
      w.add(c);
      w.setSize(Toolkit.getDefaultToolkit().getScreenSize());
    } else {
      add("Center", c);
    }
    v.addCanvas3D(c);
    v.setPhysicalBody(pb);
    v.setPhysicalEnvironment(pe);
    tg.addChild(vp);
    tg.setCapability(tg.ALLOW_TRANSFORM_WRITE);
    v.attachViewPlatform(vp);
    c.setVisible(true);
  }
  public void close() {
    c.stopRenderer();
    if (fullScreen) w.dispose();
    this.removeAll();
    this.dispose();
  }
  public void setVisible(boolean state) {
    if (fullScreen) {
      w.setVisible(state);
    } else {
      super.setVisible(state);
    }
  }
  public Canvas3D GetCanvas() {
      return c;  }
  public void fitCave() {
    c.getScreen3D().setPhysicalScreenHeight(3.0);
    c.getScreen3D().setPhysicalScreenWidth(3.0);
  }
  public View getView() {
      return v;  }
  public TransformGroup getTransformGroup() {
      return tg;  }
  public ViewPlatform getViewPlatform() {
      return vp;  }
  public void setTransform(Transform3D t) {
      tg.setTransform(t);  }
  public void startRenderer() {
    c.startRenderer();
    v.startView();
  }
  public void stopRenderer() {
    c.stopRenderer();
    v.stopView();
  }
  public boolean isRendererRunning() {
    return c.isRendererRunning();
  }
  //Overridden so we can exit when window is closed
  protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      if (envCall) env.destroy();
      else System.exit(0);
    }
  }
}
