// http://ajaxcookbook.org/transitions-animation-effects/

function Transition(curve, milliseconds, callback) {
    this.curve_ = curve;
    this.milliseconds_ = milliseconds;
    this.callback_ = callback;
    this.start_ = new Date().getTime();
    this.halt_ = false; // nrl
    var me = this;
    this.runCallback_ = function() {
        me.run();
    };
}

Transition.prototype.run = function() {
    if (!this.hasNext()) return;
    this.callback_(this.next());
    setTimeout(this.runCallback_, 10);
}

Transition.prototype.hasNext = function() {
	if (this.halt_) return false; // nrl
    if (this.done_) return this.oneLeft_;
    var now = new Date().getTime();
    if ((now - this.start_) > this.milliseconds_) {
        this.done_ = true;
        this.oneLeft_ = true;
    }
    return true;
}

Transition.prototype.next = function() {
    this.oneLeft_ = false;
    var now = new Date().getTime();
    var percentage = Math.min(1, (now - this.start_) / this.milliseconds_);
    return this.curve_(percentage);
}

Transition.prototype.halt = function() { // nrl
	this.halt_ = 1; // nrl
} // nrl

function SineCurve(percentage) {
    return (1 - Math.cos(percentage * Math.PI)) / 2;
}

function LinearCurve(percentage) {
    return percentage;
}