var frame_length = 50; // 20 fps

function animate(obj, property, unit, i_start, i_end, dur, trans) {

	this.obj = obj;
	this.property = property;
	this.unit = unit;
	this.i_start = i_start;
	this.i_end = i_end;
	this.dur = dur;
	this.trans = trans;
	this.start_time = null;
	this.complete = false;
	var me = this;
	this.runCallback = function() { me.run(); };

	this.start = start;
	this.delayed_start = delayed_start;
	this.run = run;
	this.set_value = set_value;


}

function start() {
	this.set_value();
	this.start_time = new Date().getTime(); 
	this.run();
}

function delayed_start(t) {
	this.start_time = new Date().getTime() + t; 
	this.run();
}

function run() {
	if (!this.complete) {
		this.set_value();
		setTimeout(this.runCallback, frame_length);
	} else {
		return;
	}
}

function set_value() {
	if (this.start_time == null) {
		with (this) obj.style[property] = String(trans(i_start)) + unit;
	} else {
		curr = (new Date().getTime() - this.start_time) / frame_length;
		if (curr >= this.dur) { // finished!
			with (this) obj.style[property] = String(trans(i_end)) + unit;
			this.complete = true;
		} else if (curr >= 0) {
			with (this) i_curr = ((curr / dur) * (i_end - i_start)) + i_start;
			with (this) obj.style[property] = String(trans(i_curr)) + unit;
		}
	}
}

function basic_trans(i) {
	return i;
}
