"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var LoadScheduler = /** @class */ (function () {
    function LoadScheduler() {
        this.queues = new Map();
    }
    LoadScheduler.prototype.scheduleGfxLoading = function (load) {
        return this.schedule("gfxLoading", load);
    };
    LoadScheduler.prototype.scheduleActionExecution = function (execute) {
        return this.schedule("actionExecution", execute);
    };
    LoadScheduler.prototype.schedulePostUpdateManipulation = function (execute) {
        return this.schedule("postUpdateManipulation", execute);
    };
    LoadScheduler.prototype.schedule = function (type, cb) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _this.queue(type, function () {
                return cb()
                    .then(resolve)
                    .catch(reject);
            });
            if (_this.activeType === undefined) {
                // start execution of queue if nothing is currently active
                _this.executeType(type);
            }
        });
    };
    LoadScheduler.prototype.executeType = function (type) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var queue, _a, _b, _c, loadType, typeQueue;
            var e_1, _d;
            return tslib_1.__generator(this, function (_e) {
                switch (_e.label) {
                    case 0:
                        this.activeType = type;
                        queue = this.queues.get(type).splice(0);
                        return [4 /*yield*/, Promise.all(queue.map(function (cb) { return cb(); }))];
                    case 1:
                        _e.sent();
                        try {
                            // get the first queue with at least one entry and start execution
                            for (_a = tslib_1.__values(this.queues.entries()), _b = _a.next(); !_b.done; _b = _a.next()) {
                                _c = tslib_1.__read(_b.value, 2), loadType = _c[0], typeQueue = _c[1];
                                if (typeQueue.length > 0) {
                                    this.executeType(loadType);
                                    return [2 /*return*/];
                                }
                            }
                        }
                        catch (e_1_1) { e_1 = { error: e_1_1 }; }
                        finally {
                            try {
                                if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
                            }
                            finally { if (e_1) throw e_1.error; }
                        }
                        this.activeType = undefined;
                        return [2 /*return*/];
                }
            });
        });
    };
    LoadScheduler.prototype.queue = function (type, cb) {
        var queue = this.queues.get(type);
        // create and register the queue if it does not yet exist
        if (queue === undefined) {
            queue = [];
            this.queues.set(type, queue);
        }
        // add the cb to the queue
        queue.push(cb);
    };
    return LoadScheduler;
}());
exports.LoadScheduler = LoadScheduler;
