package alive;

/**
 * <ALIVE Project>
 * Basic User Interface class
 * By Rogerio Neves
 * LSI - POLI - USP
 */

import java.awt.*;
import java.awt.event.*;
import javax.vecmath.*;

public class UserInterface extends Frame {
  Environment env = null;
  Agent ag = null;
  Panel panel1 = new Panel();
  Panel panel2 = new Panel();
  Panel panel3 = new Panel();
  Panel panel4 = new Panel();
  Panel panel5 = new Panel();
  Panel panel6 = new Panel();
  Panel viewPanel = new Panel();
  public Panel ui = new Panel();
  TextArea tx = new TextArea();
  Button update = new Button("Update");
  Button info = new Button("Env Info");
  Button pause = new Button(" Pause ");
  Button end = new Button("End");
  Checkbox re = new Checkbox("Renderer Enable");
  Checkbox v1,v2,v3,v4,v5,v6;
  Button viewPrevious = new Button("<");
  TextField idField = new TextField("1");
  Button viewNext = new Button(">");
  Button view = new Button("View Agent Info");
  Button kill = new Button("Kill Agent");
  Label label1 = new Label("Sleep");
  TextField envDelay = new TextField();
  int loc = 0;
  Button reset = new Button("Reset");
  Checkbox brunt = new Checkbox("Exclusive",false);
  String oldDelay = "";
  Label label2 = new Label("Frame Count (0=Every Frame):");
  TextField fc = new TextField("0");

  //Construct the frame
  public UserInterface(Environment caller) {
    this.env = caller;
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try { jbInit(); } catch(Exception e) { e.printStackTrace(); }
  }

  //Component initialization
  private void jbInit() throws Exception  {
    this.setLayout(new BorderLayout());
    this.setSize(new Dimension(400, 400));
    this.setTitle("ALIVE Experiment Control UI");
    viewPanel.setLayout(new GridLayout(7,1));
    panel1.setLayout(new GridLayout(2,2));
    panel3.setLayout(new GridLayout(2,1));
    panel5.setLayout(new BorderLayout());
    idField.setColumns(5);
    update.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {update_actionPerformed();}});
    pause.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {pause_actionPerformed();}});
    envDelay.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {envDelay_actionPerformed();}});
    viewPrevious.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {viewPrevious_actionPerformed();}});
    viewNext.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {viewNext_actionPerformed();}});
    view.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {view_actionPerformed();}});
    idField.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {idField_actionPerformed();}});
    kill.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {kill_actionPerformed();}});
    end.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {end_actionPerformed();}});
    re.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) {re_itemStateChanged();}});
    info.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {info_actionPerformed();}});
    panel4.setLocale(java.util.Locale.getDefault());
    reset.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {reset_actionPerformed();}});
    brunt.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) {brunt_itemStateChanged();}});
    fc.setColumns(4);
    viewPanel.add(re, null);
    re.setState(env.config.RENDER);
    if (env.v[0]!=null) {
      v1 = new Checkbox();
      v1.setLabel(env.v[0].getTitle());
      v1.setState(true);
      v1.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) {v1_itemStateChanged();}});
      viewPanel.add(v1, null);
    }
    if (env.v[1]!=null) {
      v2 = new Checkbox();
      v2.setLabel(env.v[1].getTitle());
      v2.setState(env.v[1].isRendererRunning());
      v2.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) {v2_itemStateChanged();}});
      viewPanel.add(v2, null);
    }
    if (env.v[2]!=null) {
      v3 = new Checkbox();
      v3.setLabel(env.v[2].getTitle());
      v3.setState(env.v[2].isRendererRunning());
      v3.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) { v3_itemStateChanged();}});
      viewPanel.add(v3, null);
    }
    if (env.v[3]!=null) {
      v4 = new Checkbox();
      v4.setLabel(env.v[3].getTitle());
      v4.setState(env.v[3].isRendererRunning());
      v4.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) { v4_itemStateChanged();}});
      viewPanel.add(v4, null);
    }
    if (env.v[4]!=null) {
      v5 = new Checkbox();
      v5.setLabel(env.v[4].getTitle());
      v5.setState(env.v[4].isRendererRunning());
      v5.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) { v5_itemStateChanged();}});
      viewPanel.add(v5, null);
    }
    if (env.v[5]!=null) {
      v6 = new Checkbox();
      v6.setLabel(env.v[5].getTitle());
      v6.setState(env.v[5].isRendererRunning());
      v6.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) { v6_itemStateChanged();}});
      viewPanel.add(v6, null);
    }
    envDelay.setColumns(3);
    envDelay.setText(String.valueOf(env.config.SLEEP));
    panel1.add(viewPanel);
    panel1.add(ui);
    panel4.add(label1);
    panel4.add(envDelay);
    panel4.add(brunt);
    panel4.add(label2, null);
    panel4.add(fc, null);
    panel3.add(panel6);
    panel6.add(viewPrevious);
    panel6.add(idField);
    panel6.add(viewNext);
    panel6.add(view);
    panel6.add(kill);
    panel3.add(panel4);
    panel1.add(panel5);
    panel5.add(tx, BorderLayout.CENTER);
    panel1.add(panel3);
    panel2.add(reset);
    panel2.add(update);
    panel2.add(info);
    panel2.add(pause);
    panel2.add(end);
    this.add(panel1, BorderLayout.CENTER);
    this.add(panel2,  BorderLayout.SOUTH);
  }

  // --------------------------- Actions -------------------------------
  void reset_actionPerformed() {
    tx.setText("");
    idField.setText("");
    env.resetView();
  }
  void update_actionPerformed() {
    env.config.SLEEP = getInt(envDelay);
    String s = new String(tx.getText());
    int i = 0, statPos = 0, lineStart = 0, max = s.length(), agn = -1;
    boolean f = true, stat = false, envParm = false;
    while (f&&i<max) {
      if (s.charAt(i)==' ') {
        try { agn = (int)Integer.parseInt(s.substring(0, i).trim()); }
        catch(NumberFormatException e) { agn = -1; }
        f = false;
      }
      i++;
    }
    if (s.startsWith("Env")) { envParm = true; agn = 0; }
    if (agn>-1) {
      while (i<max) {
        if (s.charAt(i)=='=') {
          stat = true;
          statPos = i;
        }
        if (s.charAt(i)==10) {
          if (stat) {
            if (envParm) env.setParm(s.substring(lineStart,statPos).trim(),
                                   getDouble(s.substring(statPos+1,i).trim()));
            else env.setAgentParam(agn,
                                   s.substring(lineStart,statPos).trim(),
                                   getDouble(s.substring(statPos+1,i).trim()));
          }
          lineStart = i + 1;
          stat = false;
        }
        i++;
      }
      view_actionPerformed();
    }
  }
  void info_actionPerformed() {
    tx.setText(env.getInfo());
  }
  void pause_actionPerformed() {
    env.PAUSED = !env.PAUSED;
    if (env.PAUSED) pause.setLabel("Resume");
    else pause.setLabel("Pause");
  }
  void re_itemStateChanged() {
    if (re.getState()) env.renderEnabled = true;
    else env.renderEnabled = false;
  }
  void end_actionPerformed() {
    env.destroy();
  }
  void envDelay_actionPerformed() {
    env.config.SLEEP= getInt(envDelay);
  }
  void brunt_itemStateChanged() {
    if (brunt.getState()) {
      tx.setText("");
      oldDelay = new String(envDelay.getText());
      envDelay.setText("0");
      re.setState(false);
      re_itemStateChanged();
      update_actionPerformed();
    } else {
      tx.setText("");
      envDelay.setText(oldDelay);
      if (getInt(envDelay)==0) envDelay.setText("1");
      re.setState(true);
      re_itemStateChanged();
      update_actionPerformed();
    }
  }
  // --------------------------- viewWindows -------------------------------
  void v1_itemStateChanged() {
    if (v1.getState()) env.v[0].startRenderer();
    else env.v[0].stopRenderer();
  }
  void v2_itemStateChanged() {
    if (v2.getState()) env.v[1].startRenderer();
    else env.v[1].stopRenderer();
  }
  void v3_itemStateChanged() {
    if (v3.getState()) env.v[2].startRenderer();
    else env.v[2].stopRenderer();
  }
  void v4_itemStateChanged() {
    if (v4.getState()) env.v[3].startRenderer();
    else env.v[3].stopRenderer();
  }
  void v5_itemStateChanged() {
    if (v5.getState()) env.v[4].startRenderer();
    else env.v[4].stopRenderer();
  }
  void v6_itemStateChanged() {
    if (v6.getState()) env.v[5].startRenderer();
    else env.v[5].stopRenderer();
  }

  // --------------------------- viewAgents -------------------------------
  void view_actionPerformed() {
    int id = getInt(idField);
    id = Math.abs(id);
    Agent a = env.findAgent(id);
    if (a==null) tx.setText("Out of Bounds");
    else {
      tx.setText(a.getInfo());
      idField.setText(String.valueOf(a.id));
      if (env.config.RENDER) {
        a.actor.setColor(new Color3f(0f, 0f, 0f));
        a.highLight();
      }
      //System.out.println("INFO(" + a.id + "," + a.highlightTime +")");
    }
  }
  void viewPrevious_actionPerformed() {
    int i = env.agents.size()-1;
    Agent a = null;
    int id = -1+(int)getInt(idField);
    id = Math.abs(id);
    while (a == null && i >= 0) {
      ag = env.getAgent(i);
      if (ag.id <= id)
        a = ag;
      i--;
    }
    if (a != null)  idField.setText(String.valueOf(a.id));
    else  if (ag!=null) idField.setText(String.valueOf(ag.id));
    if (env.agents.isEmpty()) idField.setText("empty");
    view_actionPerformed();
  }
  void viewNext_actionPerformed() {
    int id = getInt(idField);
    if (env.agents.isEmpty()) idField.setText("empty");
    else idField.setText(String.valueOf(id+1));
    view_actionPerformed();
  }
  void idField_actionPerformed() {
    view_actionPerformed();
  }
  void kill_actionPerformed() {
    int id = getInt(idField);
    id = Math.abs(id);
    Agent a = env.findAgent(id);
    if (a!=null) if (a.id==id) env.killAgent(a);
    view_actionPerformed();
  }

  // --------------------------- convert -------------------------------
  double getDouble(TextField f) {
    return env.getDouble(f.getText());
  }
  double getDouble(String f) {
    return env.getDouble(f);
  }
  float getFloat(TextField f) {
    return env.getFloat(f.getText());
  }
  float getFloat(String f) {
    return env.getFloat(f);
  }
  int getInt(TextField f) {
    return env.getInt(f.getText());
  }
  int getInt(String f) {
    return env.getInt(f);
  }

  //Overridden so we can exit when window is closed
  protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      end_actionPerformed();
    }
  }
}