function Timeout( theFunction, theInterval, start ){
	this.time = theInterval;
	this.remaining = theInterval;
	this.action = theFunction;
	if (start)
		this.start();
}

// Accessors

Timeout.prototype.remainingTime = function(){
	return (this.inProgress())
		? this.remaining - ((new Date()) - this.startTime)
		: this.remaining;
}

Timeout.prototype.inProgress = function(){
	return !!(this.timeout);
}

// Manipulators

Timeout.prototype.setAction = function( theFunction ){
	this.action = theFunction;
}

Timeout.prototype.setTime = function( theInterval ){
	this.time = theInterval;
	this.remaining = theInterval;
	if (this.inProgress())
		this.reset();
}

// Methods

Timeout.prototype.reset = function(t){
	this.clear();
	this.startTime = new Date();
	this.remaining = t || this.time;
	this.timeout = window.setTimeout( _timeout_closure(this), this.remaining );
}

Timeout.prototype.start = Timeout.prototype.reset;

function _timeout_closure(obj){ return function(){
	obj.timeout = undefined;
	obj.remaining = obj.time;
	if (obj.action) obj.action();
} }

Timeout.prototype.pause = function(){
	this.remaining = this.remainingTime();
	if (this.inProgress())
		window.clearTimeout(this.timeout);
	this.timeout = undefined;
}

Timeout.prototype.resume = function(){
	if (! this.inProgress())
		this.reset( this.remaining );
}

Timeout.prototype.clear = function(){
	if (this.inProgress())
		window.clearTimeout(this.timeout);
	this.timeout = undefined;
	this.remaining = this.time;
}

