// A Working Gate Counter Applet - by Derek Molloy

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class GateCounter extends Applet implements ActionListener
{
	private Button start, toggle;
	private TextField gate1, gate2, total, gateDetailsTotal;
	private Counter gate1Counter, gate2Counter;
	private GateDetails gateDetails;

	public void init() 
	{
	  gate1 = new TextField(10);
	  gate2 = new TextField(10);
	  total = new TextField(10);
	  gateDetailsTotal = new TextField(10);
	  this.add(new Label("Gate1:"));
	  this.add(gate1);
	  this.add(new Label("Gate2:"));
	  this.add(gate2);
	  this.add(new Label("Total should be:"));
	  this.add(total);
	  this.add(new Label("Actual Total is:"));
	  this.add(gateDetailsTotal);

	  start = new Button("Start");
	  start.addActionListener(this);
	  this.add(start);

	  toggle = new Button("Toggle/Total");
	  toggle.addActionListener(this);
	  this.add(toggle);

	  gateDetails = new GateDetails();
	  this.gate1Counter = new Counter(gate1, gateDetails);
	  this.gate2Counter = new Counter(gate2, gateDetails);
	}
	
	public void actionPerformed(ActionEvent e) 
	{
	  if (e.getSource().equals(start))
	  {
	    this.gate1Counter.start();
	    this.gate2Counter.start();
	  }
	  else if (e.getSource().equals(toggle))
	  {
	    this.gate1Counter.toggleCounter();
	    this.gate2Counter.toggleCounter();
	
	    this.gateDetailsTotal.setText(""+gateDetails.getTotalSpectators());
	
	    int indivGateSum = this.gate1Counter.getCount() + this.gate2Counter.getCount();
	    this.total.setText(""+indivGateSum);
	  }
	}
} 


class GateDetails
{
	private int numberSpectators;

	public void spectatorEntered()
	{
		int tempInt = this.numberSpectators;
		try{ 
			Thread.currentThread().sleep(5);  //added to cause problems.
		}
		catch (InterruptedException e) 
		{
			System.out.println(e.toString());
		}
		tempInt++;
		this.numberSpectators = tempInt;
	}

	public int getTotalSpectators() { return numberSpectators; }
}



class Counter extends Thread
{
	private int count;
	private boolean running = true, paused = false;
	private TextField theField;
	private GateDetails gateDetails;

	
	public Counter(TextField t, GateDetails d)
	{
	  this.theField = t;
	  this.count = 0;
	  this.gateDetails = d;
	}

	public void run() 
	{
	  while (running) 
	  {
	    this.count++;
	    theField.setText("" + count);
	    gateDetails.spectatorEntered();
	    try 
	    { 
	      Thread.currentThread().sleep(1); 
	      synchronized(this)
	      {
              	while (paused)
                  wait();
	      }
            } 
	    catch (InterruptedException e)
	    {  
		theField.setText("Interrupted!");
		this.stopCounter();
	    }   
	  }
	}

	public int getCount() { return count; }

	public void stopCounter() { this.running = false; }

	public synchronized void toggleCounter()
	{ 
	  this.paused = !this.paused; 
	  if (!this.paused) notify();
	}
}
