
innovaphone.ui1.templates = {

    /* 
    Dropdown with search input
        Author: gd
        Arguments:
            style: style attributue of the input element, which is displayed
            value: initial value
            elm: enclosing ui1.nodePrototype, drop down is displayed inside this element. There must be enough
                space to the bottom of this element to display the drop-down
            search: Search function. Args are a search string and a function which is called with search results as
                array of strings
        Function:
            - Enter text for the search
            - use arrow keys/enter or click on resuls to select
            - esc clears input and starts a new search
            - no new entries (not search results) are allowed
        Styling:
            Hardcoded
        
    */
    DropDown: function (style, value, elm, search) {
        var that = this;
        var dsp;
        var cur = -1;
        sel = [];
        val = [];
        this.createNode("input", style);
        this.addEvent("keydown", onkey);
        this.addEvent("input", oninput);
        this.container.value = value;

        function oninput() {
            var d = that.container.getBoundingClientRect();
            var e = elm.container.getBoundingClientRect();
            if (!dsp) {
                elm.addEvent("click", exit);
            }
            else {
                clear();
            }
            dsp = elm.add(new innovaphone.ui1.Div(`position:absolute; top:${d.bottom - e.top}px; left:${d.left - e.left}px; max-width:${e.right - d.left - 10}px; max-height:${e.bottom - d.bottom - 10}px; background-color:var(--bg2); padding:1px; overflow:auto`));
            search(that.container.value, (a) => {
                a.forEach((e) => {
                    sel.push(dsp.add(new innovaphone.ui1.Div("position:relative; margin:1px; padding:5px; font-size:14px; color:var(--c1); background-color:var(--bg1); cursor:pointer", e)).addEvent("click", onclick, sel.length));
                    val.push(e);
                });
            });
        }

        function onkey(e) {
            if (e.keyCode == 40) {
                if (cur < sel.length - 1) {
                    if (cur >= 0) sel[cur].container.style.backgroundColor = "var(--bg1)";
                    sel[++cur].container.style.backgroundColor = "var(--bg3)";
                }
            }
            else if (e.keyCode == 38) {
                if (cur > 0) {
                    sel[cur].container.style.backgroundColor = "var(--bg1)";
                    sel[--cur].container.style.backgroundColor = "var(--bg3)";
                }
            }
            else if (e.keyCode == 27) {
                if (dsp) {
                    exit();
                }
                else {
                    that.container.value = "";
                    oninput();
                }
            }
            else if (e.keyCode == 13) {
                if (cur >= 0) {
                    value = val[cur];
                    exit();
                }
            }
        }

        function onclick(e, o) {
            value = val[o];
            exit();
            e.stopPropagation();
        }

        function exit() {
            that.container.value = value;
            elm.remEvent("click", exit);
            clear();
        }

        function clear() {
            elm.rem(dsp);
            dsp = null;
            sel = [];
            val = []
            cur = -1;
        }

        this.getValue = function () {
            return this.container.value;
        }
    },

    /*
    Password Input with show/hide
        - change innovaphone.connectSvgs.show/hide to the correct vars containg the show/hide path
        - add
            ::-ms-reveal {
                display: none;
            }
          to the CSS to avoid duplicate show/hide shown by edge
        - ajust colors and sizes according your needs
    */
    Password: function (style, value) {
        this.createNode("div", style);
        var inp = this.add(new innovaphone.ui1.Input(`position:relative; display:flex; width:calc(100% - 25px); color:${this.container.style.color}; background-color:${this.container.style.backgroundColor}; border:0; outline:none`, value, null, 64, "password"));
        var show = this.add(new innovaphone.ui1.SvgInline("position:absolute; right:5px; top:11px; width:20px; height:20px; visibility:hidden; fill:var(--c2); cursor:pointer", "0 0 20 20", innovaphone.connectSvgs.show)).addEvent("click", (e) => {
            show.container.style.visibility = "hidden";
            hide.container.style.visibility = "visible";
            inp.container.type = "text";
        });
        var hide = this.add(new innovaphone.ui1.SvgInline("position:absolute; right:5px; top:11px; width:20px; height:20px; visibility:hidden; fill:var(--c2); cursor:pointer", "0 0 20 20", innovaphone.connectSvgs.hide)).addEvent("click", (e) => {
            hide.container.style.visibility = "hidden";
            show.container.style.visibility = "visible";
            inp.container.type = "password";
        });
        var initial = true;
        if (!value) {
            show.container.style.visibility = "visible";
            initial = false;
        }
        inp.addEvent("input", () => {
            if (initial) {
                inp.setValue("");
                show.container.style.visibility = "visible";
                initial = false;
            }
        });

        this.addEvent = (e, f, o) => inp.addEvent(e, f, o);
    }
}
innovaphone.ui1.templates.DropDown.prototype = innovaphone.ui1.nodePrototype;
innovaphone.ui1.templates.Password.prototype = innovaphone.ui1.nodePrototype;
