package alive;

/**
 * <ALIVE Project>
 * Applet/Application StartUp Class
 * By Rogerio Neves
 * LSI - POLI - USP
 */

import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class Launcher extends Applet {
  private boolean isStandalone = false;
  static String version = new String("v1.0.2.0");
  String[] choices = {
      "Template - Alga",
      "xp1 - Predator-Prey System",
      "xp2 - Fish Schooling",
      "xp3 - Flocking Behavior",
      "ts1 - Physics Test",
      "ts2 - Food growth",
      "ts3 - 3D models"};
  EnvConfig config = new EnvConfig();
  Panel panelCenter = new Panel();
  Panel panelCtrl = new Panel();
  Panel panelWindow = new Panel();
  Panel panelBounds = new Panel();
  Panel panelBehaviors = new Panel();
  Panel panelPop = new Panel();
  Panel panelText = new Panel();
  Panel panelSleep = new Panel();
  Checkbox v[] = { new Checkbox(), new Checkbox(), new Checkbox(), new Checkbox(), new Checkbox(), new Checkbox() };
  Button update = new Button("Update");
  Button start = new Button("Start");
  Button end = new Button("Quit");
  TextField xMax = new TextField();
  Label labelVers = new Label(version);
  Label labelZ = new Label("Z");
  Label labBounds = new Label("Bounds");
  Label labelY = new Label("Y");
  TextField xMin = new TextField();
  Label labelX = new Label("X");
  TextField zMin = new TextField();
  TextField yMin = new TextField();
  TextField zMax = new TextField();
  TextField yMax = new TextField();
  Label labMax = new Label("Max");
  Label labMin = new Label("Min");
  Checkbox wrapy = new Checkbox("WrapY");
  Checkbox wrapz = new Checkbox("WrapZ");
  Checkbox wrapx = new Checkbox("WrapX");
  Label labWrapAround = new Label("Wrap Around");
  Label labx = new Label("x");
  TextField xSize = new TextField();
  Label labField = new Label("Field of View");
  TextField fieldView = new TextField();
  Checkbox autoSize = new Checkbox("Auto - Window Size");
  TextField ySize = new TextField();
  Checkbox keyNav = new Checkbox("Key Navigation");
  Checkbox mouseNav = new Checkbox("Mouse Navigation");
  Checkbox picking = new Checkbox("Mouse Picking");
  Checkbox log = new Checkbox("Log to file");
  Checkbox text = new Checkbox("Text output");
  TextField logFileName = new TextField("log_file");
  Checkbox linearMode = new Checkbox("Sequential (multi-threading off)");
  TextField popLimit = new TextField("500");
  Label labPopLimit = new Label("Population Limit");
  Label labDelay = new Label("Turn idle time (sleep):");
  TextField envDelay = new TextField();
  Panel panelXpSelect = new Panel();
  Choice xpChoice = new Choice();
  Label labBehaviors = new Label("Behaviors");
  Panel panelCam = new Panel();
  TextField zPos = new TextField();
  Label labCams = new Label("Cams");
  TextField yPos = new TextField();
  TextField xPos = new TextField();
  Label labelPosition = new Label("Position");
  Label labX = new Label("X");
  Label labY = new Label("Y");
  Label labZ = new Label("Z");
  Checkbox render = new Checkbox("Enable renderer");
  Checkbox fullScreen = new Checkbox("Full Screen");
  TextField eyeSep = new TextField();
  Checkbox stereo = new Checkbox("Stereo Separation");
  Panel panelView = new Panel();
  Checkbox svr = new Checkbox("Multicast to IP:PORT");
  TextField mip = new TextField();
  Panel panelVW = new Panel();
  Button viewCave = new Button("Cave");
  Button viewSingle = new Button("Single");
  Button viewFront = new Button("Front");
  Button viewAll = new Button("All");
  Label labDisplay = new Label("Display Setup");
  Label labPresets = new Label("Presets");

  // Start selected experiment
  void startChoice() {
    updateConfig();
    config.STAND_ALONE = false;
    if (xpChoice.getSelectedItem().startsWith("Template")) {
      XP_Template_Env env = new XP_Template_Env(config);
    }
    if (xpChoice.getSelectedItem().startsWith("xp1")) {
      xp1_Environment env = new xp1_Environment(config);
    }
    if (xpChoice.getSelectedItem().startsWith("xp2")) {
      xp2_Environment env = new xp2_Environment(config);
    }
    if (xpChoice.getSelectedItem().startsWith("xp3")) {
      xp3_Environment env = new xp3_Environment(config);
    }
    if (xpChoice.getSelectedItem().startsWith("ts1")) {
      xp0_Environment env = new xp0_Environment(config);
    }
    if (xpChoice.getSelectedItem().startsWith("ts2")) {
      xp1b_Environment env = new xp1b_Environment(config);
    }
    if (xpChoice.getSelectedItem().startsWith("ts3")) {
      XP_Test_Env env = new XP_Test_Env(config);
    }
  }

  //Initialize the applet
  public void init() {
    try { jbInit(); }
    catch(Exception e) { e.printStackTrace(); }
    updateSettings();
  }
  //Component initialization
  private void jbInit() throws Exception {
    this.setLayout(new BorderLayout());
    panelCenter.setLayout(null);
    v[0].setLabel("Left");
    v[1].setLabel("Front");
    v[2].setLabel("Right");
    v[3].setLabel("Ground");
    v[4].setLabel("Rear");
    v[5].setLabel("Top");
    v[0].setBounds(10, 25, 55, 25);
    v[1].setBounds(80, 25, 55, 25);
    v[2].setBounds(150, 25, 55, 25);
    v[3].setBounds(10, 50, 55, 25);
    v[4].setBounds(80, 50, 55, 25);
    v[5].setBounds(150, 50, 45, 25);
    viewSingle.setBounds(new Rectangle(230, 25, 70, 25));
    viewFront.setBounds(new Rectangle(300, 25, 69, 25));
    viewCave.setBounds(new Rectangle(230, 50, 70, 25));
    viewAll.setBounds(new Rectangle(300, 50, 69, 25));
    for(int i = 0; i<choices.length;i++) xpChoice.addItem(choices[i]);
    start.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) { startChoice();}});
    end.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {System.exit(0);}});
    update.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) { update_actionPerformed(e);}});
    log.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) {log_itemStateChanged();}});
    autoSize.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) {autoSize_itemStateChanged();}});
    svr.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) { svr_itemStateChanged();}});
    viewCave.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) { viewCave_actionPerformed();}});
    viewSingle.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) { viewSingle_actionPerformed();  }});
    viewFront.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) { viewFront_actionPerformed();  }});
    viewAll.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) { viewAll_actionPerformed();  }});
    panelBounds.setBounds(new Rectangle(3, 194, 311, 117));
    panelBounds.setLayout( new GridLayout(4,4));
    wrapx.setState(config.wrapx); wrapy.setState(config.wrapy); wrapz.setState(config.wrapz);
    panelWindow.setBounds(new Rectangle(3, 153, 428, 34));
    xSize.setColumns(4); ySize.setColumns(4);
    fieldView.setColumns(4);
    logFileName.setColumns(12);
    popLimit.setColumns(5);
    envDelay.setColumns(3);
    eyeSep.setColumns(4);
    panelBehaviors.setBounds(new Rectangle(327, 194, 158, 105));
    panelBehaviors.setLayout( new GridLayout(4,1));
    panelText.setBounds(new Rectangle(2, 120, 374, 34));
    panelPop.setBounds(new Rectangle(0, 320, 498, 34));
    panelSleep.setBounds(new Rectangle(1, 357, 501, 33));
    envDelay.setText(String.valueOf(config.SLEEP));
    panelXpSelect.setBounds(new Rectangle(0, 388, 501, 30));
    panelCam.setBounds(new Rectangle(383, 39, 94, 93));
    panelCam.setLayout( new GridLayout(4,2));
    xPos.setColumns(3); yPos.setColumns(3); zPos.setColumns(3);
    mip.setColumns(14); mip.setEditable(false);
    render.setState(config.RENDER);
    fullScreen.setState(config.FULL_SCREEN);
    stereo.setState(config.STEREO);
    panelView.setBounds(new Rectangle(2, 0, 500, 45));
    labDisplay.setBounds(new Rectangle(2, 0, 130, 23));
    labPresets.setBounds(new Rectangle(228, 2, 110, 22));
    panelSleep.add(labDelay, null);
    panelSleep.add(envDelay, null);
    panelSleep.add(svr);
    panelCenter.add(panelPop);
    panelCam.add(labCams);
    panelCam.add(labelPosition);
    panelCam.add(labX);
    panelCam.add(xPos);
    panelCam.add(labY);
    panelCam.add(yPos);
    panelCam.add(labZ);
    panelCam.add(zPos);
    panelCenter.add(panelVW);
    this.add("South", panelCtrl);
    panelVW.setBounds(new Rectangle(-1, 39, 378, 80));
    panelVW.setLayout(null);
    panelVW.add(v[0]);
    panelVW.add(v[1]);
    panelVW.add(v[2]);
    panelVW.add(v[3]);
    panelVW.add(v[4]);
    panelVW.add(v[5]);
    panelCtrl.add(update);
    panelCtrl.add(start);
    panelCtrl.add(end);
    panelCtrl.add(labelVers);
    this.add("Center",panelCenter);
    panelBounds.add(labBounds);
    panelBounds.add(labelX);
    panelBounds.add(labelY);
    panelBounds.add(labelZ);
    panelBounds.add(labMin);
    panelBounds.add(xMin);
    panelBounds.add(yMin);
    panelBounds.add(zMin);
    panelBounds.add(labMax);
    panelBounds.add(xMax);
    panelBounds.add(yMax);
    panelBounds.add(zMax);
    panelBounds.add(labWrapAround);
    panelBounds.add(wrapx);
    panelBounds.add(wrapy);
    panelBounds.add(wrapz);
    panelCenter.add(panelBehaviors);
    panelWindow.add(autoSize);
    panelWindow.add(xSize);
    panelWindow.add(labx);
    panelWindow.add(ySize);
    panelWindow.add(labField);
    panelWindow.add(fieldView);
    panelCenter.add(panelBounds);
    panelCenter.add(panelText);
    panelBehaviors.add(labBehaviors);
    panelBehaviors.add(keyNav);
    panelBehaviors.add(mouseNav);
    panelBehaviors.add(picking);
    panelText.add(text);
    panelText.add(log);
    panelText.add(logFileName);
    panelCenter.add(panelWindow);
    panelPop.add(labPopLimit);
    panelPop.add(popLimit);
    panelPop.add(linearMode);
    panelXpSelect.add(xpChoice);
    panelXpSelect.add(mip);
    panelCenter.add(panelSleep);
    panelView.add(render);
    panelView.add(fullScreen);
    panelView.add(stereo);
    panelView.add(eyeSep);
    panelVW.add(viewSingle);
    panelVW.add(viewCave);
    panelVW.add(viewAll);
    panelVW.add(viewFront);
    panelVW.add(labDisplay);
    panelVW.add(labPresets);
    panelCenter.add(panelXpSelect);
    panelCenter.add(panelCam);
    panelCenter.add(panelView);
  }

  //Get Applet information
  public String getAppletInfo() {
    return "ALIVE Applet Launcher " + version;
  }
  void viewSingle_actionPerformed() {
    updateConfig();
    for(int i=0;i<6;i++) v[i].setState(false);
    v[1].setState(true);
    xPos.setText("0"); yPos.setText("0");
    zPos.setText(String.valueOf(1.2*(config.xMax+config.yMax-config.xMin-config.yMin)/3));
    fieldView.setText("1.22");
  }
  void viewCave_actionPerformed() {
    updateConfig();
    for(int i=0;i<5;i++)  v[i].setState(true);
    v[5].setState(false);
    double val = (config.yMax-config.yMin)/4;
    xPos.setText("0"); yPos.setText(String.valueOf(val));; zPos.setText("0");
    fieldView.setText("1.57");
  }
  void viewFront_actionPerformed() {
    updateConfig();
    for(int i=0;i<3;i++)  v[i].setState(true);
    for(int i=3;i<6;i++)  v[i].setState(false);
    xPos.setText("0"); yPos.setText("0");
    zPos.setText(String.valueOf(config.zMax));
    fieldView.setText("1.57");
  }
  void viewAll_actionPerformed() {
    updateConfig();
    for(int i=0;i<6;i++)  v[i].setState(true);
    xPos.setText("0"); yPos.setText("0");; zPos.setText("0");
    fieldView.setText("1.57");
  }

  void autoSize_itemStateChanged() {
    if(!autoSize.getState()) {
      xSize.setEditable(true);
      ySize.setEditable(true);
    } else {
      xSize.setEditable(false);
      ySize.setEditable(false);
    }
  }
  void log_itemStateChanged() {
    if(log.getState()) logFileName.setEditable(true);
    else logFileName.setEditable(false);
  }
  void updateConfig() {
    config = new EnvConfig();
    for(int i=0;i<6;i++)  config.view[i] = v[i].getState();
    config.RENDER = render.getState();
    config.STEREO = this.stereo.getState();
    config.FULL_SCREEN = fullScreen.getState();
    config.EYE_SEPARATION = (double)Double.parseDouble(eyeSep.getText().trim());
    config.KEY_NAVIGATION = keyNav.getState();
    config.MOUSE_NAVIGATION = mouseNav.getState();
    config.PICKING = picking.getState();
    config.TEXT_OUTPUT = text.getState();
    config.ip = mip.getText();
    config.NET_CAST = svr.getState();
    if (log.getState()) config.logFile = logFileName.getText();
    if (isStandalone) config.codeBase = "file:./";
    else config.codeBase = getCodeBase().toString();
    config.AUTOSIZE = autoSize.getState();
    config.CAM_FIELD = (double)Double.parseDouble(fieldView.getText().trim());
    config.xSize = (int)Integer.parseInt(xSize.getText().trim());
    config.ySize = (int)Integer.parseInt(ySize.getText().trim());
    config.xPos = (double)Double.parseDouble(xPos.getText().trim());
    config.yPos = (double)Double.parseDouble(yPos.getText().trim());
    config.zPos = (double)Double.parseDouble(zPos.getText().trim());
    config.xMax = (double)Double.parseDouble(xMax.getText().trim());
    config.yMax = (double)Double.parseDouble(yMax.getText().trim());
    config.zMax = (double)Double.parseDouble(zMax.getText().trim());
    config.xMin = (double)Double.parseDouble(xMin.getText().trim());
    config.yMin = (double)Double.parseDouble(yMin.getText().trim());
    config.zMin = (double)Double.parseDouble(zMin.getText().trim());
    config.wrapx = wrapx.getState();
    config.wrapy = wrapy.getState();
    config.wrapz = wrapz.getState();
    config.POP_LIMIT = (double)Double.parseDouble(popLimit.getText().trim());
    config.SEQUENTIAL = linearMode.getState();
    config.SLEEP = (int)Integer.parseInt(envDelay.getText().trim());
  }
  void updateSettings() {
    keyNav.setState(config.KEY_NAVIGATION);
    mouseNav.setState(config.MOUSE_NAVIGATION);
    picking.setState(config.PICKING);
    eyeSep.setText(String.valueOf(config.EYE_SEPARATION));
    fieldView.setText(String.valueOf(config.CAM_FIELD));
    popLimit.setText(String.valueOf(config.POP_LIMIT));
    linearMode.setState(config.SEQUENTIAL);
    mip.setText(config.ip);
    svr.setState(config.NET_CAST); svr_itemStateChanged();
    for(int i=0;i<6;i++)  v[i].setState(config.view[i]);
    text.setState(config.TEXT_OUTPUT);
    if (config.logFile!=null) {
      log.setState(true);
      logFileName.setText(config.logFile);
      logFileName.setEditable(true);
    }
    else {
      log.setState(false);
      logFileName.setEditable(false);
    }
    autoSize.setState(config.AUTOSIZE);
    if (autoSize.getState()) {
      xSize.setEditable(false);
      ySize.setEditable(false);
    }
    xSize.setText(Integer.toString(config.xSize));
    ySize.setText(Integer.toString(config.ySize));
    xPos.setText(Double.toString(config.xPos));
    yPos.setText(Double.toString(config.yPos));
    zPos.setText(Double.toString(config.zPos));
    xMax.setText(Double.toString(config.xMax));
    yMax.setText(Double.toString(config.yMax));
    zMax.setText(Double.toString(config.zMax));
    xMin.setText(Double.toString(config.xMin));
    yMin.setText(Double.toString(config.yMin));
    zMin.setText(Double.toString(config.zMin));
  }

  void update_actionPerformed(ActionEvent e) {
    updateConfig();
  }

 //Main method
  public static void main(String[] args) {
    Launcher applet = new Launcher();
    applet.isStandalone = true;
    Frame frame = new Frame() {
      protected void processWindowEvent(WindowEvent e) {
        super.processWindowEvent(e);
        if (e.getID() == WindowEvent.WINDOW_CLOSING) { System.exit(0);}}
      public synchronized void setTitle(String title) {
        super.setTitle(title); enableEvents(AWTEvent.WINDOW_EVENT_MASK);}};
    frame.setTitle("ALIVE Launcher " + version);
    frame.add(applet, BorderLayout.CENTER);
    applet.init();
    applet.start();
    frame.setSize(500,500);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
    frame.setVisible(true);
  }

  double getVal(TextField f) {
    double d = (double)Double.parseDouble(f.getText().trim());
    if (d-d!=0) d = 0;
    return d;
  }

  void svr_itemStateChanged() {
    if (svr.getState()) mip.setEditable(true);
    else mip.setEditable(false);
  }
}
