// Simdistalg_applet.nw -- an applet for testing fault-tolerant
// distributed algorithms
// (c) 1997 by Felix Gaertner <theedge@rbg.informatik.tu-darmstadt.de>
// NOTE: DO NOT EDIT THIS FILE. See Simdistalg_applet.nw instead.

package simdistalg;

import eduni.simjava.*;
import eduni.simanim.*;
import java.awt.event.*; // for ActionListener, MouseListener
import java.awt.*; // for PopupMenu
import java.util.*; // for Enumeration and StringTokenizer

public class Simdistalg_applet extends Anim_applet implements MouseListener {
  public void anim_init() {
    trace_out.add(popup);
    trace_out.addMouseListener(this);
    Panel buttons = new Panel(new BorderLayout());
    Button perturb_b = new Button("perturb all");
    perturb_b.addActionListener(new Sim_fault_dispatcher());
    Button reset_b = new Button("reset all");
    reset_b.addActionListener(new Sim_fault_dispatcher());
    buttons.add("West", perturb_b);
    buttons.add("East", reset_b);
    this.add("North", buttons);
  }
  public void mousePressed(MouseEvent e) {
    // System.out.println("mouse over (" + e.getX() + "," + e.getY() + ")");
    for (Enumeration en=Sim_pos_entity.sim_pos_entity_list();
        en.hasMoreElements();) {
      Sim_pos_entity node = (Sim_pos_entity) en.nextElement();
      // System.out.println("looking at node " + node.get_name() +
      //     "; is at pos (" + node.get_x_pos() + "," +
      //     node.get_y_pos() + ")");
      Polygon pol = new Polygon();
      pol.addPoint(node.get_x_pos(), node.get_y_pos());
      if (node instanceof Sim_node) {
        pol.addPoint( node.get_x_pos() + node_pix_size,
            node.get_y_pos() + node_pix_size);
      } else {
        if (node instanceof Sim_unidir_channel) {
          pol.addPoint( node.get_x_pos() + channel_pix_size,
             node.get_y_pos() + channel_pix_size);
        } else {
          throw new IllegalArgumentException("unknown object class " +
              "in global entity list");
        }
      }
      Rectangle rec = new Rectangle(pol.getBounds());
      if (rec.contains(e.getX(), e.getY())) {
         // System.out.println("mouse is over node `" + node.get_name() + "'");
         popup.removeAll();
         if (node instanceof Sim_faulty_node) {
           String[] labels = new String[] {
             "go down", "go up", "reset", "perturb state", "go byzantine" };
           String[] actions = new String[] {
             "down", "up", "reset", "perturb", "byzantine" };
           MenuItem mi = new MenuItem(node.get_name());
           mi.setEnabled(false);
           popup.add(mi);
           popup.addSeparator();
           Sim_fault_dispatcher fault_maker = new Sim_fault_dispatcher();
           for (int j=0; j<labels.length; j++) {
             mi = new MenuItem(labels[j]);
             mi.setActionCommand(actions[j] + " " + node.get_name());
             mi.addActionListener(fault_maker);
             popup.add(mi);
           }
           popup.show(trace_out, e.getX(), e.getY());
         }
         else if (node instanceof Sim_faulty_channel) {
           String[] labels = new String[] {
             "go down", "go up", "reset", "perturb state" };
           String[] actions = new String[] {
             "down", "up", "reset", "perturb"  };
           MenuItem mi = new MenuItem(node.get_name());
           mi.setEnabled(false);
           popup.add(mi);
           popup.addSeparator();
           Sim_fault_dispatcher fault_maker = new Sim_fault_dispatcher();
           for (int j=0; j<labels.length; j++) {
             mi = new MenuItem(labels[j]);
             mi.setActionCommand(actions[j] + " " + node.get_name());
             mi.addActionListener(fault_maker);
             popup.add(mi);
           }
           /* Why doesn't this work? TODO */
           /*
           Menu del = new Menu("set avg. delay");
           popup.add(del);
           labels = new String[] { "1", "5", "10", "20", "50" };
           for (int j=0; j<labels.length; j++) {
             mi = new MenuItem(labels[j]);
             mi.setActionCommand("delay " + node.get_name() + " " + labels[j]);
             mi.addActionListener(fault_maker);
             del.add(mi);
           }
           Menu delay_plus = new Menu("set max. delay");
           popup.add(delay_plus);
           labels = new String[] { "1", "5", "10", "20", "50" };
           for (int j=0; j<labels.length; j++) {
             mi = new MenuItem(labels[j]);
             mi.setActionCommand("delay_plus " + node.get_name() + " " + labels[j]);
             mi.addActionListener(fault_maker);
             delay_plus.add(mi);
           }
           Menu delay_minus = new Menu("set min. delay");
           popup.add(delay_minus);
           labels = new String[] { "1", "5", "10", "20", "50" };
           for (int j=0; j<labels.length; j++) {
             mi = new MenuItem(labels[j]);
             mi.setActionCommand("delay_minus " + node.get_name() + " " + labels[j]);
             mi.addActionListener(fault_maker);
             delay_minus.add(mi);
           }
           Menu loss = new Menu("set loss rate");
           popup.add(loss);
           labels = new String[] { "0", "0.3", "0.5", "0.7", "0.9" };
           for (int j=0; j<labels.length; j++) {
             mi = new MenuItem(labels[j]);
             mi.setActionCommand("loss_rate " + node.get_name() + " " + labels[j]);
             mi.addActionListener(fault_maker);
             loss.add(mi);
           }
           Menu dup = new Menu("set duplicate rate");
           popup.add(dup);
           labels = new String[] { "0", "0.3", "0.5", "0.7", "0.9" };
           for (int j=0; j<labels.length; j++) {
             mi = new MenuItem(labels[j]);
             mi.setActionCommand("duplicate_rate " + node.get_name() + " " + labels[j]);
             mi.addActionListener(fault_maker);
             dup.add(mi);
           }
           Menu reo = new Menu("set reordering rate");
           popup.add(reo);
           labels = new String[] { "0", "0.3", "0.5", "0.7", "0.9" };
           for (int j=0; j<labels.length; j++) {
             mi = new MenuItem(labels[j]);
             mi.setActionCommand("reordering_rate " + node.get_name() + " " + labels[j]);
             mi.addActionListener(fault_maker);
             reo.add(mi);
           }
           */
           popup.show(trace_out, e.getX(), e.getY());
         }
         // don't build menu if not one of the fault interfaces is implemented
         break;
      }
    }
  }
  public void mouseClicked(MouseEvent e) {;}
  public void mouseEntered(MouseEvent e) {;}
  public void mouseExited(MouseEvent e) {;}
  public void mouseReleased(MouseEvent e) {;}
  public void anim_layout() {
    Sim_pos_entity.clear_entity_list();
  }
  protected PopupMenu popup = new PopupMenu();
  private static final int node_pix_size = 30;
  private static final int channel_pix_size = 20;
}


