import java.util.*;

public class Timer implements Runnable
{
    public Timer()
    {
	myListeners = new ArrayList();
	myRunning = false;
	myThread = null;
	myTickPause = 1000;
    }
    
    public Timer(int duration, TimerListener tl)
    {
	this();
	myDuration = duration*1000;
	addListener(tl);
    }

    public void setPause(int pause)
    {
	myTickPause = pause;
    }

    public void addListener(TimerListener tl)
    {
	myListeners.add(tl);
    }

    public void removeListener(TimerListener tl)
    {
	myListeners.remove(tl);
    }

    public void start()
    {
	myThread = new Thread(this);
	myStartTime = new Date();
	myThread.setDaemon(true);
	myThread.start();
    }

    public void stop()
    {
	myRunning = false;
	myStopTime = new Date();
	for(int k=0; k < myListeners.size(); k++) {
	    ( (TimerListener) myListeners.get(k)).timerStopped(this);
	}
    }

    public void run()
    {
	myRunning = true;

	while (myRunning) {

	    try {
		pause();
	    }
	    catch (InterruptedException e) {
		myRunning = false;
		return;
	    }
	    
	    handleTicks();

	    if (isExpired()) {
		stop();
	    }
	}
    }

    public boolean isExpired()
    {
	myStopTime = new Date();
	return timeRemaining() <= 0;
    }

    public long timeRemaining()
    {
	myStopTime = new Date();
	long secs = myStopTime.getTime() - myStartTime.getTime();
	return myDuration - secs;
    }

    public void pause() throws InterruptedException
    {
//	System.out.println("timer pause");
	myThread.sleep(myTickPause);
    }

    public void handleTicks()
    {
//	System.out.println("timer tick "+timeRemaining());
	for(int k=0; k < myListeners.size(); k++) {
	    ( (TimerListener) myListeners.get(k)).timerTicked(this);
	}
    }

    private boolean myRunning;
    private long    myDuration;
    private Date    myStartTime;
    private Date    myStopTime;
    private Thread  myThread;
    private int     myTickPause;
    
    private List myListeners;
}
