StyleTween = function(options) {
	options.suffix = options.suffix ? options.suffix : '';
	this.options = options;
	this.start = new Date().getTime();
	this.timer = null;
	this.stopped = false;
	
	this._step = function() {
		clearTimeout(this.timer);
		if(this.stopped) return;
		var elapsed = new Date().getTime() - this.start;
		var ratio = Math.max(0, Math.min(1, parseFloat(elapsed) / parseFloat(this.options.duration)));
		
		var round = this.options.type == 'float' ? parseFloat : Math.ceil;
		var value = round(options.start + ((options.end - options.start) * options.func(ratio)) );
		this.options.element.style[options.property] = value + '' + options.suffix;
		
		if(elapsed < this.options.duration && (
			(this.options.start > this.options.end && value > this.options.end) ||
			(this.options.start < this.options.end && value < this.options.end)))
				this.timer = setTimeout(this._stepBound, 10);
	};
	
	this._stepBound = StyleTween.bind(this._step, this);
	
	this.options.element.style[options.property] = options.start + '' + options.suffix;	
	this._stepBound();
	
	this.stop = function() {
		this.stopped = true;
	}
}

StyleTween.bind = function(func, obj) {
	return function() {
		return func.call(obj);
	}
};

StyleTween.transition = {

	linear: function(ratio) {
		return ratio;
	},

	regular: {
		easeIn: function(ratio) {
			return Math.pow(ratio, 2);
		},
		easeOut: function(ratio) {
			return 1 - Math.pow(ratio - 1, 2);
		},
		easeInOut: function(ratio) {
			return -Math.cos(ratio*Math.PI)/2 + 0.5
		}
	},

	strong: {
		easeIn: function(ratio) {
			return Math.pow(ratio, 3);
		},
		easeOut: function(ratio) {
			return 1 + Math.pow(ratio - 1, 5);
		},
		easeInOut: function(ratio) {
			return -Math.cos(ratio*Math.PI)/2 + 0.5
		}
	}
	
};