'use strict';
function Scheduler(option){
    option        = option || {};
    this.timeout  = option.timeout  || 60*2*1000;
    this.duration = option.duration || 2000;
    this.abort    = false;
    this.doing    = false;
}

Scheduler.prototype._get_delay = function(){
    var delay = typeof this.duration === 'function'?this.duration(this.start_time):this.duration;
    delay = +delay;
    return delay <=0 && (delay = 2000),delay;
}

Scheduler.prototype.update = function(){
    var delay = this._get_delay() - (+new Date() - this.last_time);
    if (this.abort || this.doing) {
        return;
    }
    this.doing = true;
    setTimeout(function(){
        if (this.abort) {
            return;
        }
        this.last_time = +new Date();
        this.doing = false;
        this.callback();
    }.bind(this), delay);
}

Scheduler.prototype.begin = function(callback,success,failed){
    this.start_time = +new Date();
    this.last_time  = this.start_time;
    this.callback   = callback;
    this.success    = success;
    this.failed     = failed;
    this.abort      = false;
    this.callback();
    this.timeout_timer = setTimeout(function(){
        this.abort = true;
        if (typeof this.failed == 'function') {
            this.failed({code:1,TIMEOUT:1,CANCEL:2,UNKNOWN_ERROR:3});
        }
        delete this.timeout_timer;
    }.bind(this), this.timeout);
    return this;
}

Scheduler.prototype.cancel = function(){
    this.abort = true;
    if (this.timeout_timer) {
        clearTimeout(this.timeout_timer);
        delete this.timeout_timer;
    }
    if (typeof this.failed == 'function') {
        this.failed({code:2,TIMEOUT:1,CANCEL:2,UNKNOWN_ERROR:3});
    }
    return this;
}

Scheduler.prototype.end = function(){
    this.abort = true;
    if (this.timeout_timer) {
        clearTimeout(this.timeout_timer);
        delete this.timeout_timer;
    }
    if (typeof this.success == 'function') {
        this.success.apply(this,arguments);
    }
    return this;
}