/***
 * This class is simply a container for running monitors/scheduled tasks.
 * You can use it to schedule tasks that need to run on an interval
 * All you need to specify is a "name/id" for the task, a reference to the function/task that should be run,
 * how frequently the task should run, and the maximum number of times the task should be run.
 * 
 * There is only one interface speficication for using this class, and that is the function
 * that the reference you pass in points to must return a boolean value. If it returns TRUE,
 * the scheduler will continue executing the task on the regular interval, howerver if the
 * function returns FALSE, the scheduler will discontinue executing the task.
 *
 *
 * Usage:
 * ---------------------------------------
 * <script type="text/javascript" src="/javascript/lib_monitor.js" ></script>
 * <script type="text/javascript" >
 * 	window.monitor = new Monitor('monitor');
 * 	window.monitor.add(	'divUpdater',
 * 							function() {
 * 								var d = document.getElementById('myDiv');
 * 								if(d != null) {
 * 									d.innerHTML += '<br>content';
 * 								}
 * 							},
 * 							300,
 * 							10
 * 						);
 * 	//window.monitor.remove('divUpdater');
 * </script>
 *
 */
function Monitor(docKey) {			// docKey = the name of the variable in the window scope that holds an instance to this class
	this.docKey = docKey;
	this.monitors = new Array();
	this.add = add;
	this.remove = remove;
	this.runAndSchedule = runAndSchedule;
	
	/**
	 * Add a new scheduled task
	 * @param key	The name/id of the scheduled task
	 * @param ref	The reference to the function that should run at intervals
	 *				It should return a boolean value (true to keep task running, false to stop task)
	 *				and it should accept zero parameters
	 * @param freq	The frequency (in milliseconds) that this task should run (interval)
	 * @param maxRuns The maximum number of times the scheduled task should run before stopping (optional, 0=infinite)
	 * @return void
	 */
	function add(key, ref, freq) {
		var mp = 0;
		if(arguments.length > 3) {
			mp = arguments[3];	
		}
		this.monitors[ key ] = {
			key: key,
			ref: ref,
			frequency: freq,
			maxPolls: mp,
			numPolls: 0,
			stopRunning: false
		};
		
		this.runAndSchedule(key);		
	}


	/**
	 * Unschedule a scheduled task
	 * @param key	The name/id of the scheduled task to stop running
	 * @return void
	 */
	function remove(key) {
		this.monitors[ key ] = null;
	}
	
	
	/**
	 * Run the scheduled tasks and prevent them from running again if 
	 * necessary or schedule them to run again
	 * @param key	The name/id of the scheduled task to run
	 * @return void
	 */
	function runAndSchedule(key) {
		var m = this.monitors[ key ];
		if(m == null) return;

		// Delete the old timer
		if(m.timer != null) {
			clearTimeout(m.timer);
			m.timer == null;	
		}

		// Execute the function/task and record the result
		m.stopRunning = m.ref();
		m.numPolls = parseInt(m.numPolls) + parseInt(1);

		// If the task should be run again, then schedule it to run again
		if(  !(parseInt(m.maxPolls) > parseInt(0) && parseInt(m.numPolls) >= parseInt(m.maxPolls))  ) { //&& !eval(m.stopRunning)  
			m.timer = setTimeout(	'window.' + this.docKey + '.runAndSchedule(\'' + m.key + '\')',
									m.frequency
								);		
		}
	}

}
