/**
	Thread - Global Thread class
*/
function Thread(){
}
Thread.State = {NEW: 1, RUNNABLE: 2, BLOCKED: 3, WAITING: 4, TIMED_WAITING: 5, TERMINATED: 6};
Thread.ids = new Array();
Thread.createId = function(){Thread.ids[Thread.ids.length] = Thread.ids.length + 1; return Thread.ids[Thread.ids.length-1];}

/**
	IntervalThread - Executes the given code repeatedly with the given interval.
*/
function IntervalThread(runnable, interval){
	this.id = Thread.createId();
	this.runnable = runnable;
	this.interval = interval;
}

IntervalThread.prototype = {
	id: null,
	state: Thread.State.NEW,
	interval: 100, // The interval between two invokations of the runnable thing.
	nrOfInvokations: 0, // The number of times the runnable was invoked since Thread.start().
	runnable: null, // Function or object that should be executed.
	timeoutId: null, // Internal.
	
	start: function(){
		// Check if it hasn't already started and if all properties are set.
		if (this.state != Thread.State.NEW && this.state != Thread.State.TERMINATED){throw new Error('This thread (id=' + this.id + ') has already been started.');}
		if (isNaN(this.interval)){throw new Error('The interval for this thread (id=' + this.id + ') is not set properly (interval = ' + this.interval + ').');}
		if (this.runnable == null){throw new Error('This thread (id=' + this.id + ') has no runnable function or object.');}
		// Schedule the invocation of the runnable to occur directly after 
		// we return from this start() method.
		this.nrOfInvokations = 0;
		this.state = Thread.State.RUNNABLE;
		this.schedule(0);
	},
	
	run: function(){
		if (this.state == Thread.State.TERMINATED){throw new Error('This thread (id=' + this.id + ') has been terminated, so it can\'t be run().');}
		this.nrOfInvokations++;
		// Invoke our runnable thing.
		if (typeof(this.runnable) == 'function'){
			this.runnable(this);
		}else if (typeof(this.runnable) == 'object'){
			this.runnable.run(this);
		}
		// Schedule the next invocation of our runnable thing.
		this.schedule(this.interval);
	},
	
	terminate: function(){
		clearTimeout(this.timoutId);
		this.state = Thread.State.TERMINATED;
	},
	
	schedule: function(timeout){
		clearTimeout(this.timoutId);
		if (this.state == Thread.State.TERMINATED){return;}
		var thisThread = this;
		this.timoutId = setTimeout(function (){thisThread.run();}, timeout);
	},
	
	debug: function(message, level){
		alert(message);
	}
}