class ScheduleItem {
    constructor(callFunction, requeue, waitFunction) {
        this.callFunction = callFunction;
        this.waitFunction = waitFunction;
        this.requeue = requeue;
    }
}
export class SchedulerWorker {
    constructor(millisconds) {
        this.running = false;
        this.millisconds = millisconds;
        this.preItems = {};
        this.items = {};
        this.postItems = {};
    }
    addToPreSchedule(name, operation, requeueError = false, waitFor) {
        this.preItems[name] = new ScheduleItem(operation, requeueError, waitFor);
        if (!this.running) {
            setTimeout(this.processItems.bind(this), this.millisconds);
            this.running = true;
        }
    }
    addToSchedule(name, operation, requeueError = false, waitFor) {
        this.items[name] = new ScheduleItem(operation, requeueError, waitFor);
        if (!this.running) {
            setTimeout(this.processItems.bind(this), this.millisconds);
            this.running = true;
        }
    }
    addToPostSchedule(name, operation, requeueError = false, waitFor) {
        this.postItems[name] = new ScheduleItem(operation, requeueError, waitFor);
        if (!this.running) {
            setTimeout(this.processItems.bind(this), this.millisconds);
            this.running = true;
        }
    }
    processItems() {
        let requeue = false;
        for (let item in this.preItems) {
            if (this.processOneItem(item, this.preItems))
                requeue = true;
        }
        for (let item in this.items) {
            if (this.processOneItem(item, this.items))
                requeue = true;
        }
        for (let item in this.postItems) {
            if (this.processOneItem(item, this.postItems))
                requeue = true;
        }
        if (requeue) {
            setTimeout(this.processItems.bind(this), this.millisconds);
        }
        else {
            this.running = false;
        }
    }
    processOneItem(item, items) {
        let i = items[item];
        try {
            if (i.waitFunction) {
                if (i.waitFunction()) {
                    //                    console.log('waiting')
                    return true;
                }
            }
            i.callFunction();
        }
        catch (e) {
            //            console.log('error processing item', e);
            if (!i.requeue) {
                delete this.items[item];
                return false;
            }
            else {
                return true;
            }
        }
        delete items[item];
        return false;
    }
}
export class Scheduler {
    static getScheduler(name, millseconds = 10) {
        let scheduler = this.schedulers[name];
        if (!scheduler) {
            scheduler = new SchedulerWorker(millseconds);
            this.schedulers[name] = scheduler;
        }
        // if its not already running, reset the time
        if (!scheduler.running)
            scheduler.millisconds = millseconds;
        return scheduler;
    }
}
Scheduler.schedulers = {};
//# sourceMappingURL=Scheduler.js.map