#include channels.js
#include common.js
#include settings.js
#include user.js
#include sound/umisound.js
#include ui/channels.js
#include ui/elems.js
#include ui/messages.jsx
#include ui/title.js
#include ui/users.js
#include ui/view.js

Umi.UI.Hooks = (function() {
    return {
        AddMessageHooks: function() {
            Umi.Messages.OnSend.push(function(msg) {
                Umi.UI.View.SetText('');
            });

            Umi.Messages.OnRemove.push(function(msg) {
                Umi.UI.Messages.Remove(msg);
            });

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

            window.addEventListener('focus', function() {
                Umi.UI.Title.Clear();
            });

            Umi.Messages.OnAdd.push(function(msg) {
                Umi.UI.Channels.Unread(msg.getChannel());
                Umi.UI.Messages.Add(msg);

                if(!document.hidden && Umi.Settings.get('flashTitle'))
                    return;

                let title = ' ' + msg.getUser().getName(),
                    channel = Umi.Channels.Current() || null;
                if(msg.getUser().isBot() && Umi.Settings.get('showServerMsgInTitle'))
                    title = ' ' + msg.getText();

                if(channel !== null && channel.getName() !== msg.getChannel())
                    title += ' @ ' + channel.getName();

                Umi.UI.Title.Flash(['[ @]' + title, '[@ ]' + title]);

                if(Umi.Settings.get('enableNotifications') && Umi.User.getCurrentUser() !== null) {
                    const triggers = (Umi.Settings.get('notificationTriggers') || '').toLowerCase().split(' '),
                        options = {};

                    triggers.push((Umi.User.getCurrentUser() || { getName: function() { return ''; } }).getName().toLowerCase());
                    options.body = 'Click here to see what they said.';

                    if(Umi.Settings.get('notificationShowMessage'))
                        options.body += "\n" + msg.getText();

                    const avatarUrl = futami.get('avatar');
                    if(avatarUrl.length > 0)
                        options.icon = avatarUrl.replace('{user:id}', msg.getUser().getId()).replace('{resolution}', '80').replace('{user:avatar_change}', msg.getUser().getAvatarTime().toString());

                    for(const trigger of triggers) {
                        const message = ' ' + msg.getText() + ' ';

                        if(trigger.trim() === '')
                            continue;

                        if(message.toLowerCase().indexOf(' ' + trigger + ' ') >= 0) {
                            new Notification('{0} mentioned you!'.replace('{0}', msg.getUser().getName()), options);
                            if(Umi.Settings.get('onlySoundOnMention'))
                                Umi.Sound.Play('incoming');
                            break;
                        }
                    }
                }
            });
        },
        AddUserHooks: 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);
            });
        },
        AddChannelHooks: function() {
            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);
            });
        },
        AddTextHooks: function() {
            window.addEventListener('keydown', function(ev) {
                if(ev.ctrlKey || ev.altKey || ev.metaKey)
                    return;

                const tagName = ev.target.tagName.toLowerCase();
                if(tagName !== 'textarea' && tagName !== 'input') 
                    Umi.UI.Elements.MessageInput.focus();
            });

            Umi.UI.Elements.MessageInput.addEventListener('input', function(ev) {
                const elemInput = Umi.UI.Elements.MessageInput, elemParent = elemInput.parentNode;
                let height = 40;

                if(Umi.Settings.get('expandTextBox') && elemInput.scrollHeight > elemInput.clientHeight) {
                    /*const cols = Math.floor(elemInput.clientWidth / 8),
                        rows = Math.floor(elemInput.textLength / cols);

                    if(rows > 1)
                        height = 15.5 * (rows + 1);*/
                    height = elemInput.scrollHeight;
                }

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

            Umi.UI.Elements.MessageInput.addEventListener('keydown', function(ev) {
                switch(ev.key) {
                    case 'Tab':
                        if(!ev.shiftKey || !ev.ctrlKey) {
                            ev.preventDefault();

                            const text = Umi.UI.View.GetText();
                            if(text.length > 0) {
                                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().getRank();
                                    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].getName();
                                }

                                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);
                                }
                            }
                        }
                        break;

                    case 'Enter':
                    case 'NumpadEnter':
                        if(!ev.shiftKey) {
                            ev.preventDefault();
                            Umi.Messages.Send(Umi.UI.Elements.MessageInput.value);
                            return;
                        }
                        break;
                }
            });

            Umi.UI.Elements.MessageSend.addEventListener('click', function(ev) {
                Umi.Messages.Send(Umi.UI.Elements.MessageInput.value);
            });
        },
    };
})();
