Object.defineProperty(exports, "__esModule", { value: true });
exports.Deck = void 0;
var StreamDeck = require("@elgato-stream-deck/node");
var Jimp = require("jimp");
var canvas_1 = require("canvas");
var path = require("path");
var Logger_1 = require("../Logger");
(0, canvas_1.registerFont)(path.join(__filename, '..', '..', '..', '..', 'Static', 'font', 'Montserrat-ExtraLight.ttf'), {
    family: 'Montserrat',
    weight: '200'
});
(0, canvas_1.registerFont)(path.join(__filename, '..', '..', '..', '..', 'Static', 'font', 'Montserrat-Light.ttf'), {
    family: 'Montserrat',
    weight: '300'
});
(0, canvas_1.registerFont)(path.join(__filename, '..', '..', '..', '..', 'Static', 'font', 'Montserrat-Regular.ttf'), {
    family: 'Montserrat',
    weight: '400'
});
(0, canvas_1.registerFont)(path.join(__filename, '..', '..', '..', '..', 'Static', 'font', 'Montserrat-Medium.ttf'), {
    family: 'Montserrat',
    weight: '500'
});
(0, canvas_1.registerFont)(path.join(__filename, '..', '..', '..', '..', 'Static', 'font', 'Montserrat-SemiBold.ttf'), {
    family: 'Montserrat',
    weight: '600'
});
(0, canvas_1.registerFont)(path.join(__filename, '..', '..', '..', '..', 'Static', 'font', 'Montserrat-Bold.ttf'), {
    family: 'Montserrat',
    weight: '700'
});
(0, canvas_1.registerFont)(path.join(__filename, '..', '..', '..', '..', 'Static', 'font', 'Montserrat-ExtraBold.ttf'), {
    family: 'Montserrat',
    weight: '800'
});
var Deck = /** @class */ (function () {
    function Deck(settings, devicePath) {
        this.setDevicePath(devicePath);
        this.online = false;
        this.ready = false;
        this.name = settings.name;
        this.serialNumber = settings.serialNumber;
        this.model = settings.model;
        this.pageIndex = 0;
        this.captures = {
            confirm: {
                enabled: false,
                callback: null,
                callbacktriggers: []
            }
        };
    }
    Deck.prototype.export = function () {
        return {
            name: this.name,
            serialNumber: this.serialNumber,
            model: this.model
        };
    };
    Deck.prototype.init = function () {
        var _this = this;
        if (this.online) {
            this.columns = this.Deck.KEY_COLUMNS;
            this.rows = this.Deck.KEY_ROWS;
            this.keys = this.columns * this.rows;
            this.iconsize = this.Deck.ICON_SIZE;
            this.fill({ appearence: { background: { color: '#ffffff' } } });
            setTimeout(function () {
                _this.Deck.clearPanel();
                setTimeout(function () {
                    var coords = _this.getWaveCoords();
                    for (var i = 0; i < coords.length; i++)
                        _this.setKey(coords[i][0], coords[i][1], {
                            appearence: {
                                image: {
                                    address: path.join(__filename, '..', '..', '..', '..', 'Static', 'logo', 'single.png'),
                                    size: 100,
                                    offsetX: 0,
                                    offsetY: 0,
                                    rotation: 0
                                }
                            }
                        }, coords[i][2]);
                    setTimeout(function () {
                        var coords = _this.getWaveCoords();
                        for (var i = 0; i < coords.length; i++)
                            _this.setKey(coords[i][0], coords[i][1], {
                                state: {
                                    type: 'empty',
                                    toggle: false,
                                    confirm: false
                                },
                                appearence: {}
                            }, coords[i][2]);
                        setTimeout(function () {
                            var fadeCounter = 100;
                            var fadeInterval = setInterval(function () {
                                _this.Deck.setBrightness(fadeCounter);
                                if (fadeCounter > 0)
                                    fadeCounter--;
                                else {
                                    clearInterval(fadeInterval);
                                    _this.ready = true;
                                    (0, Logger_1.Log)('info', "Deck ".concat(_this.name, " is ready for rendering"));
                                    _this.updateAll();
                                    fadeInterval = setInterval(function () {
                                        _this.Deck.setBrightness(fadeCounter);
                                        if (fadeCounter < 100)
                                            fadeCounter++;
                                        else {
                                            clearInterval(fadeInterval);
                                        }
                                    }, 10);
                                }
                            }, 10);
                        }, 1000);
                    }, 1000);
                }, 1000);
            }, 300);
        }
    };
    Deck.prototype.setDevicePath = function (path) {
        var _this = this;
        if (path) {
            this.Deck = StreamDeck.openStreamDeck(path);
            this.listeners();
            this.online = true;
            this.Deck.on('error', function (error) {
                console.error("Deck:".concat(_this.name), error);
                _this.online = false;
            });
            this.init();
        }
    };
    Deck.prototype.handleKeyEvent = function (triggerKey, event) {
        var _this = this;
        var instance = this;
        var handleEvent = function (key) {
            switch (key.state.type) {
                case 'custom':
                    if (key.state.toggle == false) {
                        if (key.state.confirm == false) {
                            if (key.actions != undefined && key.actions[event] != undefined) {
                                Undecked.Integrations.executeActions(key.actions[event], instance);
                            }
                        }
                        else {
                            if (event == 'up')
                                _this.showConfirm(function (result) {
                                    if (result == true) {
                                        if (key.actions != undefined && key.actions.up != undefined)
                                            Undecked.Integrations.executeActions(key.actions.up, instance);
                                    }
                                });
                        }
                    }
                    else {
                        if (event == 'up') {
                            //When latched = true & When unlatch = false
                            var state = false;
                            if (key._internal != undefined && key._internal._toggle != undefined)
                                state = key._internal._toggle;
                            var location = Undecked.Pages.KeyManager.getLocation(key.id);
                            if (location) {
                                var handle = function () {
                                    Undecked.Pages
                                        .get(location.pageID)
                                        .setKeyInternal(location.x, location.y, '_toggle', !state);
                                    var namestate = !state ? 'latch' : 'unlatch';
                                    if (key.actions != undefined && key.actions[namestate] != undefined) {
                                        Undecked.Integrations.executeActions(key.actions[namestate], instance);
                                    }
                                };
                                if (key.state.confirm == true) {
                                    _this.showConfirm(function (result) {
                                        if (result == true)
                                            handle();
                                    });
                                }
                                else
                                    handle();
                            }
                        }
                        else {
                            if (key.state.confirm == false)
                                if (key.actions != undefined && key.actions[event] != undefined)
                                    Undecked.Integrations.executeActions(key.actions[event], instance);
                        }
                    }
                    break;
                case 'pageup':
                    if (event == 'down') {
                        var upPageID = Undecked.Pages.getIdByIndex(_this.pageIndex - 1);
                        if (upPageID)
                            _this.setPageID(upPageID);
                    }
                    break;
                case 'pagedown':
                    if (event == 'down') {
                        var downPageID = Undecked.Pages.getIdByIndex(_this.pageIndex + 1);
                        if (downPageID)
                            _this.setPageID(downPageID);
                    }
                    break;
            }
        };
        if (this.ready == true && triggerKey.state != undefined) {
            if (triggerKey.state.type == 'ghost') {
                if (triggerKey.state.masterID != undefined) {
                    var masterLocation = Undecked.Pages.KeyManager.getLocation(triggerKey.state.masterID);
                    var masterPage = Undecked.Pages.get(masterLocation.pageID);
                    if (masterPage) {
                        var masterKey = masterPage.getKey(masterLocation.x, masterLocation.y);
                        if (masterKey.state != undefined &&
                            masterKey.state.ghostIDs != undefined &&
                            masterKey.state.ghostIDs.includes(triggerKey.id))
                            handleEvent(masterKey);
                    }
                }
            }
            else
                handleEvent(triggerKey);
        }
    };
    Deck.prototype.listeners = function () {
        var _this = this;
        var instance = this;
        function indexToXY(index) {
            var y = Math.floor(index / instance.columns);
            var x = index - Math.floor(index / instance.columns) * instance.columns;
            return { x: x, y: y };
        }
        this.Deck.on('down', function (keyIndex) {
            var coords = indexToXY(keyIndex);
            if (Undecked.Pages.exists(instance.getPageID())) {
                var page = Undecked.Pages.get(instance.getPageID());
                var key = page.getKey(String(coords.x), String(coords.y));
                for (var captureType in _this.captures) {
                    if (_this.captures[captureType].enabled == true) {
                        return;
                    }
                }
                _this.handleKeyEvent(key, 'down');
            }
        });
        this.Deck.on('up', function (keyIndex) {
            var coords = indexToXY(keyIndex);
            if (Undecked.Pages.exists(instance.getPageID())) {
                var page = Undecked.Pages.get(instance.getPageID());
                var key = page.getKey(String(coords.x), String(coords.y));
                for (var captureType in _this.captures) {
                    if (_this.captures[captureType].enabled == true) {
                        if (_this.captures[captureType].callbacktriggers)
                            for (var i = 0; i < _this.captures[captureType].callbacktriggers.length; i++) {
                                var callbacktrigger = _this.captures[captureType].callbacktriggers[i];
                                if (coords.x == callbacktrigger[0] && coords.y == callbacktrigger[1]) {
                                    _this.captures[captureType].callback(callbacktrigger[2]);
                                    _this.captures[captureType].enabled = false;
                                    _this.captures[captureType].callback = null;
                                    return _this.updateAll();
                                }
                            }
                        return;
                    }
                }
                _this.handleKeyEvent(key, 'up');
            }
        });
    };
    Deck.prototype.setPageID = function (pageID) {
        var index = Undecked.Pages.getIndexById(pageID);
        if (index != this.pageIndex) {
            this.pageIndex = index;
            this.updateAll();
        }
    };
    Deck.prototype.getPageID = function () {
        return Undecked.Pages.getIdByIndex(this.pageIndex);
    };
    Deck.prototype.getName = function () {
        return this.name;
    };
    Deck.prototype.updateAll = function () {
        if (Undecked.Pages.exists(this.getPageID())) {
            var page = Undecked.Pages.get(this.getPageID());
            for (var x = 0; x < this.columns; x++) {
                for (var y = 0; y < this.rows; y++) {
                    this.setKey(x, y, page.getKey(String(x), String(y)));
                }
            }
        }
    };
    Deck.prototype.updateKey = function (x, y) {
        for (var captureType in this.captures)
            if (this.captures[captureType].enabled == true)
                return;
        if (Undecked.Pages.exists(this.getPageID())) {
            var page = Undecked.Pages.get(this.getPageID());
            this.setKey(x, y, page.requestKey(String(x), String(y)));
        }
    };
    Deck.prototype.fill = function (key) {
        for (var x = 0; x < this.columns; x++) {
            for (var y = 0; y < this.rows; y++) {
                this.setKey(x, y, key);
            }
        }
    };
    Deck.prototype.setKey = function (x, y, key, delay) {
        var _this = this;
        if (delay === void 0) { delay = 0; }
        if (x < this.columns && y < this.rows) {
            var keyIndex = y * this.columns + x;
            if (keyIndex < this.keys) {
                setTimeout(function () { return applyChanges(_this); }, delay);
            }
            var applyChanges = function (instance) {
                var canvas = (0, canvas_1.createCanvas)(Undecked.quality, Undecked.quality);
                var context = canvas.getContext('2d');
                context.textBaseline = 'middle';
                context.textAlign = 'center';
                if (key.state == undefined)
                    key.state = { type: 'custom' };
                if (key.state.type == 'empty') {
                    instance.Deck.clearKey(keyIndex);
                }
                else if (key.state.type == 'custom') {
                    var appearence = key.appearence;
                    render(appearence);
                }
                else if (key.state.type == 'ghost') {
                    var appearence = key.appearence;
                    appearence.system = {
                        ghost: true
                    };
                    render(appearence);
                }
                else if (key.state.type == 'pageup') {
                    render({
                        text: { value: 'Up', color: '#ffffff', size: 18, offsetX: 0, offsetY: 25 },
                        background: { color: '#4676b7' },
                        image: {
                            size: 100,
                            rotation: 0,
                            offsetX: 0,
                            offsetY: -15,
                            iconid: 'keyboard_arrow_up',
                            iconstyle: 'white'
                        },
                        system: {
                            border: {
                                color: '#253e5e',
                                thickness: 8
                            }
                        }
                    });
                }
                else if (key.state.type == 'pagedown') {
                    render({
                        text: { value: 'Down', color: '#ffffff', size: 18, offsetX: 0, offsetY: -25 },
                        background: { color: '#4676b7' },
                        image: {
                            size: 100,
                            rotation: 0,
                            offsetX: 0,
                            offsetY: 15,
                            iconid: 'keyboard_arrow_down',
                            iconstyle: 'white'
                        },
                        system: {
                            border: {
                                color: '#253e5e',
                                thickness: 8
                            }
                        }
                    });
                }
                else if (key.state.type == 'currentpage') {
                    render({
                        text: {
                            value: "Page\\n\\n".concat(instance.pageIndex + 1),
                            color: '#ffffff',
                            size: 22,
                            offsetX: 0,
                            offsetY: 0
                        },
                        background: { color: '#4676b7' },
                        system: {
                            border: {
                                color: '#253e5e',
                                thickness: 8
                            }
                        }
                    });
                }
                function render(appearence) {
                    function background(cb) {
                        if (appearence.background != undefined) {
                            context.fillStyle = appearence.background.color;
                            context.fillRect(0, 0, Undecked.quality, Undecked.quality);
                            context.fill();
                        }
                        cb();
                    }
                    function image(cb) {
                        if (appearence.image != undefined) {
                            var imageAddress = appearence.image.address != undefined
                                ? appearence.image.address
                                : appearence.image.iconid != undefined
                                    ? Undecked.Icons.getPath(appearence.image.iconid, appearence.image.iconstyle)
                                    : null;
                            var imageSize = appearence.image.size != undefined
                                ? appearence.image.size / 100 * Undecked.quality
                                : Undecked.quality;
                            if (imageAddress) {
                                var centerX = Undecked.quality / 2 + appearence.image.offsetX / 100 * Undecked.quality;
                                var centerY = Undecked.quality / 2 + appearence.image.offsetY / 100 * Undecked.quality;
                                (0, canvas_1.loadImage)(imageAddress).then(function (image) {
                                    context.save();
                                    context.translate(centerX, centerY);
                                    context.rotate(appearence.image.rotation * Math.PI / 180);
                                    context.drawImage(image, imageSize / 2 - imageSize, imageSize / 2 - imageSize, imageSize, imageSize);
                                    context.restore();
                                    cb();
                                });
                            }
                            else
                                cb();
                        }
                        else
                            cb();
                    }
                    function text(cb) {
                        if (appearence.text != undefined) {
                            context.fillStyle = appearence.text.color;
                            context.font = "700 ".concat(appearence.text.size * (Undecked.quality / 100), "px \"Montserrat\"");
                            var text = appearence.text.value;
                            var lineHeight = appearence.text.size * (Undecked.quality / 100);
                            var centerX = Undecked.quality / 2 + appearence.text.offsetX / 100 * (Undecked.quality * 2);
                            var centerY = Undecked.quality / 2 + appearence.text.offsetY / 100 * Undecked.quality;
                            var canvasYCounter = centerY;
                            var words = text != undefined ? text.replace(/\\n/g, ' \\n ').split(' ') : '';
                            var line = '';
                            var totalLineHeight = 0;
                            for (var n = 0; n < words.length; n++) {
                                if (words[n].length == 0)
                                    continue;
                                var testLine = line + words[n] + ' ';
                                var metrics = context.measureText(testLine);
                                var testWidth = metrics.width;
                                if (words[n] != '\\n')
                                    if (testWidth > Undecked.quality && n > 0) {
                                        line = words[n] + ' ';
                                        totalLineHeight += lineHeight;
                                    }
                                    else {
                                        line = testLine;
                                    }
                                else {
                                    totalLineHeight += lineHeight;
                                    line = '';
                                }
                            }
                            line = '';
                            canvasYCounter = canvasYCounter - totalLineHeight / 2;
                            var firstSkip = false;
                            for (var n = 0; n < words.length; n++) {
                                if (words[n].length == 0)
                                    continue;
                                var testLine = line + words[n] + ' ';
                                var metrics = context.measureText(testLine);
                                var testWidth = metrics.width;
                                if (words[n] != '\\n')
                                    if (testWidth > Undecked.quality && n > 0) {
                                        context.fillText(line, centerX, canvasYCounter);
                                        line = words[n] + ' ';
                                        canvasYCounter += lineHeight;
                                    }
                                    else {
                                        line = testLine;
                                    }
                                else {
                                    context.fillText(line, centerX, canvasYCounter);
                                    line = '';
                                    canvasYCounter += firstSkip ? lineHeight * 2 : lineHeight;
                                    if (firstSkip)
                                        firstSkip = false;
                                }
                            }
                            context.fillText(line, centerX, canvasYCounter);
                        }
                        cb();
                    }
                    function system(cb) {
                        if (appearence.system != undefined) {
                            if (appearence.system.border != undefined) {
                                var relativeThickness = appearence.system.border.thickness / 100 * Undecked.quality;
                                context.fillStyle = appearence.system.border.color;
                                context.fillRect(0, 0, Undecked.quality, relativeThickness);
                                context.rect(0, Undecked.quality - relativeThickness, Undecked.quality, relativeThickness);
                                context.rect(0, 0, relativeThickness, Undecked.quality);
                                context.rect(Undecked.quality - relativeThickness, 0, relativeThickness, Undecked.quality);
                                context.fill();
                            }
                            if (appearence.system.ghost == true) {
                                // var imageAddress = path.join(
                                // 	__filename,
                                // 	'..',
                                // 	'..',
                                // 	'..',
                                // 	'..',
                                // 	'Static',
                                // 	'icon',
                                // 	'ghost.png'
                                // );
                                // var size = 50 / 100 * Undecked.quality;
                                // loadImage(imageAddress).then((image) => {
                                // 	context.save();
                                // 	context.globalAlpha = 0.7;
                                // 	context.translate(Undecked.quality / 2, Undecked.quality / 2);
                                // 	context.drawImage(image, size / 2 - size, size / 2 - size, size, size);
                                // 	context.restore();
                                // 	cb();
                                // });
                            }
                        }
                        cb();
                    }
                    background(function () {
                        image(function () {
                            text(function () {
                                system(function () {
                                    Jimp.read(canvas.toBuffer())
                                        .then(function (img) {
                                        return img.resize(instance.iconsize, instance.iconsize);
                                    })
                                        .then(function (image) {
                                        instance.Deck.fillKeyBuffer(keyIndex, image.bitmap.data, {
                                            format: 'rgba'
                                        });
                                    });
                                });
                            });
                        });
                    });
                }
                // if (keyData.color != undefined)
                // 	instance.Deck.fillKeyColor(keyIndex, keyData.color.r, keyData.color.g, keyData.color.b);
                // if (keyData.image != undefined) {
            };
        }
    };
    Deck.prototype.showConfirm = function (callback) {
        var _this = this;
        var cancel = [
            0,
            0,
            false
        ];
        var deny = null;
        var confirm = null;
        if (this.columns % 2 == 0) {
            deny = [
                Math.floor(this.columns / 2) - 2,
                2,
                false
            ];
            confirm = [
                Math.floor(this.columns / 2) + 1,
                2,
                true
            ];
        }
        else {
            deny = [
                Math.floor(this.columns / 2) - 1,
                2,
                false
            ];
            confirm = [
                Math.floor(this.columns / 2) + 1,
                2,
                true
            ];
        }
        this.captures.confirm.enabled = true;
        this.captures.confirm.callbacktriggers = [
            cancel,
            deny,
            confirm
        ];
        this.captures.confirm.callback = callback;
        this.Deck.clearPanel();
        this.setKey(confirm[0], confirm[1], {
            appearence: {
                image: {
                    iconid: 'check',
                    iconstyle: 'white',
                    offsetX: 0,
                    offsetY: 0,
                    rotation: 0,
                    size: 100
                },
                background: {
                    color: '#4caf50'
                }
            }
        });
        this.setKey(deny[0], deny[1], {
            appearence: {
                image: {
                    iconid: 'clear',
                    iconstyle: 'white',
                    offsetX: 0,
                    offsetY: 0,
                    rotation: 0,
                    size: 100
                },
                background: {
                    color: '#f44336'
                }
            }
        });
        this.setKey(cancel[0], cancel[1], {
            appearence: {
                image: {
                    iconid: 'arrow_back',
                    iconstyle: 'white',
                    offsetX: 0,
                    offsetY: 0,
                    rotation: 0,
                    size: 100
                },
                background: {
                    color: '#000000'
                }
            }
        });
        var instance = this;
        var flickerList = [];
        function createText(value, x) {
            var data = {
                appearence: {
                    text: {
                        color: '#ffffff',
                        offsetX: 1,
                        offsetY: 0,
                        size: 30,
                        value: value
                    },
                    background: {
                        color: '#000000'
                    }
                }
            };
            instance.setKey(x, 1, data);
            flickerList.push({ x: x, data: data });
        }
        if (this.columns % 2 == 0) {
            createText('Are', 2);
            createText('you', 3);
            createText('sure', 4);
            createText('?', 5);
        }
        else {
            createText('Are', 1);
            createText('you', 2);
            createText('sure?', 3);
        }
        var flickerInterval = setInterval(function () {
            if (_this.captures.confirm.enabled == true) {
                for (var i = 0; i < flickerList.length; i++) {
                    var flickeritem = flickerList[i];
                    if (flickeritem.data.appearence.background.color == '#000000') {
                        flickeritem.data.appearence.background.color = '#ffffff';
                        flickeritem.data.appearence.text.color = '#000000';
                    }
                    else {
                        flickeritem.data.appearence.background.color = '#000000';
                        flickeritem.data.appearence.text.color = '#ffffff';
                    }
                    instance.setKey(flickeritem.x, 1, flickeritem.data);
                }
            }
            else
                clearInterval(flickerInterval);
        }, 500);
    };
    Deck.prototype.getWaveCoords = function () {
        var coords = [];
        for (var x0 = 0; x0 < 8; x0++) {
            var delay = x0;
            coords.push([
                x0,
                0,
                delay * 200
            ]);
        }
        for (var x1 = -1; x1 < 8; x1++) {
            var delay = x1 + 1;
            if (x1 >= 0)
                coords.push([
                    x1,
                    1,
                    delay * 200
                ]);
        }
        for (var x2 = -2; x2 < 8; x2++) {
            var delay = x2 + 2;
            if (x2 >= 0)
                coords.push([
                    x2,
                    2,
                    delay * 200
                ]);
        }
        for (var x3 = -3; x3 < 8; x3++) {
            var delay = x3 + 3;
            if (x3 >= 0)
                coords.push([
                    x3,
                    3,
                    delay * 200
                ]);
        }
        return coords;
    };
    return Deck;
}());
exports.Deck = Deck;
;
//# sourceMappingURL=Deck.js.map