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

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

const TPL = new Template(`
    <div id="scroll-container">
        <slot id="content">
        </slot>
        <div id="empty-container" class="hidden">
            <emc-i18n-label id="empty" i18n-value="no entries"></emc-i18n-label>
        </div>
    </div>
    
`);

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

const STYLE = new GlobalStyle(`
    :host {
        display: flex;
        flex-direction: column;
        align-items: start;
        justify-content: center;
        min-height: 200px;
        min-width: 300px;
        margin: 8px;
        background-color: var(--datalist-back-color, #ffffff);
        background-image: var(--datalist-back-image, none);
        border-style: solid;
        border-width: var(--datalist-border-width, 2px);
        border-color: var(--datalist-border-color, #000000);
        border-radius: var(--datalist-border-radius, 6px);
        overflow: hidden;
        line-height: normal;
    }
    
    #scroll-container {
        flex-grow: 1;
        flex-shrink: 0;
        width: 100%;
        height: 100%;
        overflow-x: hidden;
        overflow-y: auto;
    }
    
    #content {
        display: flex;
        flex-direction: column;
        width: 100%;
        padding: 2px;
    }
    
    ::slotted(*) {
        flex-shrink: 0;
    }
    
    #empty-container {
        position: sticky;
        display: flex;
        align-items: center;
        justify-content: center;
        flex: 1;
        top: 50px;
        left: 0px;
        width: 100%;
        height: 100%;
        max-height: 200px;
        min-width: calc(200px - var(--scrollbar-size, 0px) - 4px);
        /* --datagrid-border-width * 2 */
        min-height: 2rem;
        pointer-events: none;
        user-select: none;
        animation: popInLater 0ms ease-in 100ms forwards;
        animation-fill-mode: forwards;
        opacity: 0;
    }
    
    #empty-container #empty {
        display: flex;
        align-items: center;
        justify-content: center;
        min-width: 100px;
        padding: 20px;
        height: 30px;
        color: var(--datalist-empty-text-color, #666666);
        background-color: var(--datalist-empty-back-color, #dadada);
        background-image: var(--datalist-empty-back-image, none);
        border-style: solid;
        border-width: var(--datalist-empty-border-width, 2px);
        border-color: var(--datalist-empty-border-color, #666666);
        border-radius: var(--datalist-empty-border-radius, 6px);
        font-size: 16px;
        font-style: italic;
        white-space: nowrap;
    }
    
    #empty-container.hidden {
        display: none;
    }
    
    @keyframes popInLater {
        to {
            opacity: 1;
        }
    }
    
`);

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

import CustomElement from "../../element/CustomElement.js";
import ResizeObserverMixin from "../../mixin/ResizeObserverMixin.js";
import DataRecieverMixin from "../../../util/dataprovider/DataRecieverMixin.js";
import ElementManager from "../../../util/html/ElementManager.js";
import BusyIndicator from "../../BusyIndicator.js";
import "../../i18n/I18nLabel.js";
import "./components/DataListEntry.js";

// TODO add "no match" label
export default class DataList extends ResizeObserverMixin(DataRecieverMixin(CustomElement)) {

    #scrollContainerEl;

    #emptyContainerEl;

    #elementManager = new ElementManager(this);

    #busyIndicator = new BusyIndicator();

    constructor() {
        super();
        TPL.apply(this.shadowRoot);
        STYLE.apply(this.shadowRoot);
        /* --- */
        this.#busyIndicator.setTarget(this.shadowRoot);
        /* --- */
        this.#scrollContainerEl = this.shadowRoot.getElementById("scroll-container");
        this.#emptyContainerEl = this.shadowRoot.getElementById("empty-container");
        this.#elementManager.composer = (key, values) => {
            const el = this.createListEntry();
            if (typeof el.setData !== "function") {
                throw new Error("list elements must implement a setData function");
            }
            el.key = key;
            el.setData(values);
            return el;
        };
        this.#elementManager.mutator = (el, key, values) => {
            el.setData(values);
        };
        this.#elementManager.addEventListener("afterrender", () => {
            const isEmpty = this.children.length === 0;
            this.#emptyContainerEl.classList.toggle("hidden", !isEmpty);
            if (this.autoscroll) {
                const scrollHeight = this.#scrollContainerEl.scrollHeight;
                this.#scrollContainerEl.scroll({top: scrollHeight});
            }
        });
        this.#scrollContainerEl.addEventListener("scrollend", () => {
            const ev = new Event("scrollend", event);
            this.dispatchEvent(ev);
        });
    }

    resizeCallback() {
        if (this.autoscroll) {
            const scrollHeight = this.#scrollContainerEl.scrollHeight;
            this.#scrollContainerEl.scroll({top: scrollHeight});
        }
    }

    set autoscroll(val) {
        this.setBooleanAttribute("autoscroll", val);
    }

    get autoscroll() {
        return this.getBooleanAttribute("autoscroll");
    }

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

    attributeChangedCallback(name, oldValue, newValue) {
        if (oldValue != newValue) {
            switch (name) {
                case "autoscroll": {
                    if (this.autoscroll) {
                        const scrollHeight = this.#scrollContainerEl.scrollHeight;
                        this.#scrollContainerEl.scroll({top: scrollHeight});
                    }
                } break;
            }
        }
    }

    setData(records) {
        this.#elementManager.manage(records);
    }

    createListEntry() {
        return document.createElement("emc-datalist-entry");
    }

    busy() {
        return this.#busyIndicator.busy();
    }

    unbusy() {
        return this.#busyIndicator.unbusy();
    }

    reset() {
        return this.#busyIndicator.reset();
    }

    getVerticalScrollFactor() {
        const scrollHeight = this.#scrollContainerEl.scrollHeight;
        const clientHeight = this.#scrollContainerEl.clientHeight;
        const scrollTop = this.#scrollContainerEl.scrollTop;
        const currentScrollPosition = clientHeight + scrollTop;

        if (scrollHeight <= clientHeight) {
            return 1;
        }

        if (scrollHeight <= 0) {
            return 0;
        }

        return currentScrollPosition / scrollHeight;
    }

}

customElements.define("emc-datalist", DataList);
