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

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

const TPL = new Template(`
    <emc-panel-tabpanel id="categories">
    </emc-panel-tabpanel>
    <div id="footer">
        <button id="submit" title="submit">
            submit
        </button>
        <button id="cancel" title="cancel">
            cancel
        </button>
    </div>
`);

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

const STYLE = new GlobalStyle(`
    :host {
        box-sizing: border-box;
    }
    
    #window {
        height: 600px;
        width: 1000px;
    }
    
    #footer,
    #submit,
    #cancel {
        display: flex;
    }
    
    #categories {
        overflow-x: auto;
        overflow-y: hidden;
    }
    
    #footer {
        height: 50px;
        padding: 10px 30px 10px;
        justify-content: flex-end;
        color: var(--modal-footer-text-color, #000000);
        background-color: var(--modal-footer-back-color, #e4e4e4);
        background-image: var(--modal-footer-back-image, none);
        border-top: solid var(--modal-border-width, 2px) var(--modal-border-color, #cccccc);
    }
    
    #submit,
    #cancel {
        margin-left: 10px;
        padding: 5px;
        color: var(--button-text-color, #000000);
        background-color: var(--button-back-color, #eaeaea);
        border-style: solid;
        border-width: var(--button-border-width, 2px);
        border-color: var(--button-border-color, #222222);
        border-radius: var(--button-border-radius, 6px);
        align-items: center;
        justify-content: center;
        font-weight: 900;
        text-transform: uppercase;
        cursor: pointer;
        user-select: none;
        appearance: none;
    }
    
    #submit:hover,
    #cancel:hover {
        color: var(--button-hover-text-color, #ffffff);
        background-color: var(--button-hover-back-color, #353935);
        border-color: var(--button-hover-border-color, #222222);
    }
    
`);

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

import ObservableMultiDefaultValueStorage from "../../../../data/storage/observable/ObservableMultiDefaultValueStorage.js";
import Window from "../Window.js";
import "../../../layout/panel/TabPanel.js";
import "../../../input/ListSelect.js";
import "./SettingsTabContent.js";

function convertValueList(values = {}) {
    const opt = {};
    if (typeof values == "object") {
        if (Array.isArray(values)) {
            for (const key of values) {
                opt[key] = key;
            }
        } else {
            for (const key in values) {
                if (values[key] != null) {
                    opt[key] = values[key];
                } else {
                    opt[key] = key;
                }
            }
        }
    }
    return opt;
}

export default class SettingsWindow extends Window {

    #windowEl;

    #bodyEl;

    #categoriesEl;

    #submitEl;

    #cancelEl;

    #storage = new ObservableMultiDefaultValueStorage();

    constructor(title = "Settings", options = {}) {
        super(title, options.close);
        const els = TPL.generate();
        STYLE.apply(this.shadowRoot);
        /* --- */
        this.#windowEl = this.shadowRoot.getElementById("window");
        this.#bodyEl = this.shadowRoot.getElementById("body");
        this.#bodyEl.innerHTML = "";
        this.#categoriesEl = els.getElementById("categories");
        this.#bodyEl.append(this.#categoriesEl);
        this.#windowEl.append(els.getElementById("footer"));

        this.#categoriesEl.onclick = (event) => {
            const targetEl = event.target.getAttribute("target");
            if (targetEl) {
                this.active = targetEl;
                event.preventDefault();
                return false;
            }
        };

        this.#submitEl = this.shadowRoot.getElementById("submit");
        if (!!options.submit && typeof options.submit === "string") {
            this.#submitEl.innerHTML = options.submit;
            this.#submitEl.setAttribute("title", options.submit);
        }
        this.#submitEl.addEventListener("click", () => this.submit());

        this.#cancelEl = this.shadowRoot.getElementById("cancel");
        if (!!options.cancel && typeof options.cancel === "string") {
            this.#cancelEl.innerHTML = options.cancel;
            this.#cancelEl.setAttribute("title", options.cancel);
        }
        this.#cancelEl.addEventListener("click", () => this.cancel());
    }

    show(data = {}, category = "") {
        if (category) {
            this.#categoriesEl.active = category;
        } else {
            this.#categoriesEl.active = "";
        }
        this.#storage.setAll(data);
        super.show();
    }

    submit() {
        const data = this.#storage.getAll();
        const ev = new Event("submit");
        ev.data = data;
        this.dispatchEvent(ev);
        this.remove();
    }

    cancel() {
        this.dispatchEvent(new Event("cancel"));
        this.remove();
    }

    overwriteValues(data) {
        this.#storage.deserialize(data);
    }

    getTab(category) {
        const tabEl = this.#categoriesEl.getTab(category);
        if (tabEl != null) {
            const containerEl = tabEl.querySelector(".container");
            return containerEl;
        } else {
            const tabEl = this.#categoriesEl.setTab(category, this.constructor.getTabLabel(category));
            const containerEl = document.createElement("emc-window-settings-tab");
            containerEl.className = "container";
            containerEl.id = `settings_${category}`;
            tabEl.append(containerEl);
            return containerEl;
        }
    }

    addStringInput(category, ref, label, desc, def, visible, resettable) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            this.#storage.setDefault(ref, def);
            tabEl.addStringInput(this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable);
        }
    }

    addNumberInput(category, ref, label, desc, def, visible, resettable, min, max) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            this.#storage.setDefault(ref, def);
            tabEl.addNumberInput(this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable, min, max);
        }
    }

    addRangeInput(category, ref, label, desc, def, visible, resettable, min, max) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            this.#storage.setDefault(ref, def);
            tabEl.addRangeInput(this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable, min, max);
        }
    }

    addCheckInput(category, ref, label, desc, def, visible, resettable) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            this.#storage.setDefault(ref, !!def);
            tabEl.addCheckInput(this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable);
        }
    }

    addColorInput(category, ref, label, desc, def, visible, resettable) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            this.#storage.setDefault(ref, def);
            tabEl.addColorInput(this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable);
        }
    }

    addKeyInput(category, ref, label, desc, def, visible, resettable) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            this.#storage.setDefault(ref, def);
            tabEl.addKeyInput(this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable);
        }
    }

    addChoiceInput(category, ref, label, desc, def, visible, resettable, values) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            this.#storage.setDefault(ref, def);
            tabEl.addChoiceInput(this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable, values);
        }
    }

    addListSelectInput(category, ref, label, desc, def, visible, resettable, multiple, values) {
        const convertedValues = convertValueList(values);
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            for (const value in convertedValues) {
                this.#storage.setDefault(value, def.includes(value));
            }
            tabEl.addListSelectInput(this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable, multiple, convertedValues);
        }
    }

    addButton(category, ref, label, desc, visible, text = "", callback = null) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            tabEl.addButton(this.#storage, ref, this.constructor.getLabel(label), desc, visible, text, callback);
        }
    }

    addCustomInput(category, inputEl, ref, label, desc, def, visible, resettable) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            this.#storage.setDefault(ref, def);
            tabEl.addCustomInput(inputEl, this.#storage, ref, this.constructor.getLabel(label), desc, visible, resettable);
        }
    }

    addElements(category, content) {
        const tabEl = this.getTab(category);
        if (tabEl != null) {
            tabEl.addElements(content);
        }
    }

    static getTabLabel(label) {
        return label;
    }

    static getLabel(label) {
        return label;
    }

}

customElements.define("emc-settingswindow", SettingsWindow);
