
import java.util.Observable;


/**
 * HeartBeat
 *
 * The model class of our little project.  It starts a thread that
 * simulates a heart beat.  The model presents a method that other
 * objects (controllers) can use to alter the rate of the heart beat.
 *
 *@author <a href="http://www.cs.indiana.edu/~cbaray/">cristobal baray</a> cbaray@cs.indiana.edu 
 */
public class HeartBeat
	extends Observable 
	implements Runnable
	{
		

	/** The smallest sleep duration */
	private static final long DURATION = 200;
	
	/** The excitement level of the heart */
	private long excitementLevel = 5;
	
	/** The number of beats counter */
	private long numberOfBeats = 0;
	
	/** The state of the model */
	private boolean running;
	
	/** An empty constructor */
	public HeartBeat() {
		running = true;
		new Thread(this).start();
	}
	
	/**
	 * The "heart" of the HeartBeat model.  
	 * The loop increments the beat counter, then sends updates
	 * to whoever subscribed, then goes to sleep for a 
	 * certain amount of time. The amount of time depends 
	 * on the current excitementLevel of the model.
 	 *
 	 */
	public void run() {
		while (running) {
			numberOfBeats++;
			updateObservers();
			try {
				Thread.sleep(DURATION * excitementLevel);
			} catch (InterruptedException e) {
			}
			
		}
	}
	
	/**
	 * Set the changed flag in the Observable object
	 * and then notify the observers with the current
	 * beat count.
	 *
	 * Each model might have it's own process for updating
	 * observers - for instance, they might need to build new
	 * data objects before sending the update - this is a good
	 * reason for separating the update method in the model.
	 * Also, if there is more than one way to trigger the update,
	 * a single update method is the smart way to go.
	 * Also, if there is more than one update in one model, 
	 * it might benefit from having separate methods as well.
	 */
	private void updateObservers() {
		setChanged();
		notifyObservers(new Long(numberOfBeats));
	}
	
	/**
	 * Adjusts the excitementLevel of the model by adding the
	 * delta value to the current  <code>excitementLevel</code>.  It also
	 * insures that the <code>excitementLevel</code> doesn't go below
	 * -1.
	 *
	 *@param delta The amount to change the excementLevel by.
	 */
	public void adjustExcitementLevel(long delta) {
		excitementLevel += delta;
		if (excitementLevel < 1) {
			excitementLevel = 1;
		}
		
	}
	
	/**
	 * Halts the heart...with no way to start it up again...
	 */
	public void stopHeart() {
		running = false;
	}
}

