//
// $Source: /home/cur/djb1/java/threads/RCS/StatusControl.java,v $
//
// $Id: StatusControl.java,v 1.3 1996/10/02 15:20:26 djb1 Exp $
//
// Simple Control and Status threads applet
//
// (C) Copyright 1996 Dave Beckett <D.J.Beckett@ukc.ac.uk>
// University of Kent at Canterbury
//

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

import java.lang.InterruptedException;

import CHAN_OF_INT;

//{{{  class SizedLabel
class SizedLabel extends Label
{
  // private member data
  private Dimension dimension;

  public SizedLabel (String label, int width, int height, int align)
  {
    super (label, align);

    dimension = new Dimension (width, height);
  }

  public Dimension preferredSize ()
  {
    return dimension;
  }
}

//}}}
//{{{  class ControlPanel
class ControlPanel extends Panel implements Runnable
{
  //{{{  private member data
  private Thread thread;
  private Button reset;
  private CHAN_OF_INT chan;
  private boolean button_clicked;
  
  //}}}
  //{{{  ControlPanel (CHAN_OF_INT chan)
  public ControlPanel (CHAN_OF_INT chan)
  {
    setLayout(new BorderLayout());
  
    this.chan=chan;
    button_clicked=false;
  
    reset = new Button ("Reset");
  
    add ("Center", reset);
  }
  
  //}}}
  //{{{  void run ()
  public void run ()
  {
    while (Thread.currentThread() == thread) {
      if (button_clicked) {
        try {
          System.out.println ("Control: Writing integer");
          chan.write(0);
          System.out.println ("Control: Write completed");
        } catch (InterruptedException e) {
          break;
        }
        button_clicked=false;
      }
      try {
        Thread.sleep(50);
      } catch (InterruptedException e) {
        break;
      }
    }
  }
  
  //}}}
  //{{{  void start ()
  public void start ()
  {
    if (thread == null)
      thread = new Thread(this, "Control");
    thread.start();
  }
  
  //}}}
  //{{{  void stop ()
  public void stop ()
  {
    thread = null;
  }
  
  //}}}
  //{{{  boolean action (Event event, Object arg)
  public boolean action (Event event, Object arg)
  {
    if (event.target == reset) {
      System.out.println ("Control: Reset button clicked");
      button_clicked = true;
      return true;
    } else {
      return super.action(event, arg);
    }
  }
  
  //}}}
  //{{{  void update (Graphics g)
  public void update (Graphics g) {
    paint(g);
  }
  
  //}}}
  //{{{  Insets insets ()
  // Put a little breathing space between the panel and its contents
  public Insets insets () {
    return new Insets(5,5,5,5);
  }
  //}}}
}

//}}}
//{{{  class StatusPanel
class StatusPanel extends Panel implements Runnable
{
  //{{{  private member data
  private Thread thread;
  private SizedLabel label;
  private int count;
  private CHAN_OF_INT chan;
  
  // Default number of milliseconds to wait between updates
  private static final long defaultPause = 1000;
  
  //}}}
  //{{{  StatusPanel (CHAN_OF_INT chan)
  StatusPanel (CHAN_OF_INT chan)
  {
    setLayout(new BorderLayout());
  
    this.chan=chan;
  
    label = new SizedLabel (new Integer(count).toString(), 100, 30, Label.CENTER);
  
    add("Center", label);
  }
  
  //}}}
  //{{{  void run ()
  public void run ()
  {
    // Remember the starting time.
    long startTime = System.currentTimeMillis();
  
    while (Thread.currentThread() == thread) {
      if (!chan.is_empty()) {
        try {
          int dummy = chan.read();
          System.out.println ("Status: Read completed - got "+dummy);
          count = 0;
        } catch (InterruptedException e) {
          break;
        }
      } else {
        count++;
      }
      label.setText(new Integer(count).toString());
      repaint();
      try {
        startTime += defaultPause;
        Thread.sleep(Math.max(0, startTime-System.currentTimeMillis()));
      } catch (InterruptedException e) {
        break;
      }
    }
  }
  
  //}}}
  //{{{  void start ()
  public void start ()
  {
    if (thread == null)
      thread = new Thread(this, "Status");
    thread.start();
  }
  
  //}}}
  //{{{  void stop ()
  public void stop ()
  {
    thread = null;
  }
  
  //}}}
  //{{{  void update (Graphics g)
  public void update (Graphics g) {
    paint(g);
  }
  
  //}}}
  //{{{  Insets insets ()
  // Put a little breathing space between the panel and its contents
  public Insets insets () {
    return new Insets(5,5,5,5);
  }
  //}}}
}

//}}}
//{{{  class StatusControl
public class StatusControl extends Applet
{
  //{{{  private member data
  private Label label;
  private ControlPanel control_panel;
  private StatusPanel status_panel;
  
  private CHAN_OF_INT chan;
  
  //}}}
  //{{{  void init ()
  // Called on class load
  public void init ()
  {
    System.out.println ("StatusControl:init()");
  
    chan = new CHAN_OF_INT();
  
    label = new Label("CHAN OF INT between control (left) and status (right)");
    control_panel = new ControlPanel(chan);
    status_panel = new StatusPanel(chan);
  
    add(label);
    add(control_panel);
    add(status_panel);
  
    // Cause all components to be created
    validate();
  }
  
  //}}}
  //{{{  void stop ()
  // Called on applet pausing
  public void stop ()
  {
    System.out.println ("StatusControl:stop()");
    control_panel.stop();
    status_panel.stop();
  }
  
  //}}}
  //{{{  void start()
  // Called on applet continuing
  public void start()
  {
    System.out.println ("StatusControl:start()");
    control_panel.start();
    status_panel.start();
  }
  
  //}}}
  //{{{  void destroy ()
  // Called on applet destruction
  public void destroy ()
  {
    System.out.println ("StatusControl:destroy()");
    control_panel.stop();
    control_panel = null;
  
    status_panel.stop();
    status_panel = null;
  }
  
  //}}}
  //{{{  update (Graphics g)
  public void update(Graphics g)
  {
    paint(g);
  }
  
  //}}}
  //{{{  Insets insets ()
  // Put a little breathing space between the panel and its contents
  public Insets insets () {
    return new Insets(5,5,5,5);
  }
  
  //}}}
  //{{{  String getAppletInfo ()
  public String getAppletInfo () {
    return "StatusControl by Dave Beckett <D.J.Beckett@ukc.ac.uk>";
  }
  //}}}
}
//}}}
