/*----------------------------------------------------------------------+
|      Title:	Mothstats.java                                          |
|                                                                       |
|      Author:	David E. Joyce                                          |
|           Department of Mathematics and Computer Science              |
|           Clark University                                            |
|           Worcester, MA 01610-1477                                    |
|           U.S.A.                                                      |
|                                                                       |
|           http://aleph0.clarku.edu/~djoyce/home.html                  |
|           djoyce@clarku.edu                                           |
|                                                                       |
|      Date:    May, 2002.                                              |
+----------------------------------------------------------------------*/


import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
import java.util.StringTokenizer;

public class Mothstats extends Applet implements ActionListener,
 AdjustmentListener {

  // default parameters determined by html page
  int benefit;           // benefit from altruist, in 10ths of a unit
  int cost;              // cost to altruist, in 10ths of a unit
  int herd_size;         // each herd has this population
  int init_alt;          // how many initial altruists
  int deaths;            // this many die and are born each day in each herd
  int runs;              // how runs per simulation
  Color background;      // background color for applet

  Herdstats hs = new Herdstats();

  // Panels
  Panel controlPanel = new Panel();

  // Control Panel components
  Button startButton = new Button("Start");
  Button resetButton = new Button("Reset");
  Label deaths_label = new Label();
  Scrollbar deaths_scrollbar;
  Label herd_size_label = new Label();
  Scrollbar herd_size_scrollbar;
  Label init_alt_label = new Label();
  Scrollbar init_alt_scrollbar;
  Label cost_label = new Label();
  Scrollbar cost_scrollbar;
  Label benefit_label = new Label();
  Scrollbar benefit_scrollbar;
  Label runs_label = new Label();
  Scrollbar runs_scrollbar;

  // statistics  components
  BarGraph frequencyGraph;
  TextArea reportArea;

  public String getAppletInfo() {
    return
      "Velcrostats. Copyright 2002, David Joyce, Clark University. Version 1.0";
    }

  public String[][] getParameterInfo() {
    String[][] pinfo = {
	{"cost",             "int","cost to altruist in 10ths of a unit"},
	{"benefit",          "int","benefit from altruist in 10ts of a unit"},
        {"deaths",           "int","deaths per day in each herd"},
        {"herd_size",        "int","each herd has this population"},
        {"init_alt",         "int","how many initial altruists"},
	{"deaths",           "int","this many die and are born each day in each herd"},
	{"runs",             "int","how runs per simulation"},
    };
    return pinfo;
  }

  public void init() {
    // initialize the parameters
    String param = getParameter("cost");
    cost = (param == null) ? 10 : Integer.parseInt(param);

    param = getParameter("benefit");
    benefit = (param == null) ? 50 : Integer.parseInt(param);

    param = getParameter("deaths");
    deaths = (param == null) ? 5 : Integer.parseInt(param);

    param = getParameter("herd_size");
    herd_size = (param == null) ? 100 : Integer.parseInt(param);

    param = getParameter("init_alt");
    init_alt = (param == null) ? 10 : Integer.parseInt(param);

    param = getParameter("deaths");
    deaths = (param == null) ? 5 : Integer.parseInt(param);

    param = getParameter("runs");
    runs = (param == null) ? 100 : Integer.parseInt(param);

   // set up the stats computer
    hs.reset(cost, benefit, herd_size, init_alt, deaths);

    // construct and place the components in the window
    setLayout(new BorderLayout());
    add("West",controlPanel);

    // components of the start control panel
    controlPanel.setLayout(new GridLayout(7,2));

    startButton.addActionListener(this);
    controlPanel.add(startButton);

    resetButton.addActionListener(this);
    controlPanel.add(resetButton);

    controlPanel.add(herd_size_label);
    herd_size_label.setText("herd size: "+herd_size+"   ");
    herd_size_scrollbar = new Scrollbar (Scrollbar.HORIZONTAL, herd_size, 0, 1,
 10001);
    herd_size_scrollbar.addAdjustmentListener(this);
    controlPanel.add(herd_size_scrollbar);

    controlPanel.add(deaths_label);
    deaths_label.setText("death rate: "+deaths);
    deaths_scrollbar = new Scrollbar (Scrollbar.HORIZONTAL, deaths, 0, 1,
 herd_size/2);
    deaths_scrollbar.addAdjustmentListener(this);
    controlPanel.add(deaths_scrollbar);

    controlPanel.add(init_alt_label);
    init_alt_label.setText("altruists: "+init_alt+"   ");
    init_alt_scrollbar = new Scrollbar (Scrollbar.HORIZONTAL,
                         init_alt, 0, 1, herd_size+1);
    init_alt_scrollbar.addAdjustmentListener(this);
    controlPanel.add(init_alt_scrollbar);

    controlPanel.add(cost_label);
    cost_label.setText("cost: "+cost/10.0);
    cost_scrollbar = new Scrollbar (Scrollbar.HORIZONTAL, cost, 0, 1, 101);
    cost_scrollbar.addAdjustmentListener(this);
    controlPanel.add(cost_scrollbar);

    controlPanel.add(benefit_label);
    benefit_label.setText("benefit: "+benefit/10.0);
    benefit_scrollbar = new Scrollbar (Scrollbar.HORIZONTAL, benefit, 0, 1,
 101);
    benefit_scrollbar.addAdjustmentListener(this);
    controlPanel.add(benefit_scrollbar);

    controlPanel.add(runs_label);
    runs_label.setText("runs: "+runs+"   ");
    runs_scrollbar = new Scrollbar (Scrollbar.HORIZONTAL,
                         runs, 0, 1, 1001);
    runs_scrollbar.addAdjustmentListener(this);
    controlPanel.add(runs_scrollbar);

    // set up the frequency graph
    frequencyGraph = new BarGraph(1,hs.init_alt,1,runs,Color.black,Color.green);
    add("Center",frequencyGraph);

    // set up the report area
    reportArea = new TextArea(25,80);
    reportArea.setEditable(false);
    reportArea.setFont(new Font("Serif",Font.PLAIN,10));
    add("South",reportArea);
  }

  public void actionPerformed(ActionEvent e) {
    if (e.getActionCommand().equals("Start")) {
      startButton.setLabel("Stop");
      doSimulations();
    } else if (e.getActionCommand().equals("Stop")) {
      startButton.setLabel("Start");
    } else if (e.getActionCommand().equals("Reset")) {
      hs.reset(cost, benefit, herd_size, init_alt, deaths);
      frequencyGraph.clear();
      resetScrollBars();
    }
  }

  public void adjustmentValueChanged(AdjustmentEvent e) {
    if (e.getSource() == deaths_scrollbar) {
      hs.deaths = e.getValue();
      resetScrollBars();
    } else if (e.getSource() == herd_size_scrollbar) {
      hs.herd_size = e.getValue();
      if (hs.init_alt > hs.herd_size)
        hs.init_alt = hs.herd_size;
      resetScrollBars();
    } else if (e.getSource() == init_alt_scrollbar) {
      hs.init_alt = e.getValue();
      resetScrollBars();
    } else if (e.getSource() == cost_scrollbar) {
      hs.cost = e.getValue();
      resetScrollBars();
    } else if (e.getSource() == benefit_scrollbar) {
      hs.benefit = e.getValue();
      resetScrollBars();
    } else if (e.getSource() == runs_scrollbar) {
      runs = e.getValue();
      resetScrollBars();
    }
  }

  void resetScrollBars () {
    herd_size_label.setText("herd size: "+hs.herd_size);
    herd_size_scrollbar.setValue(hs.herd_size);
    deaths_label.setText("death rate: "+hs.deaths);
    deaths_scrollbar.setValue(hs.deaths);
    deaths_scrollbar.setMaximum(hs.herd_size/2);
    init_alt_label.setText("altruists: "+hs.init_alt);
    init_alt_scrollbar.setValue(hs.init_alt);
    init_alt_scrollbar.setMaximum(hs.herd_size+1);
    cost_label.setText("cost: "+hs.cost/10.0);
    cost_scrollbar.setValue(hs.cost);
    benefit_label.setText("benefit: "+hs.benefit/10.0);
    benefit_scrollbar.setValue(hs.benefit);
    runs_label.setText("runs: "+runs);
    runs_scrollbar.setValue(runs);
    repaint();
    try {Thread.currentThread().sleep(100);}
    catch (InterruptedException e){}
  }

  void doSimulations () {
    frequencyGraph.set(1,hs.init_alt,1,runs,Color.black,Color.green);
    reportArea.append("\n\n"+"Herd size: " + hs.herd_size+
        ". Deaths: " + hs.deaths+
	". Altruists: " + hs.init_alt+
	". Cost: " + hs.cost/10.0 +
        ". Benefit: " + hs.benefit/10.0 +".");
    reportArea.append("\n\ninitalt\tsel\talt\tavesel\tstdsel\tavealt\tstdalt");
    int max_alt = hs.init_alt;
    for (int i=1; i<=max_alt; ++i) {
      hs.init_alt = i;
      hs.doSimulation(runs);
      frequencyGraph.plot(i,hs.countalt);
      frequencyGraph.repaint();
      reportArea.append("\n"+i+"\t"+hs.getStats());
    }
    startButton.setLabel("Start");
  }

}

