var
    /**
     * Minimum time between 2 notifications (ms)
     * @const
     * @type {number}
    **/
    NOTIFICATION_COOLDOWN = 30 * 1000 //30 sec

    /**
     * Maximum time the notification will stay visible (ms)
     * @const
     * @type {number}
    **/
    ,NOTIFICATION_DELAY = 5 * 1000 // 5 sec

    /** @type {number} */
    ,lastNotificationSpawn = 0

;

function onContextUpdated() {
    var chanListFram = document.createDocumentFragment()
        ,sortedChans = SLACK.context.self ? Object.keys(SLACK.context.self.channels) : [];

    sortedChans.sort(function(a, b) {
        if (a[0] !== b[0]) {
            return a[0] - b[0];
        }
        return SLACK.context.getChannel(a).name.localeCompare(SLACK.context.getChannel(b).name);
    });
    sortedChans.forEach(function(chanId) {
        var chan =
            /**
             * SortedChan does not contains ims ids
             * @type {SlackChan|SlackGroup}
            **/
            (SLACK.context.getChannel(chanId));
        if (!chan.archived) {
            var chanListItem = createChanListItem(chan);
            if (chanListItem)
                chanListFram.appendChild(chanListItem);
        }
    });
    var sortedUsers = SLACK.context.users ? Object.keys(SLACK.context.users) : [];
    sortedUsers.sort(function(a, b) {
        return SLACK.context.users[a].name.localeCompare(SLACK.context.users[b].name);
    });
    sortedUsers.forEach(function(userId) {
        var user = SLACK.context.getMember(userId);

        if (!user.deleted) {
            var ims = user.ims
                ,imsListItem = createImsListItem(ims);

            if (imsListItem) {
                chanListFram.appendChild(imsListItem);
            }
        }
    });
    document.getElementById(R.id.chanList).textContent = "";
    document.getElementById(R.id.chanList).appendChild(chanListFram);
    setRoomFromHashBang();
    updateTitle();
    createContextBackground(function(imgData) {
        document.getElementById(R.id.context).style.backgroundImage = 'url(' +imgData +')';
    });
}

function onTypingUpdated() {
    var typing = SLACK.context.typing;
    for (var chanId in SLACK.context.self.channels) {
        if (!SLACK.context.self.channels[chanId].archived) {
            var dom = document.getElementById(chanId);
            if (typing[chanId])
                dom.classList.add(R.klass.chatList.typing);
            else
                dom.classList.remove(R.klass.chatList.typing);
        }
    }
    for (var userId in SLACK.context.users) {
        var ims = SLACK.context.users[userId].ims;
        if (ims && !ims.archived) {
            var dom = document.getElementById(ims.id);
            if (typing[ims.id])
                dom.classList.add(R.klass.chatList.typing);
            else
                dom.classList.remove(R.klass.chatList.typing);
        }
    }
    updateTypingChat();
}

function updateTypingChat() {
    var typing = SLACK.context.typing;
    if (SELECTED_ROOM && typing[SELECTED_ROOM.id]) {
        var typingUserNames = [], isOutOfSync = false;
        for (var i in typing[SELECTED_ROOM.id]) {
            var member = SLACK.context.getMember(i);
            if (member)
                typingUserNames.push(member.name);
            else
                isOutOfSync = true;
        }
        if (isOutOfSync)
            outOfSync();
        document.getElementById(R.id.typing).textContent = locale.areTyping(typingUserNames);
    } else {
        document.getElementById(R.id.typing).textContent = "";
    }
}

function onNetworkStateUpdated(isNetworkWorking) {
    isNetworkWorking ? document.body.classList.remove(R.klass.noNetwork) : document.body.classList.add(R.klass.noNetwork);
    updateTitle();
}

function onRoomSelected() {
    var name = SELECTED_ROOM.name || (SELECTED_ROOM.user ? SELECTED_ROOM.user.name : undefined);
    if (!name) {
        var members = [];
        for (var i in SELECTED_ROOM.members) {
            members.push(SELECTED_ROOM.members[i].name);
        }
        name = members.join(", ");
    }
    var roomLi = document.getElementById(SELECTED_ROOM.id);
    document.getElementById(R.id.currentRoom.title).textContent = name;
    onRoomUpdated();
    focusInput();

    document.getElementById(R.id.message.file.formContainer).classList.add(R.klass.hidden);
    markRoomAsRead(SELECTED_ROOM);
    if (REPLYING_TO) {
        REPLYING_TO = null;
        onReplyingToUpdated();
    }
    if (EDITING) {
        EDITING = null;
        onReplyingToUpdated();
    }
    updateTypingChat();
}

function onReplyingToUpdated() {
    if (REPLYING_TO) {
        document.body.classList.add(R.klass.replyingTo);
        var domParent = document.getElementById(R.id.message.replyTo)
            ,closeLink = document.createElement("a");
        closeLink.addEventListener("click", function() {
            REPLYING_TO = null;
            onReplyingToUpdated();
        });
        closeLink.className = R.klass.msg.replyTo.close;
        closeLink.textContent = 'x';
        domParent.textContent = "";
        domParent.appendChild(closeLink);
        domParent.appendChild(createMessageDom("reply_" +SELECTED_ROOM.id, REPLYING_TO, true));
        focusInput();
    } else {
        document.body.classList.remove(R.klass.replyingTo);
        document.getElementById(R.id.message.replyTo).textContent = "";
        focusInput();
    }
}

function onEditingUpdated() {
    if (EDITING) {
        document.body.classList.add(R.klass.replyingTo);
        var domParent = document.getElementById(R.id.message.replyTo)
            ,closeLink = document.createElement("a");
        closeLink.addEventListener("click", function() {
            EDITING = null;
            onEditingUpdated();
        });
        closeLink.className = R.klass.msg.replyTo.close;
        closeLink.textContent = 'x';
        domParent.textContent = "";
        domParent.appendChild(closeLink);
        domParent.appendChild(createMessageDom("edit_" +SELECTED_ROOM.id, EDITING, true));
        document.getElementById(R.id.message.input).value = EDITING.text;
        focusInput();
    } else {
        document.body.classList.remove(R.klass.replyingTo);
        document.getElementById(R.id.message.replyTo).textContent = "";
        focusInput();
    }
}

/**
 * @param {string} chanId
 * @param {string} msgId
 * @param {string} reaction
**/
window['toggleReaction'] = function(chanId, msgId, reaction) {
    var hist = SLACK.history[chanId];
    if (!hist)
        return;
    var msg = hist.getMessageById(msgId);
    if (msg) {
        if (msg.hasReactionForUser(reaction, SLACK.context.self.id)) {
            removeReaction(chanId, msgId, reaction);
        } else {
            addReaction(chanId, msgId, reaction);
        }
    }
};

/**
 * Try to resolve emoji from customized context
 * @param {string} emoji
 * @return {Element|string}
**/
function tryGetCustomEmoji(emoji) {
    var loop = {};

    while (!loop[emoji]) {
        var emojisrc= SLACK.context.emojis[emoji];
        if (emojisrc) {
            if (emojisrc.substr(0, 6) == "alias:") {
                loop[emoji] = true;
                emoji = emojisrc.substr(6);
            } else {
                var dom = document.createElement("span");
                dom.className = R.klass.emoji.custom +' ' +R.klass.emoji.emoji;
                dom.style.backgroundImage = "url('" +emojisrc +"')";
                return dom;
            }
        }
        return emoji; // Emoji not found, fallback to std emoji
    }
    return emoji; //loop detected, return first emoji
}

function makeEmojiDom(emojiCode) {
    var emoji = tryGetCustomEmoji(emojiCode);

    if (typeof emoji === "string" && "makeEmoji" in window)
        emoji = window['makeEmoji'](emoji);
    return typeof emoji === "string" ? null : emoji;
}

/**
 * replace all :emoji: codes with corresponding image
 * @param {string} inputString
 * @return {string}
**/
function formatEmojis(inputString) {
    return inputString.replace(/:([^ \t:]+):/g, function(returnFailed, emoji) {
        var emojiDom = makeEmojiDom(emoji);
        if (emojiDom) {
            var domParent = document.createElement("span");
            domParent.className = returnFailed === inputString ? R.klass.emoji.medium : R.klass.emoji.small;
            domParent.appendChild(emojiDom);
            return domParent.outerHTML;
        }
        return returnFailed;
    });
}

/**
 * @param {string} fullText
 * @return {string}
**/
function formatSlackText(fullText) {
    var msgContents = fullText.split(/\r?\n/g);

    for (var msgContentIndex=0, nbMsgContents = msgContents.length; msgContentIndex < nbMsgContents; msgContentIndex++) {
        var msgContent = msgContents[msgContentIndex].trim()
            ,_msgContent = ""
            ,currentMods = {}
            ,quote = false
            ,i =0

        msgContent = msgContent.replace(new RegExp('<([@#]?)([^>]*)>', 'g'),
            function(matched, type, entity) {
                var sub = entity.split('|');

                if (type === '@') {
                    if (!sub[1]) {
                        var user = SLACK.context.getMember(sub[0]);
                        sub[1] = user ? ('@' +user.name) : locale.unknownMember;
                    } else if ('@' !== sub[1][0]) {
                        sub[1] = '@' +sub[1];
                    }
                    sub[0] = '#' +sub[0];
                    sub[2] = R.klass.msg.link +' ' +R.klass.msg.linkuser;
                } else if (type === '#') {
                    if (!sub[1]) {
                        var chan = SLACK.context.getChannel(sub[0]);
                        sub[1] = chan ? ('#' +chan.name) : locale.unknownChannel;
                    } else if ('#' !== sub[1][0]) {
                        sub[1] = '#' +sub[1];
                    }
                    sub[0] = '#' +sub[0];
                    sub[2] = R.klass.msg.link +' ' +R.klass.msg.linkchan;
                } else if (sub[0].indexOf("://") !== -1) {
                    if (!sub[1])
                        sub[1] = sub[0];
                    sub[2] = R.klass.msg.link;
                } else {
                    return matched;
                }
                return '<a href="' +sub[0] +'" class="' +sub[2] +'"' +(!type ? ' target="_blank"' : '') +'>' +sub[1] +'</a>';
            });
        msgContent = formatEmojis(msgContent);
        var msgLength = msgContent.length;
        var isAlphadec = function(c) {
            return ((c >= 'A' && c <= 'Z') ||
                (c >= 'a' && c <= 'z') ||
                (c >= '0' && c <= '9') ||
                "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ".indexOf(c) !== -1);
        }
        ,checkEnd = function(str, pos, c) {
            while (str[pos]) {
                if (isAlphadec(str[pos]) && str[pos] != c && str[pos +1] == c) {
                    return true;
                }
                pos++;
            }
            return false;
        } ,appendMod = function(mods) {
            if (!Object.keys(currentMods).length)
                return "";
            return '<span class="' +Object.keys(mods).join(' ') +'">';
        };

        // Skip trailing
        while (i < msgLength && (msgContent[i] === ' ' || msgContent[i] === '\t'))
            i++;
        if (msgContent.substr(i, 4) === '&gt;') {
            quote = true;
            i += 4;
        }
        for (; i < msgLength; i++) {
            var c = msgContent[i];

            if (c === '<') {
                do {
                    _msgContent += msgContent[i++];
                } while (msgContent[i -1] !== '>');
                i--;
                continue;
            }
            if (!(currentMods[R.klass.msg.style.bold]) && c === '*' && msgContent[i +1] && checkEnd(msgContent, i, c)) {
                if (Object.keys(currentMods).length)
                    _msgContent += '</span>';
                currentMods[R.klass.msg.style.bold] = true;
                _msgContent += appendMod(currentMods);
            } else if (!(currentMods[R.klass.msg.style.strike]) && c === '~' && msgContent[i +1] && checkEnd(msgContent, i, c)) {
                if (Object.keys(currentMods).length)
                    _msgContent += '</span>';
                currentMods[R.klass.msg.style.strike] = true;
                _msgContent += appendMod(currentMods);
            } else if (!(currentMods[R.klass.msg.style.code]) && c === '`' && msgContent[i +1] && checkEnd(msgContent, i, c)) {
                if (Object.keys(currentMods).length)
                    _msgContent += '</span>';
                currentMods[R.klass.msg.style.code] = true;
                _msgContent += appendMod(currentMods);
            } else if (!(currentMods[R.klass.msg.style.italic]) && c === '_' && msgContent[i +1] && checkEnd(msgContent, i, c)) {
                if (Object.keys(currentMods).length)
                    _msgContent += '</span>';
                currentMods[R.klass.msg.style.italic] = true;
                _msgContent += appendMod(currentMods);
            } else {
                var finalFound = false;
                _msgContent += c;

                do {
                    if ((currentMods[R.klass.msg.style.bold]) && c !== '*' && msgContent[i +1] === '*') {
                        delete currentMods[R.klass.msg.style.bold];
                        finalFound = true;
                    } else if ((currentMods[R.klass.msg.style.strike]) && c !== '~' && msgContent[i +1] === '~') {
                        delete currentMods[R.klass.msg.style.strike];
                        finalFound = true;
                    } else if ((currentMods[R.klass.msg.style.code]) && c !== '`' && msgContent[i +1] === '`') {
                        delete currentMods[R.klass.msg.style.code];
                        finalFound = true;
                    } else if ((currentMods[R.klass.msg.style.italic]) && c !== '_' && msgContent[i +1] === '_') {
                        delete currentMods[R.klass.msg.style.italic];
                        finalFound = true;
                    } else {
                        break;
                    }
                    c = msgContent[++i];
                } while (i < msgLength);
                if (finalFound)
                    _msgContent += '</span>' +appendMod(currentMods);
            }
        }
        if (currentMods) {
            // Should not append
            _msgContent += '</span>';
        }
        if (quote)
            msgContents[msgContentIndex] = '<span class="' +R.klass.msg.style.quote +'">' +_msgContent +'</span>';
        else
            msgContents[msgContentIndex] = _msgContent;
    }
    return msgContents.join('<br/>');
}

/**
 * @param {string} channelId
 * @param {SlackMessage} msg
 * @param {boolean=} skipAttachment
 * @return {Element}
**/
function doCreateMeMessageDom(channelId, msg, skipAttachment) {
    var dom = doCreateMessageDom(channelId, msg, skipAttachment);
    dom.classList.add(R.klass.msg.meMessage);
    return dom;
}

/**
 * @param {string} channelId
 * @param {SlackMessage} msg
 * @param {boolean=} skipAttachment
 * @return {Element}
**/
function createMessageDom(channelId, msg, skipAttachment) {
    var dom = (msg.isMeMessage ?
        doCreateMeMessageDom(channelId, msg, skipAttachment):
        doCreateMessageDom(channelId, msg, skipAttachment));
    if (msg.edited)
        dom.classList.add(R.klass.msg.edited);
    return dom;
}

/**
 * @param {number} unreadhi
 * @param {number} unread
**/
function setFavicon(unreadhi, unread) {
    if (!unreadhi && !unread)
        document.getElementById(R.id.favicon).href = "favicon_ok.png";
    else
        document.getElementById(R.id.favicon).href = "favicon.png?h="+unreadhi+"&m="+unread;
}

function setNetErrorFavicon() {
    document.getElementById(R.id.favicon).href = "favicon_err.png";
}

function updateTitle() {
    var hasHl = HIGHLIGHTED_CHANS.length
        ,title = "";

    if (NEXT_RETRY) {
        title = '!' +locale.netErrorShort +' - ';
        setNetErrorFavicon();

    } else if (hasHl) {
        title = "(!" +hasHl +") - ";
        setFavicon(hasHl, hasHl);
    } else {
        var hasUnread = 0;
        SLACK.context.forEachChans(function(i) {
            if (i.lastMsg > i.lastRead)
                hasUnread++;
        });
        if (hasUnread)
            title = "(" +hasUnread +") - ";
        setFavicon(0, hasUnread);
    }
    title += SLACK.context.team.name;
    document.title = title;
}

function spawnNotification() {
    if (!("Notification" in window))
    {}
    else if (Notification.permission === "granted") {
        var now = Date.now();

        if (lastNotificationSpawn + NOTIFICATION_COOLDOWN < now) {
            var n = new Notification(locale.newMessage);
            lastNotificationSpawn = now;
            setTimeout(function() {
                n.close();
            }, NOTIFICATION_DELAY);
        }
    }
    else if (Notification.permission !== "denied")
        Notification.requestPermission();
}

function onRoomUpdated() {
    var chatFrag = document.createDocumentFragment()
        ,currentRoomId = SELECTED_ROOM.id
        ,prevMsg = null
        ,firstTsCombo = 0
        ,prevMsgDom = null;

    if (SLACK.history[currentRoomId])
        SLACK.history[currentRoomId].messages.forEach(function(msg) {
            if (!msg.removed) {
                var dom = createMessageDom(currentRoomId, msg);
                if (prevMsg && prevMsg.userId === msg.userId && msg.userId) {
                    dom.classList.add(R.klass.msg.same.author);
                    if (Math.abs(firstTsCombo -msg.ts) < 30)
                        prevMsgDom.classList.add(R.klass.msg.same.ts);
                    else
                        firstTsCombo = msg.ts;
                } else
                    firstTsCombo = msg.ts;
                if ((!prevMsg || prevMsg.ts <= SELECTED_ROOM.lastRead) && msg.ts > SELECTED_ROOM.lastRead)
                    dom.classList.add(R.klass.msg.firstUnread);
                prevMsg = msg;
                prevMsgDom = dom;
                chatFrag.appendChild(dom);
            }
        });
    var content = document.getElementById(R.id.currentRoom.content);
    content.textContent = "";
    content.appendChild(chatFrag);
    //TODO scroll lock
    content.scrollTop = content.scrollHeight -content.clientHeight;
}

function chatClickDelegate(e) {
    var target = e.target
        ,getMessageId = function(e, target) {
            target = target || e.target;
            while (target !== e.currentTarget && target) {
                if (target.classList.contains(R.klass.msg.item)) {
                    return target.id;
                }
                target = target.parentElement;
            }
        };
    while (target !== e.currentTarget && target) {
        if (target.classList.contains(R.klass.msg.hover.container)) {
            return;
        } else if (target.parentElement && target.parentElement.classList.contains(R.klass.msg.hover.container)) {
            var messageId = getMessageId(e, target);
            if (messageId) {
                messageId = parseFloat(messageId.split("_")[1]);
                var msg = SLACK.history[SELECTED_ROOM.id].getMessage(messageId);

                if (msg && target.classList.contains(R.klass.msg.hover.reply)) {
                    if (EDITING) {
                        EDITING = null;
                        onEditingUpdated();
                    }
                    if (REPLYING_TO !== msg) {
                        REPLYING_TO = msg;
                        onReplyingToUpdated();
                    }
                } else if (msg && target.classList.contains(R.klass.msg.hover.reaction)) {
                    EMOJI_BAR.spawn(document.body, function(emoji) {
                        if (emoji)
                            addReaction(SELECTED_ROOM.id, msg.id, emoji);
                    });
                } else if (msg && target.classList.contains(R.klass.msg.hover.edit)) {
                    if (REPLYING_TO) {
                        REPLYING_TO = null;
                        onReplyingToUpdated();
                    }
                    if (EDITING !== msg) {
                        EDITING = msg;
                        onEditingUpdated();
                    }
                } else if (msg && target.classList.contains(R.klass.msg.hover.remove)) {
                    //TODO promt confirm
                    if (REPLYING_TO) {
                        REPLYING_TO = null;
                        onReplyingToUpdated();
                    }
                    if (EDITING) {
                        EDITING = null;
                        onEditingUpdated();
                    }
                    removeMsg(SELECTED_ROOM, msg);
                }
            }
            return;
        }
        target = target.parentElement;
    }
}

function focusInput() {
    document.getElementById(R.id.message.input).focus();
}

function setRoomFromHashBang() {
    var hashId = document.location.hash.substr(1)
        ,room = SLACK.context.getChannel(hashId)
        ,user = SLACK.context.getMember(hashId);

    if (room && room !== SELECTED_ROOM)
        selectRoom(room);
    else if (user && user.ims)
        selectRoom(user.ims);
}

document.addEventListener('DOMContentLoaded', function() {
    initLang();
    document.getElementById(R.id.currentRoom.content).addEventListener("click", chatClickDelegate);
    window.addEventListener("hashchange", function(e) {
        if (document.location.hash && document.location.hash[0] === '#') {
            setRoomFromHashBang();
        }
    });
    document.getElementById(R.id.message.file.cancel).addEventListener("click", function(e) {
        e.preventDefault();
        document.getElementById(R.id.message.file.error).classList.add(R.klass.hidden);
        document.getElementById(R.id.message.file.formContainer).classList.add(R.klass.hidden);
        document.getElementById(R.id.message.file.fileInput).value = "";
        return false;
    });
    document.getElementById(R.id.message.file.form).addEventListener("submit", function(e) {
        e.preventDefault();
        var fileInput = document.getElementById(R.id.message.file.fileInput)
            ,filename = fileInput.value;

        if (filename) {
            filename = filename.substr(filename.lastIndexOf('\\') +1);
            uploadFile(SELECTED_ROOM, filename, fileInput.files[0], function(errorMsg) {
                var error = document.getElementById(R.id.message.file.error);
                if (errorMsg) {
                    error.textContent = errorMsg;
                    error.classList.remove(R.klass.hidden);
                } else {
                    error.classList.add(R.klass.hidden);
                    document.getElementById(R.id.message.file.fileInput).value = "";
                    document.getElementById(R.id.message.file.formContainer).classList.add(R.klass.hidden);
                }
            });
        }
        return false;
    });
    document.getElementById(R.id.message.file.bt).addEventListener("click", function(e) {
        e.preventDefault();
        if (SELECTED_ROOM) {
            document.getElementById(R.id.message.file.formContainer).classList.remove(R.klass.hidden);
        }
        return false;
    });
    document.getElementById(R.id.message.form).addEventListener("submit", function(e) {
        e.preventDefault();
        var input =document.getElementById(R.id.message.input);
        if (SELECTED_ROOM && input.value) {
            if (onTextEntered(input.value)) {
                input.value = "";
                if (REPLYING_TO) {
                    REPLYING_TO = null;
                    onReplyingToUpdated();
                }
                if (EDITING) {
                    EDITING = null;
                    onReplyingToUpdated();
                }
                document.getElementById(R.id.message.slashComplete).textContent = '';
            }
        }
        focusInput();
        return false;
    });
    window.addEventListener('blur', function() {
        window.hasFocus = false;
    });
    window.addEventListener('focus', function() {
        window.hasFocus = true;
        lastNotificationSpawn = 0;
        if (SELECTED_ROOM)
            markRoomAsRead(SELECTED_ROOM);
        focusInput();
    });

    var lastKeyDown = 0;
    document.getElementById(R.id.message.input).addEventListener('input', function() {
        if (SELECTED_ROOM) {
            var now = Date.now();
            if (lastKeyDown + 3000 < now && (SLACK.context.self.presence || !(SELECTED_ROOM instanceof SlackChan))) {
                sendTyping(SELECTED_ROOM);
                lastKeyDown = now;
            }
            var commands = []
                ,input = this.value;
            if (this.value[0] === '/') {
                var endCmd = input.indexOf(' ')
                    ,inputFinished = endCmd !== -1;
                endCmd = endCmd === -1 ? input.length : endCmd;
                var inputCmd = input.substr(0, endCmd);

                for (var i in SLACK.context.commands.data) {
                    var currentCmd = SLACK.context.commands.data[i]
                    if ((!inputFinished && currentCmd.name.substr(0, endCmd) === inputCmd) ||
                        (inputFinished && currentCmd.name === inputCmd))
                        commands.push(currentCmd);
                }
            }
            commands.sort(function(a, b) {
                return a.serviceName.localeCompare(b.serviceName) || a.name.localeCompare(b.name);
            });
            var slashDom = document.getElementById(R.id.message.slashComplete)
                ,slashFrag = document.createDocumentFragment()
                ,prevService;
            slashDom.textContent = '';
            for (var i =0, nbCmd = commands.length; i < nbCmd; i++) {
                var command = commands[i];
                if (prevService !== command.serviceName) {
                    prevService = command.serviceName;
                    slashFrag.appendChild(createSlashAutocompleteHeader(command.serviceName));
                }
                slashFrag.appendChild(createSlashAutocompleteDom(command));
            }
            slashDom.appendChild(slashFrag);
        }
    });

    window.hasFocus = true;

    //Emoji closure
    (function() {
        var emojiButton = document.getElementById(R.id.message.emoji);
        if ('makeEmoji' in window) {
            var emojiDom = window['makeEmoji']('smile');

            if (emojiDom) {
                emojiButton.innerHTML = "<span class='" +R.klass.emoji.small +"'>" +emojiDom.outerHTML +"</span>";
            } else {
                emojiButton.style.backgroundImage = 'url("smile.svg")';
            }

            emojiDom = window['makeEmoji']('paperclip');
            if (emojiDom) {
                document.getElementById(R.id.message.file.bt).innerHTML = "<span class='" +R.klass.emoji.small +"'>" +emojiDom.outerHTML +"</span>";
            } else {
                document.getElementById(R.id.message.file.bt).style.backgroundImage = 'url("public/paperclip.svg")';
            }

            emojiButton.addEventListener("click", function() {
                EMOJI_BAR.spawn(document.body, function(e) {
                    if (e) document.getElementById(R.id.message.input).value += ":"+e+":";
                    focusInput();
                });
            });
        } else {
            emojiButton.classList.add(R.klass.hidden);
        }
    })();

    startPolling();
});

