
/**
 * @return {Element!}
**/
function createTypingDisplay() {
    var dom = document.createElement("span")
        ,dot1 = document.createElement("span")
        ,dot2 = document.createElement("span")
        ,dot3 = document.createElement("span");

    dom.className = R.klass.typing.container;
    dot1.className = R.klass.typing.dot1;
    dot2.className = R.klass.typing.dot2;
    dot3.className = R.klass.typing.dot3;

    dot1.textContent = dot2.textContent = dot3.textContent = '.';

    dom.appendChild(dot1);
    dom.appendChild(dot2);
    dom.appendChild(dot3);
    return dom;
}

/**
 * @param {SlackChan|SlackGroup} chan
 * @return {Element}
**/
function createChanListItem(chan) {
    var dom = document.createElement("li")
        ,link = document.createElement("a");

    dom.id = chan.id;
    link.href = '#' +chan.id;
    if (chan instanceof SlackGroup) {
        dom.className = R.klass.chatList.entry + " " +R.klass.chatList.typeGroup;
        dom.dataset["count"] = chan.nbMembers -1;
    }
    else if (chan instanceof SlackChan)
        dom.className = R.klass.chatList.entry + " " +R.klass.chatList.typeChannel;
    if (SELECTED_ROOM === chan)
        dom.classList.add(R.klass.selected);
    link.textContent = chan.name;
    dom.appendChild(createTypingDisplay());
    dom.appendChild(link);
    if (chan.lastMsg > chan.lastRead) {
        dom.classList.add(R.klass.unread);
        if (HIGHLIGHTED_CHANS.indexOf(chan) >= 0)
            dom.classList.add(R.klass.unreadHi);
    }
    return dom;
}

/**
 * @param {SlackIms} ims
 * @return {Element}
**/
function createImsListItem(ims) {
    var dom = document.createElement("li")
        ,link = document.createElement("a");

    dom.id = ims.id;
    link.href = '#' +ims.id;
    dom.className = R.klass.chatList.entry + " " +R.klass.chatList.typeDirect;
    link.textContent = ims.user.name;
    dom.appendChild(createTypingDisplay());
    dom.appendChild(link);

    if (!ims.user.presence)
        dom.classList.add(R.klass.presenceAway);
    if (SELECTED_ROOM === ims)
        dom.classList.add(R.klass.selected);

    if (ims.lastMsg > ims.lastRead) {
        dom.classList.add(R.klass.unread);
        if (HIGHLIGHTED_CHANS.indexOf(ims) >= 0)
            dom.classList.add(R.klass.unreadHi);
    }
    return dom;
}

/**
 * @param {string} chanId
 * @param {string} msgId
 * @param {string} reaction
 * @param {Array.<string>} users
 * @return {Element|null}
**/
function createReactionDom(chanId, msgId, reaction, users) {
    var emojiDom = makeEmojiDom(reaction);
    if (emojiDom) {
        var dom = document.createElement("li")
            ,a = document.createElement("a")
            ,emojiContainer = document.createElement("span")
            ,userList = document.createElement("span")
            ,userNames = [];

        for (var i =0, nbUser = users.length; i < nbUser; i++) {
            var user = SLACK.context.getMember(users[i]);
            if (user)
                userNames.push(user.name);
        }
        userNames.sort();
        userList.textContent = userNames.join(", ");
        emojiContainer.appendChild(emojiDom);
        emojiContainer.className = R.klass.emoji.small;
        a.href = "javascript:toggleReaction('" +chanId +"', '" +msgId +"', '" +reaction +"')";
        a.appendChild(emojiContainer);
        a.appendChild(userList);
        dom.className = R.klass.msg.reactions.item;
        dom.appendChild(a);
        return dom;
    }
    return null;
}

/**
 * @param {string} channelId
 * @param {SlackMessage} msg
 * @param {boolean=} skipAttachment
 * @return {Element}
**/
function doCreateMessageDom(channelId, msg, skipAttachment) {
    var dom = document.createElement("div")
        ,msgBlock = document.createElement("div")
        ,ts = document.createElement("div")
        ,text = document.createElement("div")
        ,authorImg = document.createElement("img")
        ,authorName = document.createElement("span")
        ,hover = document.createElement("ul")
        ,hoverReply = document.createElement("li")
        ,attachments = document.createElement("ul")
        ,reactions = document.createElement("ul")
        ,sender = SLACK.context.getMember(msg.userId);

    dom.id = channelId +"_" +msg.ts;
    dom.className = R.klass.msg.item;
    ts.className = R.klass.msg.ts;
    text.className = R.klass.msg.msg;
    authorImg.className = R.klass.msg.authorAvatar;
    authorName.className = R.klass.msg.authorname;
    hover.className = R.klass.msg.hover.container;
    hoverReply.className = R.klass.msg.hover.reply;
    ts.innerHTML = locale.formatDate(msg.ts);
    text.innerHTML = formatSlackText(msg.text);
    authorName.textContent = sender ? sender.name : (msg.username || "?");
    authorImg.src = sender ? sender.icons.image_48 : "";
    hover.appendChild(hoverReply);
    if ('makeEmoji' in window) {
        var hoverReaction = document.createElement("li")
            ,domReply = window['makeEmoji']("arrow_heading_down")
            ,domReaction = window['makeEmoji']("smile")
            ,domEdit = window['makeEmoji']("pencil2")
            ,domRemove = window['makeEmoji']("x");

        hoverReaction.className = R.klass.msg.hover.reaction;

        if (domReaction) {
            hoverReaction.classList.add(R.klass.emoji.small);
            hoverReaction.appendChild(domReaction);
        } else {
            hoverReaction.style.backgroundImage = 'url("smile.svg")';
        }

        if (domReply) {
            hoverReply.classList.add(R.klass.emoji.small);
            hoverReply.appendChild(domReply);
        } else {
            hoverReply.style.backgroundImage = 'url("repl.svg")';
        }
        hover.appendChild(hoverReaction);

        if (msg.userId === SLACK.context.self.id) {
            var hoverEdit = document.createElement("li");
            hoverEdit.className = R.klass.msg.hover.edit;
            if (domEdit)
                hoverEdit.classList.add(R.klass.emoji.small);
            else
                hoverEdit.style.backgroundImage = 'url("edit.svg")';
            hoverEdit.appendChild(domEdit);
            hover.appendChild(hoverEdit);

            var hoverRemove = document.createElement("li");
            hoverRemove.className = R.klass.msg.hover.remove;
            if (domRemove)
                hoverRemove.classList.add(R.klass.emoji.small);
            else
                hoverRemove.style.backgroundImage = 'url("remove.svg")';
            hoverRemove.appendChild(domRemove);
            hover.appendChild(hoverRemove);
        }

    } else {
        hoverReply.style.backgroundImage = 'url("repl.svg")';
        if (msg.userId === SLACK.context.self.id) {
            var hoverEdit = document.createElement("li");
            hoverEdit.className = R.klass.msg.hover.edit;
            hoverEdit.style.backgroundImage = 'url("edit.svg")';
            hover.appendChild(hoverEdit);

            var hoverRemove = document.createElement("li")
            hoverRemove.className = R.klass.msg.hover.remove;
            hoverRemove.style.backgroundImage = 'url("remove.svg")';
            hover.appendChild(hoverRemove);
        }
    }
    dom.appendChild(authorImg);
    msgBlock.appendChild(authorName);
    msgBlock.appendChild(text);
    msgBlock.appendChild(ts);
    msgBlock.appendChild(attachments);
    if (msg.edited) {
        var edited = document.createElement("div");
        edited.textContent = locale.edited;
        edited.className = R.klass.msg.edited;
        msgBlock.appendChild(edited);
    }
    msgBlock.appendChild(reactions);
    msgBlock.className = R.klass.msg.content;
    attachments.className = R.klass.msg.attachment.list;
    reactions.className = R.klass.msg.reactions.container;
    if (skipAttachment !== true) {
        if (msg.reactions) for (var reaction in msg.reactions) {
            var reac = createReactionDom(channelId, msg.id, reaction, msg.reactions[reaction]);
            reac && reactions.appendChild(reac);
        }
        msg.attachments.forEach(function(attachment) {
            var domAttachment = createAttachmentDom(channelId, msg, attachment);
            if (domAttachment)
                attachments.appendChild(domAttachment);
        });
    }
    dom.appendChild(msgBlock);
    dom.appendChild(hover);
    return dom;
}

/**
 * @param {string} channelId
 * @param {SlackMessage} msg
 * @param {*} attachment
 * @return {Element|null}
**/
function createAttachmentDom(channelId, msg, attachment) {
    var rootDom = document.createElement("li")
        ,attachmentBlock = document.createElement("div")

        ,pretext = document.createElement("div")

        ,titleBlock = document.createElement("a")

        ,authorBlock = document.createElement("div")
        ,authorImg = document.createElement("img")
        ,authorName = document.createElement("a")

        ,textBlock = document.createElement("div")
        ,textDom = document.createElement("div")
        ,thumbImgDom = document.createElement("img")
        ,imgDom = document.createElement("img")

        ,footerBlock = document.createElement("div")
        ,footerIcon = document.createElement("img")
        ,footerText = document.createElement("span")
        ,footerTs = document.createElement("span")
    ;

    rootDom.className = R.klass.msg.attachment.container;
    //Color
    var color = "#e3e4e6";
    if (attachment["color"]) {
        if (attachment["color"][0] === '#')
            color = attachment["color"][0];
        else if (attachment["color"] === "good")
            color = "#2fa44f";
        else if (attachment["color"] === "warning")
            color = "#de9e31";
        else if (attachment["color"] === "danger")
            color = "#d50200";
    }
    attachmentBlock.style.borderColor = color;
    attachmentBlock.className = R.klass.msg.attachment.block;

    //Pretext
    pretext.className = R.klass.msg.attachment.pretext;
    if (attachment["pretext"]) {
        pretext.innerHTML = formatSlackText(attachment["pretext"]);
    } else {
        pretext.classList.add(R.klass.hidden);
    }

    //Title
    titleBlock.target = "_blank";
    if (attachment["title"]) {
        titleBlock.innerHTML = formatSlackText(attachment["title"]);
        if (attachment["title_link"]) {
            titleBlock.href = attachment["title_link"];
        }
        titleBlock.className = R.klass.msg.attachment.title;

    } else {
        titleBlock.className = R.klass.hidden + " " +R.klass.msg.attachment.title;
    }

    //Author
    authorName.target = "_blank";
    authorBlock.className = R.klass.msg.author;
    if (attachment["author_name"]) {
        authorName.innerHTML = formatSlackText(attachment["author_name"]);
        authorName.href = attachment["author_link"] || "";
        authorName.className = R.klass.msg.authorname;
        authorImg.className = R.klass.msg.authorAvatar;
        if (attachment["author_icon"])
            authorImg.src = attachment["author_icon"];
        else
            authorImg.classList.add(R.klass.hidden);
    } else {
        authorBlock.classList.add(R.klass.hidden);
    }

    //Text
    textDom.innerHTML = formatSlackText(attachment["text"] || "");
    textDom.klassName = R.klass.msg.attachment.text;

    // Img (small one)
    thumbImgDom.className = R.klass.msg.attachment.thumbImg;
    if (attachment["thumb_url"])
        thumbImgDom.src = attachment["thumb_url"];
    else
        thumbImgDom.classList.add(R.klass.hidden);

    //Img (the big one)
    imgDom.className = R.klass.msg.attachment.img;
    if (attachment["image_url"])
        imgDom.src = attachment["image_url"];
    else
        imgDom.classList.add(R.klass.hidden);

    //Footer
    footerBlock.className = R.klass.msg.attachment.footer;
    footerText.className = R.klass.msg.attachment.footerText;
    footerIcon.className = R.klass.msg.attachment.footerIcon;
    if (attachment["footer"]) {
        footerText.innerHTML = formatSlackText(attachment["footer"]);
        if (attachment["footer_icon"])
            footerIcon.src = attachment["footer_icon"];
        else
            footerIcon.classList.add(R.klass.hidden);
    } else {
        footerIcon.classList.add(R.klass.hidden);
        footerText.classList.add(R.klass.hidden);
    }

    //Ts
    footerTs.className = R.klass.msg.ts;
    if (attachment["ts"])
        footerTs.innerHTML = locale.formatDate(attachment["ts"]);
    else
        footerTs.classList.add(R.klass.hidden);

    // TODO Field [ {title, value, short } ]
    // TODO actions (button stuff)

    authorBlock.appendChild(authorImg);
    authorBlock.appendChild(authorName);
    textBlock.appendChild(textDom);
    textBlock.appendChild(thumbImgDom);
    footerBlock.appendChild(footerIcon);
    footerBlock.appendChild(footerText);
    footerBlock.appendChild(footerTs);
    attachmentBlock.appendChild(titleBlock);
    attachmentBlock.appendChild(authorBlock);
    attachmentBlock.appendChild(textBlock);
    attachmentBlock.appendChild(imgDom);
    attachmentBlock.appendChild(footerBlock);
    rootDom.appendChild(pretext);
    rootDom.appendChild(attachmentBlock);
    return rootDom;
}

/**
 * @param {string} servicename
 * @return {Element}
**/
function createSlashAutocompleteHeader(servicename) {
    var lh = document.createElement("lh");
    lh.textContent = servicename;
    lh.className = R.klass.commands.header;
    return lh;
}

/**
 * @param {SlackCommand} cmd
 * @return {Element}
**/
function createSlashAutocompleteDom(cmd) {
    var li = document.createElement("li")
        ,name = document.createElement("span")
        ,usage = document.createElement("span")
        ,desc = document.createElement("span");

    name.textContent = cmd.name;
    usage.textContent = cmd.usage;
    desc.textContent = cmd.desc;

    li.appendChild(name);
    li.appendChild(usage);
    li.appendChild(desc);

    li.className = R.klass.commands.item;
    name.className = R.klass.commands.name;
    usage.className = R.klass.commands.usage;
    desc.className = R.klass.commands.desc;
    return li;
}

