#include settings.js
#include utility.js
#include ui/menus.js

Umi.UI.Settings = (function() {
    let copyright = null;
    const createCopyright = function() {
            if(copyright !== null)
                return;

            copyright = $e({
                attrs: {
                    className: 'mami-copyright',
                },
                child: [
                    'Mami',
                    ' © ',
                    {
                        tag: 'a',
                        child: 'flash.moe',
                        attrs: {
                            href: '//flash.moe',
                            target: '_blank',
                        },
                    },
                    { tag: 'br', },
                    {
                        tag: 'a',
                        child: 'Sock Chat Documentation',
                        attrs: {
                            href: '//railgun.sh/sockchat',
                            target: '_blank',
                        },
                    },
                ],
            });

            Umi.UI.Menus.Get('settings').appendChild(copyright);
        };

    const addCategory = function(category) {
        const catBody = $e({
                attrs: {
                    id: Umi.UI.Menus.Get('settings').id + '-category-' + category.id,
                    classList: ['setting__category', 'setting__category--' + category.id],
                    style: { overflow: 'hidden' },
                },
            }),
            catHeader = $e({
                attrs: {
                    classList: ['setting__category-title', 'setting__category-title--' + category.id],
                    style: {
                        cursor: 'pointer',
                    },
                    onclick: function() {
                        if(catBody.dataset.mamiClosed) {
                            delete catBody.dataset.mamiClosed;
                            catBody.style.maxHeight = null;
                            const meow = catBody.clientHeight;
                            catBody.style.maxHeight = '0';
                            setTimeout(function() {
                                catBody.style.maxHeight = meow.toString() + 'px';
                            }, 50);
                        } else {
                            catBody.dataset.mamiClosed = 1;
                            if(!catBody.style.maxHeight) {
                                catBody.style.maxHeight = catBody.clientHeight.toString() + 'px';
                                setTimeout(function() {
                                    catBody.style.maxHeight = '0';
                                }, 50);
                            } else catBody.style.maxHeight = '0';
                        }
                    },
                },
                child: category.name,
            });

        $ib(copyright, catHeader);
        $ib(copyright, catBody);

        if(category.collapse) {
            catBody.dataset.mamiClosed = 1;
            catBody.style.maxHeight = '0';
        }

        if(category.warning)
            catBody.appendChild($e({
                attrs: {
                    style: {
                        fontSize: '.9em',
                        lineHeight: '1.4em',
                        margin: '5px',
                        padding: '5px',
                        backgroundColor: 'darkred',
                        border: '2px solid red',
                        borderRadius: '5px',
                    },
                },
                child: category.warning,
            }));
    };

    const addSetting = function(setting) {
        if(!setting.category)
            return;

        let entry = null;
        const settingsHtml = Umi.UI.Menus.Get('settings'),
            typeAlias = setting.type === 'url' ? 'text' : setting.type,
            container = $e({
                attrs: {
                    'class': 'setting__container setting__container--' + typeAlias,
                    id: settingsHtml.id + '-' + setting.id
                }
            });

        switch(setting.type) {
            case 'select':
                entry = $e({ tag: 'select', attrs: { 'class': 'setting__input' } });
                entry.disabled = !setting.mutable;

                let data = {};
                const dataType = setting.dataType || 'setting';

                switch(dataType) {
                    case 'object':
                        data = setting.data;
                        break;
                    case 'call':
                        data = setting.data();
                        break;
                }

                for(const _i in data) {
                    const _j = data[_i],
                        _x = $e({ tag: 'option', attrs: { 'class': 'setting__style setting__style--' + setting.id + '-' + _i } });
                    _x.value = _i;
                    _x.appendChild($t(_j));
                    entry.appendChild(_x);
                }

                Umi.Settings.watch(setting.id, function(v) {
                    const keys = Object.keys(data);
                    for(let i = 0; i < keys.length; ++i) {
                        if(keys[i] === v) {
                            entry.selectedIndex = i;
                            break;
                        }
                    }
                });

                entry.addEventListener('change', function(ev) {
                    Umi.Settings.set(setting.id, entry.value);
                });

                container.appendChild($e({
                    tag: 'label',
                    attrs: {
                        className: 'setting__label',
                    },
                    child: [
                        { child: setting.name },
                        entry,
                    ],
                }));
                break;

            case 'checkbox':
                entry = $e({ tag: 'input', attrs: { type: 'checkbox', 'class': 'setting__input' } });
                entry.disabled = !setting.mutable;

                entry.addEventListener('click', function(ev) {
                    if(setting.confirm && !confirm(setting.confirm)) {
                        entry.checked = !entry.checked;
                        return;
                    }

                    Umi.Settings.toggle(setting.id);
                });

                Umi.Settings.watch(setting.id, function(v) {
                    entry.checked = v;
                });

                container.appendChild($e({
                    tag: 'label',
                    attrs: {
                        className: 'setting__label',
                    },
                    child: [
                        entry,
                        { child: setting.name },
                    ],
                }));
                break;

            case 'button': // this really shouldn't probably be here i think
                entry = $e({ tag: 'input', attrs: { 'class': 'setting__input' } });
                entry.disabled = !setting.mutable;
                entry.value = setting.name;
                entry.type = setting.type;
                entry.addEventListener('click', setting.click);

                container.appendChild($e({
                    tag: 'label',
                    attrs: {
                        className: 'setting__label',
                    },
                    child: entry,
                }));
                break;

            case 'url':
            case 'text':
            case 'number':
                entry = $e({ tag: 'input', attrs: { 'class': 'setting__input' } });
                entry.disabled = !setting.mutable;
                entry.type = setting.type;
                
                Umi.Settings.watch(setting.id, function(v) {
                    if(entry.value !== v)
                        entry.value = v;
                });
                entry.addEventListener('keyup', function(ev) {
                    Umi.Settings.set(setting.id, entry.value);
                });

                container.appendChild($e({
                    tag: 'label',
                    attrs: {
                        className: 'setting__label',
                    },
                    child: [
                        { child: setting.name },
                        entry,
                    ],
                }));
                break;

            case 'range':
                entry = $e({ tag: 'input', attrs: { 'class': 'setting__input' } });
                entry.disabled = !setting.mutable;
                entry.type = setting.type;
                
                Umi.Settings.watch(setting.id, function(v) {
                    entry.value = v;
                });
                entry.addEventListener('change', function(ev) {
                    Umi.Settings.set(setting.id, entry.value);
                });

                container.appendChild($e({
                    tag: 'label',
                    attrs: {
                        className: 'setting__label',
                    },
                    child: [
                        { child: setting.name },
                        entry,
                    ],
                }));
                break;
        }

        $i(settingsHtml.id + '-category-' + setting.category).appendChild(container);
    };

    return {
        Init: function() {
            createCopyright();

            for(const category of UmiSettings.categories)
                addCategory(category);
            for(const setting of UmiSettings.settings)
                addSetting(setting);
        },
        Add: addSetting,
        AddCat: addCategory,
    };
})();
