#include channels.js
#include users.js
#include utility.js
#include ui/channels.js
#include ui/messages.jsx
#include ui/users.js
#include ui/view.js

Umi.UI.Hooks = (function() {
    let sendMessage;
    let switchChannel;

    return {
        SetCallbacks: (sendMessageFunc, switchChannelFunc) => {
            sendMessage = sendMessageFunc;
            switchChannel = switchChannelFunc;
        },
        AddHooks: function() {
            Umi.Users.OnAdd.push(function(user) {
                Umi.UI.Users.Add(user);
            });

            Umi.Users.OnRemove.push(function(user) {
                Umi.UI.Users.Remove(user);
            });

            Umi.Users.OnClear.push(function() {
                Umi.UI.Users.RemoveAll();
            });

            Umi.Users.OnUpdate.push(function(id, user) {
                Umi.UI.Users.Update(user);
            });


            Umi.Channels.OnAdd.push(function(channel) {
                Umi.UI.Channels.Add(channel);
            });

            Umi.Channels.OnRemove.push(function(channel) {
                Umi.UI.Channels.Remove(channel);
            });

            Umi.Channels.OnClear.push(function() {
                Umi.UI.Channels.RemoveAll();
            });

            Umi.Channels.OnUpdate.push(function(name, channel) {
                Umi.UI.Channels.Update(name, channel);
            });

            Umi.Channels.OnSwitch.push(function(name, channel) {
                Umi.UI.Channels.Reload(name === null);

                if(typeof switchChannel === 'function')
                    switchChannel(channel);
            });


            window.addEventListener('keydown', function(ev) {
                if((ev.ctrlKey && ev.key !== 'v') || ev.altKey)
                    return;

                if(!ev.target.matches('input, textarea, select, button'))
                    $i('umi-msg-text').focus();
            });

            $i('umi-msg-form').addEventListener('submit', ev => {
                ev.preventDefault();

                if(typeof sendMessage !== 'function')
                    return;

                const textField = ev.target.elements.namedItem('text');
                if(textField instanceof HTMLTextAreaElement) {
                    let text = textField.value;
                    textField.value = '';

                    text = text.replace(/\t/g, '    ');
                    if(text.length > 0)
                        sendMessage(text);
                }
            });

            $i('umi-msg-text').addEventListener('input', function(ev) {
                const elemInput = $i('umi-msg-text');
                const elemParent = elemInput.parentNode;
                let height = 40;

                if(mami.settings.get('expandTextBox') && elemInput.scrollHeight > elemInput.clientHeight)
                    height = elemInput.scrollHeight;

                if(height > 40)
                    elemParent.style.height = height.toString() + 'px';
                else
                    elemParent.style.height = null;
            });

            $i('umi-msg-text').addEventListener('keydown', function(ev) {
                if(ev.key === 'Tab' && (!ev.shiftKey || !ev.ctrlKey)) {
                    ev.preventDefault();

                    const text = Umi.UI.View.GetText();
                    if(text.length < 1)
                        return;

                    const start = Umi.UI.View.GetPosition();
                    let position = start,
                        snippet = '';
                    while(position >= 0 && text.charAt(position - 1) !== ' ' && text.charAt(position - 1) !== "\n") {
                        --position;
                        snippet = text.charAt(position) + snippet;
                    }

                    let insertText = undefined;

                    if(snippet.indexOf(':') === 0) {
                        let emoteRank = 0;
                        if(Umi.User.hasCurrentUser())
                            emoteRank = Umi.User.getCurrentUser().perms.rank;
                        const emotes = MamiEmotes.findByName(emoteRank, snippet.substring(1), true);
                        if(emotes.length > 0)
                            insertText = ':' + emotes[0] + ':';
                    } else {
                        const users = Umi.Users.Find(snippet);
                        if(users.length === 1)
                            insertText = users[0].name;
                    }

                    if(insertText !== undefined) {
                        Umi.UI.View.SetText(text.slice(0, start - snippet.length) + text.slice(start));
                        Umi.UI.View.SetPosition(start - snippet.length);
                        Umi.UI.View.EnterAtCursor(insertText);
                        Umi.UI.View.SetPosition(Umi.UI.View.GetPosition() + insertText.length);
                        Umi.UI.View.SetPosition(Umi.UI.View.GetPosition(), true);
                    }

                    return;
                }

                if((ev.key === 'Enter' || ev.key === 'NumpadEnter') && !ev.shiftKey) {
                    ev.preventDefault();
                    $i('umi-msg-form').requestSubmit();
                    return;
                }
            });
        },
    };
})();
