var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};
var _server;
import { h } from "@stencil/core";
export class OptionCreator {
    constructor() {
        this.value = [];
        _server.set(this, window.BCE.file);
        this.handleInput = (event, index) => {
            const input = event.target;
            if (!input)
                return;
            // Update value
            const copy = [...this.value];
            const update = Object.assign(Object.assign({}, this.value[index]), { text: input.value });
            copy.splice(index, 1, update);
            this.updateValue(copy);
            event.stopPropagation();
        };
        this.handleKeyDown = async (event, index) => {
            switch (event.keyCode) {
                case 8: // Backspace
                    const target = event.target;
                    if (!target.value && index != 0) {
                        this.focusOption(index - 1);
                        this.handleRemove(index);
                    }
                    return;
                case 13: //Enter
                    return this.addOption();
            }
        };
        this.handleOther = () => {
            this.other = !this.other;
            this.value = this.other
                ? [...this.value, { text: this.label.labelOCOther || '' }]
                : this.value.slice(0, -1);
            this.onOther.emit(this.other);
        };
        this.handleRemove = (index) => {
            const copy = [...this.value];
            copy.splice(index, 1);
            this.updateValue(copy);
        };
        this.handleColor = (index) => { };
        this.handleImage = (index) => {
            const current = this.value[index];
            if ('image' in current && current.image)
                this.deleteImage(current, index);
            else
                this.uploadImage(index);
        };
    }
    watchValue(value) {
        if (!value.length)
            this.addOption(false);
    }
    async addOption(focus = true) {
        const insert = { text: '' };
        const value = this.other
            ? [...this.value.slice(0, -1), insert, ...this.value.slice(-1)]
            : [...this.value, insert];
        this.updateValue(value);
        if (focus)
            this.focusLast(true);
    }
    async focusLast(nextTick) {
        return this.focusOption(-(this.other ? 2 : 1), nextTick);
    }
    async focusOption(index, nextTick = false) {
        if (nextTick)
            await new Promise(res => setTimeout(res, 100));
        // Find last input element
        const query = '[data-option] bce-input';
        const options = this.el.shadowRoot.querySelectorAll(query);
        const option = options[index < 0 ? options.length + index : index];
        const input = option && option.shadowRoot.querySelector('input');
        // Set focus to new element
        if (input)
            input.focus();
    }
    async uploadImage(index) {
        const root = document.querySelector('bce-root');
        // Create upload dialog
        const upload = document.createElement('bce-upload');
        upload.accept = 'image/*';
        upload.active = true;
        upload.dialog = true;
        // Trigger upload
        const file = await root.execute(upload, res => {
            upload.addEventListener('input', event => {
                const target = event.target;
                res(target.value[0]);
            });
        }, { display: true });
        // Update value
        const copy = [...this.value];
        copy.splice(index, 1, Object.assign(Object.assign({}, this.value[index]), { image: file }));
        // Emit value
        console.log(copy);
    }
    deleteImage(option, index) {
        if (!('image' in option) || !option.image)
            return;
        __classPrivateFieldGet(this, _server).delete(option.image, {});
        // Update value
        const copy = [...this.value];
        const value = Object.assign({}, this.value[index]);
        if ('image' in value)
            delete value.image;
        copy.splice(index, 1, value);
        this.updateValue(copy);
    }
    updateValue(value) {
        this.value = value;
        const e = new globalThis.Event('input', { bubbles: true, composed: true });
        this.el.dispatchEvent(e);
    }
    componentWillLoad() {
        this.watchValue(this.value);
    }
    renderTooltip(icon, content) {
        if (!content)
            return null;
        return (h("bce-tooltip", { placement: "left", icon: icon }, content));
    }
    renderMetadata(option) {
        if (!('image' in option))
            return;
        return h("div", { "data-meta": true }, this.renderTooltip('fas:image', option.image));
    }
    renderOption(option, index, other = false) {
        if (!option.hasOwnProperty('text'))
            return null;
        const placeholder = this.placeholder && `${this.placeholder} ${index + 1}`;
        return (h("div", { key: index, "data-option": true },
            h("bce-input", { value: option.text, onInput: e => this.handleInput(e, index), onKeyDown: e => this.handleKeyDown(e, index), placeholder: placeholder }),
            this.renderMetadata(option),
            h("bce-menu", null,
                h("slot", { name: "option" }),
                this.allowColor && (h("bce-button", { icon: "fas:palette", onClick: () => this.handleColor(index) }, "Color")),
                this.allowImage && !other && (h("bce-button", { icon: "fas:image", onClick: () => this.handleImage(index) }, 'image' in option && option.image
                    ? this.label.labelOCImageDelete
                    : this.label.labelOCImageUpload)),
                this.value.length > 1 && (h("bce-button", { icon: "fas:trash", onClick: () => this.handleRemove(index) }, this.label.labelOCOptionRemove)))));
    }
    render() {
        const options = this.other ? this.value.slice(0, -1) : this.value;
        const other = this.other && this.value[this.value.length - 1];
        return [
            options.map((option, i) => this.renderOption(option, i)),
            other && this.renderOption(other, this.value.length - 1, true),
            h("slot", null),
            h("div", null,
                h("bce-button", { design: "text", icon: "fas:plus", onClick: () => this.addOption() }, this.label.labelOCOptionAdd),
                this.allowOther && (h("bce-button", { design: "text", icon: "fas:font", onClick: this.handleOther }, this.other
                    ? this.label.labelOCOtherRemove
                    : this.label.labelOCOtherAdd)),
                h("slot", { name: "action" }))
        ];
    }
    static get is() { return "bce-option-creator"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() { return {
        "$": ["bce-option-creator.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["bce-option-creator.css"]
    }; }
    static get properties() { return {
        "allowColor": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "allow-color",
            "reflect": true
        },
        "allowImage": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "allow-image",
            "reflect": true
        },
        "allowOther": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "allow-other",
            "reflect": true
        },
        "label": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "BlockElement.LabelOptionCreator",
                "resolved": "LabelOptionCreator",
                "references": {
                    "BlockElement": {
                        "location": "import",
                        "path": "../../models/element"
                    }
                }
            },
            "required": true,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            }
        },
        "name": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "name",
            "reflect": false
        },
        "other": {
            "type": "boolean",
            "mutable": true,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "other",
            "reflect": false
        },
        "placeholder": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string | undefined",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "placeholder",
            "reflect": false
        },
        "value": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "BlockElement.Option[]",
                "resolved": "Option[]",
                "references": {
                    "BlockElement": {
                        "location": "import",
                        "path": "../../models/element"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "defaultValue": "[]"
        }
    }; }
    static get events() { return [{
            "method": "onOther",
            "name": "other",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            }
        }]; }
    static get methods() { return {
        "addOption": {
            "complexType": {
                "signature": "(focus?: boolean) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        },
        "focusLast": {
            "complexType": {
                "signature": "(nextTick?: boolean | undefined) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        },
        "focusOption": {
            "complexType": {
                "signature": "(index: number, nextTick?: boolean) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }, {
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    },
                    "HTMLInputElement": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        }
    }; }
    static get elementRef() { return "el"; }
    static get watchers() { return [{
            "propName": "value",
            "methodName": "watchValue"
        }]; }
}
_server = new WeakMap();
