var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PageManager = void 0;
var path = require("path");
var Logger_1 = require("../Logger");
var KeyManager_1 = require("./KeyManager");
var fs = require("fs-extra");
var ensureDir = fs.ensureDir, pathExists = fs.pathExists, readdir = fs.readdir, readJSON = fs.readJSON, readJson = fs.readJson, writeFile = fs.writeFile;
var PageClass = require('./Page');
var PageManager = /** @class */ (function () {
    function PageManager() {
    }
    PageManager.prototype.load = function (callback) {
        var _this = this;
        this.managerConfigPath = path.join(Undecked.dataPath, 'pagemanager.json');
        this.managerDataPath = path.join(Undecked.dataPath, 'pages');
        this.KeyManager = new KeyManager_1.KeyManager();
        this.pages = {};
        this.order = [];
        (0, Logger_1.Log)('info', 'Loading pages');
        ensureDir(this.managerDataPath, function (err) {
            if (err)
                throw err;
            _this.loadConfig(function () {
                _this.order = _this.managerConfig.order || [];
                _this.loadPages(callback);
            });
        });
    };
    PageManager.prototype.loadConfig = function (callback) {
        var _this = this;
        pathExists(this.managerConfigPath, function (err, exists) {
            if (err)
                throw err;
            if (exists) {
                readJson(_this.managerConfigPath, function (err, json) {
                    if (err)
                        throw err;
                    _this.managerConfig = json;
                    callback();
                });
            }
            else {
                _this.managerConfig = defaultPageConfig;
                _this.saveConfig(callback);
            }
        });
    };
    PageManager.prototype.saveConfig = function (callback) {
        var toSave = {
            order: this.order
        };
        writeFile(this.managerConfigPath, JSON.stringify(toSave, null, 4), function (err) {
            if (err)
                (0, Logger_1.Log)('error', 'Error whilst saving manager config', err.message);
            if (callback)
                callback();
        });
    };
    PageManager.prototype.loadPages = function (callback) {
        var instance = this;
        readdir(this.managerDataPath, function (err, files) {
            if (err)
                throw err;
            (function readPage(i) {
                if (i === void 0) { i = 0; }
                if (files[i]) {
                    readJSON(path.join(instance.managerDataPath, files[i]), function (err, data) {
                        if (err)
                            (0, Logger_1.Log)('error', "Error whilst loading page ".concat(files[i].replace('.json', '')), err.message);
                        else
                            instance.pages[data.pageID] = new PageClass(data);
                        readPage(i + 1);
                    });
                }
                else {
                    (0, Logger_1.Log)('info', "Loaded ".concat(Object.keys(instance.pages).length, " page(s)"));
                    if (Object.keys(instance.pages).length > 0)
                        callback();
                    else {
                        instance.create('First page', callback);
                    }
                }
            })();
        });
    };
    PageManager.prototype.create = function (pageName, callback) {
        var existingPageIDs = Object.keys(this.pages);
        var pageID = Undecked.generateRandom(4, function (testrandom) {
            return !existingPageIDs.includes(testrandom);
        }, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
        this.pages[pageID] = new PageClass({
            pageID: pageID,
            name: "".concat(pageName, " (").concat(pageID, ")"),
            keys: {
                '0': { '0': { state: { type: 'pageup' } } },
                '1': { '0': { state: { type: 'currentpage' } } },
                '2': { '0': { state: { type: 'pagedown' } } }
            }
        });
        if (!this.order.includes(pageID))
            this.order.push(pageID);
        Undecked.SocketServer.broadcastTo('home', 'pagelist', this.getNames());
        this.pages[pageID].save(function () {
            (0, Logger_1.Log)('info', "Page ".concat(pageID, " has been created"));
            if (callback)
                callback();
        });
    };
    PageManager.prototype.exists = function (pageID) {
        return this.pages[pageID] != undefined;
    };
    PageManager.prototype.get = function (pageID) {
        if (this.exists(pageID))
            return this.pages[pageID];
        return null;
    };
    PageManager.prototype.getAll = function () {
        return this.pages;
    };
    PageManager.prototype.getIdByIndex = function (index) {
        var ids = this.order;
        if (ids[index])
            return ids[index];
        return null;
    };
    PageManager.prototype.getIndexById = function (id) {
        var ids = this.order;
        if (ids.includes(id))
            return ids.indexOf(id);
        return null;
    };
    PageManager.prototype.getNames = function () {
        var order = this.getOrder();
        var names = [];
        for (var i = 0; i < order.length; i++) {
            if (this.pages[order[i]] != undefined) {
                var page = this.pages[order[i]];
                names.push({ pageID: order[i], name: page.name });
            }
        }
        return names;
    };
    PageManager.prototype.getOrder = function () {
        var hasChanges = false;
        for (var pageID in this.pages) {
            if (!this.order.includes(pageID)) {
                this.order.push(pageID);
                hasChanges = true;
            }
        }
        for (var i = 0; i < this.order.length; i++) {
            if (this.pages[this.order[i]] == undefined) {
                this.order.splice(i, 1);
                i--;
                hasChanges = true;
            }
        }
        if (hasChanges)
            this.saveConfig();
        return this.order;
    };
    PageManager.prototype.setOrder = function (order) {
        var newOrder = [];
        for (var i = 0; i < order.length; i++)
            if (this.exists(order[i]))
                newOrder.push(order[i]);
        for (var pageID in this.pages)
            if (!newOrder.includes(pageID))
                newOrder.push(pageID);
        this.order = newOrder;
        for (var serialNumber in Undecked.Decks.decks)
            Undecked.Decks.decks[serialNumber].updateAll();
        Undecked.SocketServer.broadcastTo('home', 'pagelist', this.getNames());
        this.saveConfig();
    };
    PageManager.prototype.handleOperation = function (operation, originPageID, originX, originY, destinationPageID, destinationX, destinationY) {
        var _this = this;
        var findKey = function (pageID, x, y) {
            if (_this.exists(pageID)) {
                return _this.get(pageID).getKey(x, y);
            }
            return null;
        };
        var setKey = function (pageID, x, y, key, force) {
            if (force === void 0) { force = false; }
            if (_this.exists(pageID)) {
                return _this.get(pageID).updateKey(x, y, key, '-1', null, force);
            }
            return null;
        };
        var newKey = function () {
            return {
                state: { type: 'empty', confirm: false, toggle: false },
                appearence: {},
                actions: { down: {}, up: {}, latch: {}, unlatch: {} },
                id: Undecked.Pages.KeyManager.generateNew()
            };
        };
        var originKey = findKey(originPageID, originX, originY);
        var destinationKey = findKey(destinationPageID, destinationX, destinationY);
        var originKeyClone = JSON.parse(JSON.stringify(originKey));
        if (originKey && originKey.state.type == 'custom') {
            switch (operation) {
                case 'copy':
                    //FIXME: For some reason it doesnt copy the actions
                    if (destinationKey) {
                        var destinationKeyID = destinationKey.id;
                        var actions = originKeyClone.actions;
                        for (var actionsCategory in actions) {
                            for (var actionID in actions[actionsCategory]) {
                                actions[actionsCategory][actionID].id = Undecked.generateRandom(8, function (checkValid) {
                                    return actions[actionsCategory][actionID] == undefined;
                                });
                            }
                        }
                        setKey(destinationPageID, destinationX, destinationY, __assign(__assign({}, originKey), { actions: actions, id: destinationKeyID }), true);
                    }
                    break;
                case 'cut':
                    if (destinationKey) {
                        setKey(originPageID, originX, originY, newKey(), true);
                        setKey(destinationPageID, destinationX, destinationY, originKeyClone, true);
                    }
                    break;
                case 'ghost':
                    if (destinationKey) {
                        var originKeyID = originKey.id;
                        var destinationKeyID = destinationKey.id;
                        setKey(destinationPageID, destinationX, destinationY, {
                            id: destinationKeyID,
                            appearence: {},
                            state: {
                                type: 'ghost',
                                toggle: false,
                                confirm: false,
                                masterID: originKeyID
                            },
                            actions: {
                                up: {},
                                down: {},
                                latch: {},
                                unlatch: {}
                            }
                        }, true);
                        if (originKey.state.ghostIDs == undefined)
                            originKey.state.ghostIDs = [];
                        originKey.state.ghostIDs.push(destinationKeyID);
                    }
                    break;
                case 'delete':
                    setKey(originPageID, originX, originY, newKey(), true);
                    break;
            }
        }
    };
    return PageManager;
}());
exports.PageManager = PageManager;
var defaultPageConfig = {
    order: []
};
//# sourceMappingURL=PageManager.js.map