/* ===================== AUTOGENERATED SOURCE IMPORT ===================== */

import Template from "/emcJS/util/html/template/HTMLTemplate.js";

const TPL = new Template(`
    <input type="text" id="display" value="" readonly>
`);

import GlobalStyle from "/emcJS/util/html/template/CSSTemplate.js";

const STYLE = new GlobalStyle(`
    :host {
        display: flex;
        flex-direction: row;
        align-items: center;
        min-width: 200px;
        height: 2rem;
        color: var(--input-text-color, #000000);
        background-color: var(--input-back-color, #ffffff);
        border: solid 1px var(--input-border-color, #222222);
        border-radius: 2px;
        user-select: none;
    }
    :host(:focus) {
        box-shadow: 0 0 2px 2px var(--input-focus-color, #06b5ff);
        outline: none;
    }
    :host(:focus:not(:focus-visible)) {
        box-shadow: none;
        outline: none;
    }
    :focus {
        outline: none;
    }
    #display {
        width: 100%;
        height: 100%;
        border: none;
    }
    
`);

/* ======================================================================= */

import CustomElementDelegating from "../element/CustomElementDelegating.js";
import {toStartUppercaseEndLowercase} from "../../util/helper/string/ConvertCase.js";

const BLACKLIST = [
    "Control",
    "Shift",
    "Alt",
    "Meta"
];
const VALUE_PARSE = /(ctrl\+)?(shift\+)?(alt\+)?(meta\+)?(.+)?/i;

/**
 * @deprecated
 */
export default class KeyInput extends CustomElementDelegating {

    #displayEl;

    constructor() {
        super();
        this.shadowRoot.append(TPL.generate());
        STYLE.apply(this.shadowRoot);
        /* --- */
        this.#displayEl = this.shadowRoot.getElementById("display");
        this.addEventListener("keydown", (event) => {
            const {
                key, ctrlKey, shiftKey, altKey, metaKey
            } = event;
            if (key !== "Tab") {
                if (key === "Escape") {
                    this.value = "";
                    const ev = new Event("change");
                    ev.ctrlKey = false;
                    ev.shiftKey = false;
                    ev.altKey = false;
                    ev.metaKey = false;
                    ev.key = "";
                    this.dispatchEvent(ev);
                } else if (BLACKLIST.includes(key)) {
                    this.#display(KeyInput.stringifyKeys({
                        ctrlKey,
                        shiftKey,
                        altKey,
                        metaKey
                    }));
                } else {
                    this.value = KeyInput.stringifyKeys({
                        ctrlKey,
                        shiftKey,
                        altKey,
                        metaKey,
                        key
                    });
                    const ev = new Event("change");
                    ev.ctrlKey = ctrlKey;
                    ev.shiftKey = shiftKey;
                    ev.altKey = altKey;
                    ev.metaKey = metaKey;
                    ev.key = key;
                    this.dispatchEvent(ev);
                }
                event.preventDefault();
                event.stopPropagation();
                return false;
            }
        });
        this.addEventListener("keyup", (event) => {
            if (event.key !== "Tab") {
                const value = KeyInput.parseKeys(this.value);
                if (value.key == null) {
                    const {
                        ctrlKey, shiftKey, altKey, metaKey
                    } = event;
                    this.#display(KeyInput.stringifyKeys({
                        ctrlKey,
                        shiftKey,
                        altKey,
                        metaKey
                    }));
                }
                event.preventDefault();
                event.stopPropagation();
                return false;
            }
        });
        this.addEventListener("blur", () => {
            this.#display(this.value);
        });
    }

    #display(value) {
        this.#displayEl.value = value.split("+").map((s) => toStartUppercaseEndLowercase(s)).join(" + ");
    }

    set value(val) {
        this.setAttribute("value", val);
    }

    get value() {
        return this.getAttribute("value");
    }

    static get observedAttributes() {
        return ["value"];
    }

    attributeChangedCallback(name, oldValue, newValue) {
        if (oldValue != newValue) {
            switch (name) {
                case "value": {
                    this.#display(newValue);
                } break;
            }
        }
    }

    static parseKeys(string) {
        const res = VALUE_PARSE.exec(string);
        return {
            ctrlKey: res[1] != null,
            shiftKey: res[2] != null,
            altKey: res[3] != null,
            metaKey: res[4] != null,
            key: res[5] === "Space" ? " " : res[5]
        };
    }

    static stringifyKeys(opts = {}) {
        const {
            ctrlKey, shiftKey, altKey, metaKey, key
        } = opts;
        let res = "";
        if (ctrlKey) {
            res += "ctrl+";
        }
        if (shiftKey) {
            res += "shift+";
        }
        if (altKey) {
            res += "alt+";
        }
        if (metaKey) {
            res += "meta+";
        }
        if (key != null) {
            res += key === " " ? "Space" : key;
        }
        return res;
    }

}

customElements.define("emc-keyinput", KeyInput);
