<html>
<!-- Empty head might be needed for setSenderImage -->
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta charset=“utf-8”>
</head>

<body>
      <div class="navbar-wrapper">
          <div id="navbar">
            <div id="backButton" class="nav-button non-action-button nav-left" onmouseover="addBackButtonHoverProperty()" onclick="backToWelcomeView()" title="Hide chat view">
                <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
                    <path d="M11.67 3.87L9.9 2.1 0 12l9.9 9.9 1.77-1.77L3.54 12z"/>
                    <path fill="none" d="M0 0h24v24H0z"/>
                </svg>
            </div>
            <div id="nav-contactid" class="nav-left">
                <div id="nav-contactid-alias"></div>
                <div id="nav-contactid-bestId"></div>
            </div>
            <div style="display:none" class="deactivated nav-button action-button nav-right" onclick="moreOptions()" title="Options">
                <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
                    <path d="M0 0h24v24H0z" fill="none"/>
                    <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>
                </svg>
            </div>
            <div id="callButtons"> <!-- callButtons block allows more efficient hiding of placeCallButton and placeAudioCallButton -->
                <div id="placeCallButton" class="nav-button action-button nav-right" onclick="placeCall()" title="Place video call">
                    <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                        <path d="M0 0h24v24H0z" fill="none"/>
                        <path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z"/>
                    </svg>
                </div>
                <div id="placeAudioCallButton" class="nav-button action-button nav-right" onclick="placeAudioCall()" title="Place audio call">
                    <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                        <path fill="none" d="M0 0h24v24H0z"/>
                        <path d="M20.01 15.38c-1.23 0-2.42-.2-3.53-.56-.35-.12-.74-.03-1.01.24l-1.57 1.97c-2.83-1.35-5.48-3.9-6.89-6.83l1.95-1.66c.27-.28.35-.67.24-1.02-.37-1.11-.56-2.3-.56-3.53 0-.54-.45-.99-.99-.99H4.19C3.65 3 3 3.24 3 3.99 3 13.28 10.73 21 20.01 21c.71 0 .99-.63.99-1.18v-3.45c0-.54-.45-.99-.99-.99z"/>
                    </svg>
                </div>
            </div>
            <div id="addToConversationsButton" class="nav-button action-button nav-right" onclick="addToConversations()" title="Add to conversations">
                <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                    <path d="M0 0h24v24H0z" fill="none"/>
                    <path d="M15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-9-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9 4c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
                </svg>
            </div>
            <div id="addBannedContactButton" class="nav-button action-critical-button nav-right" onclick="addBannedContact()" title="Unban banned contact">
                <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                    <path fill="none" d="M0 0h24v24H0V0z"/>
                    <circle cx="15" cy="8" r="4"/>
                    <path d="M23 20v-2c0-2.3-4.1-3.7-6.9-3.9l6 5.9h.9zm-11.6-5.5C9.2 15.1 7 16.3 7 18v2h9.9l4 4 1.3-1.3-21-20.9L0 3.1l4 4V10H1v2h3v3h2v-3h2.9l2.5 2.5zM6 10v-.9l.9.9H6z"/>
                </svg>
            </div>
          </div>
          <div id="invitation">
            <div id="text">
            </div>
            <div id="actions">
              <div id="accept-btn" class="invitation-button button-green" onclick="acceptInvitation()" >Accept</div>
              <div id="refuse-btn" class="invitation-button button-red" onclick="refuseInvitation()" >Refuse</div>
              <div id="block-btn" class="invitation-button button-red" onclick="blockConversation()" >Block</div>
            </div>
          </div>
      </div>
    <div id="container">
      <!-- messages are dynamically inserted here -->
      <div id="sendMessage">
        <div class="nav-button action-button" onclick="sendFile()" title="Send File">
            <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                <path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"/>
                <path d="M0 0h24v24H0z" fill="none"/>
            </svg>
        </div>
        <textarea id="message" autofocus placeholder="Type a message" onkeyup="grow_text_area()" onkeydown="process_messagebar_keydown()" rows="1" disabled="false"></textarea>
        <div class="nav-button action-button" onclick="sendMessage()" title="Send">
            <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
                <path d="M0 0h24v24H0z" fill="none"/>
            </svg>
        </div>
      </div>
    </div>
</body>

<script>
"use strict"

/* Constants used at several places*/
const messageBarPlaceHolder = "Type a message"
const avatar_size = 35
// scrollDetectionThresh represents the number of pixels a user can scroll
// without disabling the automatic go-back-to-bottom when a new message is
// received
const scrollDetectionThresh = 200

/* Buffers */
var historyBufferIndex = 0 // When showing a large amount of interactions, this counter store the interaction's index to show
var historyBuffer = [] // Before showing a large amount of interactions, this array is used as a buffer.

/* We retrieve refs to the most used navbar and message bar elements for efficiency purposes */
/* NOTE: always use getElementById when possible, way more efficient */
const backButton        = document.getElementById("backButton")
const aliasField        = document.getElementById("nav-contactid-alias")
const bestIdField       = document.getElementById("nav-contactid-bestId")
const idField           = document.getElementById("nav-contactid")
const messageBar        = document.getElementById("sendMessage")
const messageBarInput   = document.getElementById("message")
const container         = document.getElementById("container")
const addToConvButton   = document.getElementById("addToConversationsButton")
const invitation        = document.getElementById("invitation")
const navbar            = document.getElementById("navbar")
const invitationText    = document.getElementById("text")

/* States: allows us to avoid re-doing something if it isn't meaningful */
var displayLinksEnabled = false
var hoverBackButtonAllowed = true
var hasInvitation = false
var isTemporary = false
var isBanned = false
var isInitialLoading = false

/**
 * Generic wrapper. Execute passed function keeping scroll position identical.
 *
 * @param func function to execute
 * @param args parameters as array
 */
function exec_keeping_scroll_position(func, args) {
    const messages = document.getElementById("messages")

    if (messages) {
        var atEnd = messages.scrollTop >= messages.scrollHeight - messages.clientHeight - scrollDetectionThresh
        func(...args)
        if (atEnd) {
            messages.scrollTop = messages.scrollHeight
        }
    } else {
        // should not happen
        func(...args)
    }
}

/**
 * Reset scrollbar at a given position.
 * @param scroll position at which the scrollbar should be set.
 *               Here position means the number of pixels scrolled,
 *               i.e. scroll = 0 resets the scrollbar at the bottom.
 */
function back_to_scroll(scroll) {
    const messages = document.getElementById("messages")
    if (messages) {
        messages.scrollTop = messages.scrollHeight - scroll
    }
}

/**
 * Reset scrollbar at bottom.
 */
function back_to_bottom() {
    back_to_scroll(0)
}

/**
 * Update common frame between conversations.
 *
 * Whenever the current conversation is switched, information from the navbar
 * and message bar have to be updated to match new contact. This function
 * handles most of the required work (except the showing/hiding the invitation,
 * which is handled by showInvitation()).
 *
 * @param banned 	whether contact is banned or not
 * @param temporary	whether contact is temporary or not
 * @param alias
 * @param bestId
 */
/* exported update_chatview_frame */
function update_chatview_frame(banned, temporary, alias, bestid) {
    navbar.style.display = "none"

    hoverBackButtonAllowed = true

    aliasField.innerHTML = (alias ? alias : bestid)

    if(alias) {
        bestIdField.innerHTML = bestid
        idField.classList.remove("oneEntry")
    } else {
        idField.classList.add("oneEntry")
    }

    if (isBanned !== banned) {
        isBanned = banned
        hideMessageBar(banned)

        if(banned) {
            // contact is banned. update navbar and states
            navbar.classList.add("onBannedState")
        } else {
            navbar.classList.remove("onBannedState")
        }
    } else if (isTemporary !== temporary) {
        isTemporary = temporary
        if (temporary) {
            addToConvButton.style.display = "flex"
            messageBarInput.placeholder = "Note: an interaction will create a new contact."
        } else {
            addToConvButton.style.display = ""
            messageBarInput.placeholder = messageBarPlaceHolder
        }
    }

    navbar.style.display = ""
}

/**
 * Hide or show invitation.
 *
 * Invitation is hidden if no contactAlias/invalid alias is passed.
 * Otherwise, invitation div is updated.
 *
 * @param contactAlias
 */
/* exported showInvitation */
function showInvitation(contactAlias) {
    if (!contactAlias) {
        if (hasInvitation) {
            hasInvitation = false
            invitation.style.visibility = ""
        }
    } else {
        hasInvitation = true
        invitationText.innerHTML = "<h1>" + contactAlias + " sends you an invitation</h1>"
      + "Do you want to add them to the conversations list?<br>"
      + "Note: you can automatically accept this invitation by sending a message."
        invitation.style.visibility = "visible"
    }
}

/**
 * Hide or show navbar, and update body top padding accordingly.
 *
 * @param isVisible whether navbar should be displayed or not
 */
/* exported displayNavbar */
function displayNavbar(isVisible)
{
    if (isVisible) {
        navbar.classList.remove("hiddenState")
        document.documentElement.style.setProperty("--navbar-size", undefined)
    } else {
        navbar.classList.add("hiddenState")
        document.documentElement.style.setProperty("--navbar-size", "0")
    }
}

/**
 * Hide or show message bar, and update body bottom padding accordingly.
 *
 * @param isHidden whether message bar should be displayed or not
 */
/* exported hideMessageBar */
function hideMessageBar(isHidden) {
    if (isHidden) {
        messageBar.classList.add("hiddenState")
        document.body.style.setProperty("--messagebar-size", "0")
    } else {
        messageBar.classList.remove("hiddenState")
        document.body.style.removeProperty("--messagebar-size")
    }
}

/* exported setDisplayLinks */
function setDisplayLinks(display) {
    displayLinksEnabled = display
}

/**
 * This event handler dynamically resizes the message bar depending on the amount of
 * text entered, while adjusting the body paddings so that that the message bar doesn't
 * overlap messages when it grows.
 */
/* exported grow_text_area */
function grow_text_area() {
    exec_keeping_scroll_position(function(){
        var old_height = window.getComputedStyle(messageBar).height
        messageBarInput.style.height = "auto" /* <-- necessary, no clue why */
        messageBarInput.style.height = messageBarInput.scrollHeight + "px"
        var new_height = window.getComputedStyle(messageBar).height

        var msgbar_size = window.getComputedStyle(document.body).getPropertyValue("--messagebar-size")
        var total_size = parseInt(msgbar_size) + parseInt(new_height) - parseInt(old_height)

        document.body.style.setProperty("--messagebar-size", total_size.toString() + "px")
    }, [])
}

/**
 * This event handler processes keydown events from the message bar. When pressed key is
 * the enter key, send the message unless shift or control was pressed too.
 *
 * @param key the pressed key
 */
/* exported process_messagebar_keydown */
function process_messagebar_keydown(key) {
    key = key || event
    var map = {}
    map[key.keyCode] = key.type == "keydown"
    if (key.ctrlKey || key.shiftKey) {
        return true
    }
    if (map[13]) {
        sendMessage()
        key.preventDefault()
    }
    return true
}

/**
 * Disable or enable textarea.
 *
 * @param isDisabled whether message bar should be enabled or disabled
 */
/* exported disableSendMessage */
function disableSendMessage(isDisabled)
{
    messageBarInput.disabled = isDisabled
}

/**
 * This event handler adds the hover property back to the "back to welcome view"
 * button.
 *
 * This is a hack. It needs some explanations.
 *
 * Problem: Whenever the "back to welcome view" button is clicked, the webview
 * freezes and the GTK ring welcome view is displayed. While the freeze
 * itself is perfectly fine (probably necessary for good performances), this
 * is a big problem for us when the user opens a chatview again: Since the
 * chatview was freezed, the back button has «remembered» the hover state and
 * still displays the blue background for a small instant. This is a very bad
 * looking artefact.
 *
 * In order to counter this problem, we introduced the following evil mechanism:
 * Whenever a user clicks on the "back to welcome view" button, the hover
 * property is disabled. The hover property stays disabled until the user calls
 * this event handler by hover-ing the button.
 */
/* exported addBackButtonHoverProperty */
function addBackButtonHoverProperty()
{
    if(hoverBackButtonAllowed) {
        backButton.classList.add("non-action-button")
    }
}

/*
 * Update timestamps messages.
 */
function updateView() {
    const messages = document.getElementById("messages")
    if (messages)
        updateTimestamps(messages)
}

setInterval(updateView, 60000)

/*
 * FIXME updateTimestamps has to be called when the window is resized because
 * updateTimestamps also handles timestamp repositioning (responsive view). This
 * task should be done in a separate function.
 */
window.onresize = function() {
    updateView()
}

/* exported addBannedContact */
function addBannedContact()
{
    window.prompt("UNBLOCK")
}

/* exported addToConversations */
function addToConversations()
{
    window.prompt("ADD_TO_CONVERSATIONS")
}

/* exported placeCall */
function placeCall()
{
    window.prompt("PLACE_CALL")
}

/* exported placeAudioCall */
function placeAudioCall()
{
    window.prompt("PLACE_AUDIO_CALL")
}

/* exported backToWelcomeView */
function backToWelcomeView()
{
    backButton.classList.remove("non-action-button")
    hoverBackButtonAllowed = false
    window.prompt("CLOSE_CHATVIEW")
}

/**
 * Transform a date to a string group like "1 hour ago".
 *
 * @param date
 */
function formatDate(date) {
    const seconds = Math.floor((new Date() - date) / 1000)
    var interval = Math.floor(seconds / (3600 * 24))
    if (interval > 5) {
        return date.toLocaleDateString()
    }
    if (interval > 1) {
        return interval + " days ago"
    }
    if (interval === 1) {
        return interval + " day ago"
    }
    interval = Math.floor(seconds / 3600)
    if (interval > 1) {
        return interval + " hours ago"
    }
    if (interval === 1) {
        return interval + " hour ago"
    }
    interval = Math.floor(seconds / 60)
    if (interval > 1) {
        return interval + " minutes ago"
    }
    return "just now"
}

/**
 * Send content of message bar
 */
function sendMessage()
{
    var message = messageBarInput.value
    if (message.length > 0) {
        messageBarInput.value = ""
        window.prompt("SEND:" + message)
    }
}

/* exported acceptInvitation */
function acceptInvitation()
{
    window.prompt("ACCEPT")
}

/* exported refuseInvitation */
function refuseInvitation()
{
    window.prompt("REFUSE")
}

/* exported blockConversation */
function blockConversation()
{
    window.prompt("BLOCK")
}

/* exported sendFile */
function sendFile()
{
    window.prompt("SEND_FILE")
}

/**
 * Clear all messages.
 */
/* exported clearMessages */
function clearMessages()
{
    const messages = document.getElementById("messages")
    if (messages) {
        messages.parentNode.removeChild(messages)
    }
}

/**
 * Convert text to HTML.
 */
function escapeHtml(html)
{
    var text = document.createTextNode(html)
    var div = document.createElement("div")
    div.appendChild(text)
    return div.innerHTML
}


/**
 * Get the youtube video id from a URL.
 * @param url
 */
function youtube_id(url) {
    const regExp = /^.*(youtu\.be\/|v\/|\/u\/w|embed\/|watch\?v=|&v=)([^#&?]*).*/
    const match = url.match(regExp)
    return (match && match[2].length == 11) ? match[2] : null
}

/**
 * Returns HTML message from the message text, cleaned and linkified.
 * @param message_text
 */
function getMessageHtml(message_text)
{
    const escaped_message = escapeHtml(message_text)
    var linkified_message = linkifyHtml(escaped_message, {})  // eslint-disable-line no-undef

    const textPart = document.createElement("pre")
    textPart.innerHTML = linkified_message

    return textPart.outerHTML
}

/**
 * Returns the message status, formatted for display
 * @param message_delivery_status
 */
/* exported getMessageDeliveryStatusText */
function getMessageDeliveryStatusText(message_delivery_status)
{
    var formatted_delivery_status = message_delivery_status

    switch(message_delivery_status)
    {
    case "sending":
    case "ongoing":
        formatted_delivery_status = "Sending<svg overflow='visible' viewBox='0 -2 16 14' height='16px' width='16px'><circle class='status_circle anim-first' cx='4' cy='12' r='1'/><circle class='status_circle anim-second' cx='8' cy='12' r='1'/><circle class='status_circle anim-third' cx='12' cy='12' r='1'/></svg>"
        break
    case "failure":
        formatted_delivery_status = "Failure <svg overflow='visible' viewBox='0 -2 16 14' height='16px' width='16px'><path class='status-x x-first' stroke='#AA0000' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' fill='none' d='M4,4 L12,12'/><path class='status-x x-second' stroke='#AA0000' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' fill='none' d='M12,4 L4,12'/></svg>"
        break
    case "sent":
    case "finished":
    case "unknown":
    case "read":
        formatted_delivery_status = ""
        break
    default:
        break
    }

    return formatted_delivery_status
}

/**
 * Returns the message date, formatted for display
 */
function getMessageTimestampText(message_timestamp, custom_format)
{
    const date = new Date(1000 * message_timestamp)
    if(custom_format) {
        return formatDate(date)
    } else {
        return date.toLocaleString()
    }
}

/**
 * Merge timestamps if they are from the same group. For instance, several "1 hour ago"
 * timestamps will be merged into a single one.
 *
 * @param baseNode
 * @param endIndex
 * @param message_div
 */
function cleanPreviousTimestamps (baseNode, endIndex, messages_div) {
    // Remove previous elements with the same formatted timestamp
    for (var c = endIndex - 1 ; c >= 0 ; --c) {
        const child = messages_div.children[c]
        if (child.className.indexOf("timestamp") !== -1) {
            if (child.className === baseNode.className &&
                    child.innerHTML === baseNode.innerHTML) {
                messages_div.removeChild(child)
            } else {
                break // A different timestamp is met, we can stop here.
            }
        }
    }
}

/**
 * Update timestamps.
 * @param message_div
 */
function updateTimestamps(messages_div) {
    const timestamps = messages_div.querySelector(".timestamp")
    const is_image_out = messages_div.querySelector(".message_out .sender_image")
    const is_image_in = messages_div.querySelector(".message_in .sender_image")
    if (timestamps) {
        for ( var c = 0 ; c < messages_div.children.length ; ++c) {
            const child = messages_div.children[c]
            if (child.className.indexOf("timestamp") !== -1) {
                // Update timestamp
                child.innerHTML = getMessageTimestampText(child.getAttribute("message_timestamp"), true)

                // FIXME this is EVIL HACK. Responsive behaviour should be handled by CSS, not JS
                var desktop_margin = "25%"
                const height = document.body.clientHeight
                const width = document.body.clientWidth
                if (width <= 1920 || height <= 1080) {
                    desktop_margin = "15%"
                }
                if (width <= 1000 || height <= 480) {
                    desktop_margin = "0px"
                }
                if (child.className.indexOf("timestamp_out") !== -1) {
                    const avatar_px = is_image_out ? (is_image_out.offsetHeight === avatar_size ? "60px" : "20px") : "20px"
                    child.style.paddingRight = `calc(${desktop_margin} + ${avatar_px})`
                } else if (child.className.indexOf("timestamp_in") !== -1) {
                    const avatar_px = is_image_in ? (is_image_in.offsetHeight === avatar_size ? "60px" : "20px") : "20px"
                    child.style.paddingLeft = `calc(${desktop_margin} + ${avatar_px})`
                }
                // Remove previous elements with the same formatted timestamp
                cleanPreviousTimestamps(child, c, messages_div)
            }
        }
    }
}

/**
 * Convert a value in filesize
 */
function humanFileSize(bytes) {
    var thresh = 1024
    if(Math.abs(bytes) < thresh) {
        return bytes + " B"
    }
    var units = ["kB","MB","GB","TB","PB","EB","ZB","YB"]
    var u = -1
    do {
        bytes /= thresh
        ++u
    } while(Math.abs(bytes) >= thresh && u < units.length - 1)
    return bytes.toFixed(1)+" "+units[u]
}

/**
 * Change the value of the progress bar.
 *
 * @param progress_bar
 * @param message_object
 */
function updateProgressBar(progress_bar, message_object) {
    var delivery_status = message_object["delivery_status"]
    if ("progress" in message_object && !isErrorStatus(delivery_status) && message_object["progress"] !== 100) {
        var progress_percent = (100 * message_object["progress"] / message_object["totalSize"])
        if (progress_percent !== 100)
            progress_bar.childNodes[0].setAttribute("style", "width: " + progress_percent + "%")
        else
            progress_bar.setAttribute("style", "display: none")
    } else
        progress_bar.setAttribute("style", "display: none")
}

/**
 * Check if a status is an error status
 * @param
 */
function isErrorStatus(status) {
    return (status === "failure"
         || status === "awaiting peer timeout"
         || status === "canceled"
         || status === "unjoinable peer")
}

/**
 * Build a new file interaction
 * @param message_id
 */
function fileInteraction(message_id) {
    var message_wrapper = document.createElement("div")
    message_wrapper.setAttribute("class", "message_wrapper")

    /* A file interaction contains buttons at the left for status information
       or accept/refuse actions. The text is bold and clickable. */
    var left_buttons = document.createElement("div")
    left_buttons.setAttribute("class", "left_buttons")
    message_wrapper.appendChild(left_buttons)
    var text_div = document.createElement("div")
    text_div.setAttribute("class", "text")

    text_div.addEventListener("click", function () {
        // ask ring to open the file
        const filename = document.querySelector("#message_" + message_id + " .full").innerText
        window.prompt("OPEN_FILE:" + filename)
    })

    var full_div = document.createElement("div")
    full_div.setAttribute("class", "full")
    full_div.style = "visibility: hidden; display: none;"
    var message_text = document.createElement("div")
    message_text.setAttribute("class", "filename")

    // And some informations like size or error message.
    var informations_div = document.createElement("div")
    informations_div.setAttribute("class", "informations")
    text_div.appendChild(message_text)
    text_div.appendChild(full_div)
    text_div.appendChild(informations_div)
    message_wrapper.appendChild(text_div)

    // And finally, a progress bar
    var message_transfer_progress_bar = document.createElement("span")
    message_transfer_progress_bar.setAttribute("class", "message_progress_bar")
    var message_transfer_progress_completion = document.createElement("span")
    message_transfer_progress_bar.appendChild(message_transfer_progress_completion)
    message_wrapper.appendChild(message_transfer_progress_bar)
    return message_wrapper
}

/**
 * Build information text for passed file interaction message object
 *
 * @param message_object message object containing file interaction info
 */
function buildFileInformationText(message_object) {
    var informations_txt = getMessageTimestampText(message_object["timestamp"], true)
    if (message_object["totalSize"] && message_object["progress"]) {
        if (message_object["delivery_status"] === "finished") {
            informations_txt += " - " + humanFileSize(message_object["totalSize"])
        } else {
            informations_txt += " - " + humanFileSize(message_object["progress"])
                         + " / " + humanFileSize(message_object["totalSize"])
        }
    }

    return informations_txt + " - " + message_object["delivery_status"]
}

/**
 * Update a file interaction (icons + filename + status + progress bar)
 *
 * @param message_div the message to update
 * @param message_object new informations
 * @param forceTypeToFile
 */
function updateFileInteraction(message_div, message_object, forceTypeToFile = false) {
    if (!message_div.querySelector(".informations")) return // media

    var acceptSvg = "<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z\"/></svg>",
        refuseSvg = "<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/><path d=\"M0 0h24v24H0z\" fill=\"none\"/></svg>",
        fileSvg = "<svg fill=\"#000000\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z\"/><path d=\"M0 0h24v24H0z\" fill=\"none\"/></svg>",
        warningSvg = "<svg fill=\"#000000\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>"
    var message_delivery_status = message_object["delivery_status"]
    var message_direction = message_object["direction"]
    var message_id = message_object["id"]
    var message_text = message_object["text"]


    if (isImage(message_text) && message_delivery_status === "finished" && displayLinksEnabled && !forceTypeToFile) {
        // Replace the old wrapper by the downloaded image
        if (message_div.querySelector(".message_wrapper")) {
            var wrapper = message_div.querySelector(".message_wrapper")
            wrapper.parentNode.removeChild(wrapper)
        }
        message_div.append(mediaInteraction(message_id, message_text))
        message_div.querySelector("img").id = message_id
        message_div.querySelector("img").msg_obj = message_object
        message_div.querySelector("img").onerror = function() {
            message_div = document.getElementById("message_" + this.id)
            var wrapper = message_div.querySelector(".message_wrapper")
            if (wrapper) {
                wrapper.parentNode.removeChild(wrapper)
            }
            message_div.append(fileInteraction(message_id))
            updateFileInteraction(message_div, this.msg_obj, true)
        }
        return
    }

    // Set informations text
    var informations_div = message_div.querySelector(".informations")
    informations_div.innerText = buildFileInformationText(message_object)

    // Update flat buttons
    var left_buttons = message_div.querySelector(".left_buttons")
    left_buttons.innerHTML = ""
    if (message_delivery_status === "awaiting peer" || message_delivery_status === "awaiting host" || message_delivery_status.indexOf("ongoing") === 0) {
        if (message_direction === "in" && message_delivery_status.indexOf("ongoing") !== 0) {
            // add buttons to accept or refuse a call.
            var accept_button = document.createElement("div")
            accept_button.innerHTML = acceptSvg
            accept_button.setAttribute("title", "Accept")
            accept_button.setAttribute("class", "flat-button accept")
            accept_button.onclick = function() {
                window.prompt("ACCEPT_FILE:" + message_id)
            }
            left_buttons.appendChild(accept_button)
        }
        var refuse_button = document.createElement("div")
        refuse_button.innerHTML = refuseSvg
        refuse_button.setAttribute("title", "Refuse")
        refuse_button.setAttribute("class", "flat-button refuse")
        refuse_button.onclick = function() {
            window.prompt("REFUSE_FILE:" + message_id)
        }
        left_buttons.appendChild(refuse_button)
    } else {
        var status_button = document.createElement("div")
        var statusFile = fileSvg
        if (isErrorStatus(message_delivery_status))
            statusFile = warningSvg
        status_button.innerHTML = statusFile
        status_button.setAttribute("class", "flat-button")
        left_buttons.appendChild(status_button)
    }

    message_div.querySelector(".full").innerText = message_text
    message_div.querySelector(".filename").innerText = message_text.split("/").pop()
    updateProgressBar(message_div.querySelector(".message_progress_bar"), message_object)
}

/**
 * Return if a file is an image
 * @param file
 */
function isImage(file) {
    return file.toLowerCase().match(/\.(jpeg|jpg|gif|png)$/) !== null
}

/**
 * Return if a file is a youtube video
 * @param file
 */
function isVideo(file) {
    const availableProtocols = ["http:", "https:"]
    const videoHostname = ["youtube.com", "www.youtube.com", "youtu.be"]
    const urlParser = document.createElement("a")
    urlParser.href = file
    return (availableProtocols.includes(urlParser.protocol) && videoHostname.includes(urlParser.hostname))
}

/**
 * Build a container for passed video thumbnail
 * @param linkElt video thumbnail div
 */
function buildVideoContainer(linkElt) {
    const containerElt = document.createElement("div")
    containerElt.setAttribute("class", "containerVideo")
    const playDiv = document.createElement("div")
    playDiv.setAttribute("class", "playVideo")
    playDiv.innerHTML = "<svg fill=\"#ffffff\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\
        <path d=\"M8 5v14l11-7z\"/>\
        <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\
    </svg>"
    linkElt.appendChild(playDiv)
    containerElt.appendChild(linkElt)

    return containerElt
}

/**
 * Try to show an image or a video link (youtube for now)
 * @param message_id
 * @param link to show
 * @param ytid if it's a youtube video
 * @param noerror
 */
function mediaInteraction(message_id, link, ytid, noerror) {
    /* TODO promise?
     Try to display images. */
    const media_wrapper = document.createElement("div")
    media_wrapper.setAttribute("class", "media_wrapper")
    const linkElt = document.createElement("a")
    linkElt.href = link
    linkElt.style = "text-decoration: none; border:none;"
    const imageElt = document.createElement("img")
    /* Note, here, we don't check the size of the image.
     in the future, we can check the content-type and content-length with a request
     and maybe disable svg */
    if (noerror)
        imageElt.setAttribute("onerror", "this.style.display='none'")

    imageElt.src = ytid ? `http://img.youtube.com/vi/${ytid}/0.jpg` : link
    if (isInitialLoading || messages.scrollTop >= messages.scrollHeight - messages.clientHeight - scrollDetectionThresh) {
        /* Hack to keep the scrollbar at the bottom.
           Images are loaded asynchronously and the scrollbar position is
           changed each time an image is loaded and displayed. In order to
           make sure the scrollbar stays at the bottom, reset scrollbar
           position each time an image was loaded. */
        imageElt.onload = back_to_bottom
    }
    linkElt.appendChild(imageElt)

    if (ytid) {
        media_wrapper.appendChild(buildVideoContainer(linkElt))
    } else {
        media_wrapper.appendChild(linkElt)
    }
    return media_wrapper
}

/**
 * Build a new text interaction
 * @param message_id
 * @param htmlText the DOM to show
 */
function textInteraction(message_id, htmlText) {
    const message_wrapper = document.createElement("div")
    message_wrapper.setAttribute("class", "message_wrapper")
    var message_text = document.createElement("span")
    message_text.setAttribute("class", "message_text")
    message_text.innerHTML = htmlText
    message_wrapper.appendChild(message_text)
    // TODO STATUS
    return message_wrapper
}

/**
 * Update a text interaction (text)
 * @param message_div the message to update
 * @param delivery_status the status of the message
 */
function updateTextInteraction(message_div, delivery_status) {
    if (!message_div.querySelector(".message_text")) return // media
    var sending = message_div.querySelector(".sending")
    switch(delivery_status)
    {
    case "ongoing":
    case "sending":
        if (!sending) {
            sending = document.createElement("div")
            sending.setAttribute("class", "sending")
            sending.innerHTML = "<svg overflow=\"hidden\" viewBox=\"0 -2 16 14\" height=\"16px\" width=\"16px\"><circle class=\"status_circle anim-first\" cx=\"4\" cy=\"12\" r=\"1\"/><circle class=\"status_circle anim-second\" cx=\"8\" cy=\"12\" r=\"1\"/><circle class=\"status_circle anim-third\" cx=\"12\" cy=\"12\" r=\"1\"/></svg>"
            // add sending animation to message;
            message_div.insertBefore(sending, message_div.querySelector(".menu_interaction"))
        }
        message_div.querySelector(".message_text").style = "color: #888"
        break
    case "failure":
        // change text color to red
        message_div.querySelector(".message_wrapper").style = "background-color: #f3a6a6"
        message_div.querySelector(".message_text").style = "color: #000"
        var failure_div = message_div.querySelector(".failure")
        if (!failure_div) {
            failure_div = document.createElement("div")
            failure_div.setAttribute("class", "failure")
            failure_div.innerHTML = "<svg overflow=\"visible\" viewBox=\"0 -2 16 14\" height=\"16px\" width=\"16px\"><path class=\"status-x x-first\" stroke=\"#AA0000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"3\" fill=\"none\" d=\"M4,4 L12,12\"/><path class=\"status-x x-second\" stroke=\"#AA0000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"3\" fill=\"none\" d=\"M12,4 L4,12\"/></svg>"
            // add failure animation to message
            message_div.insertBefore(failure_div, message_div.querySelector(".menu_interaction"))
        }
        if (sending) sending.style.display = "none"
        break
    case "sent":
    case "finished":
    case "unknown":
    case "read":
        // change text color to black
        message_div.querySelector(".message_text").style = "color: #000"
        if (sending) sending.style.display = "none"
        break
    default:
        break
    }
}

/**
 * Build a new interaction (call or contact)
 */
function actionInteraction() {
    var message_wrapper = document.createElement("div")
    message_wrapper.setAttribute("class", "message_wrapper")

    // An file interaction contains buttons at the left of the interaction
    // for the status or accept/refuse
    var left_buttons = document.createElement("div")
    left_buttons.setAttribute("class", "left_buttons")
    message_wrapper.appendChild(left_buttons)
    // Also contains a bold clickable text
    var text_div = document.createElement("div")
    text_div.setAttribute("class", "text")
    message_wrapper.appendChild(text_div)
    return message_wrapper
}

/**
 * Update a call interaction (icon + text)
 * @param message_div the message to update
 * @param message_object new informations
 */
function updateCallInteraction(message_div, message_object) {
    const outgoingCall = "<svg fill=\"#219d55\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5z\"/></svg>"
    const callMissed = "<svg fill=\"#dc2719\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19.59 7L12 14.59 6.41 9H11V7H3v8h2v-4.59l7 7 9-9z\"/></svg>"
    const outgoingMissed = "<svg fill=\"#dc2719\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><defs><path d=\"M24 24H0V0h24v24z\" id=\"a\"/></defs><clipPath id=\"b\"><use overflow=\"visible\" xlink:href=\"#a\"/></clipPath><path clip-path=\"url(#b)\" d=\"M3 8.41l9 9 7-7V15h2V7h-8v2h4.59L12 14.59 4.41 7 3 8.41z\"/></svg>"
    const callReceived = "<svg fill=\"#219d55\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M20 5.41L18.59 4 7 15.59V9H5v10h10v-2H8.41z\"/></svg>"

    const message_text = message_object["text"]
    const message_direction = (message_text.toLowerCase().indexOf("incoming") !== -1) ? "in" : "out"
    const missed = message_text.indexOf("Missed") !== -1

    message_div.querySelector(".text").innerText = message_text.substring(2)

    var left_buttons = message_div.querySelector(".left_buttons")
    left_buttons.innerHTML = ""
    var status_button = document.createElement("div")
    var statusFile = ""
    if (missed)
        statusFile = (message_direction === "in") ? callMissed : outgoingMissed
    else
        statusFile = (message_direction === "in") ? callReceived : outgoingCall
    status_button.innerHTML = statusFile
    status_button.setAttribute("class", "flat-button")
    left_buttons.appendChild(status_button)
}

/**
 * Update a contact interaction (icon + text)
 * @param message_div the message to update
 * @param message_object new informations
 */
function updateContactInteraction(message_div, message_object) {
    const message_text = message_object["text"]

    message_div.querySelector(".text").innerText = message_text

    var left_buttons = message_div.querySelector(".left_buttons")
    left_buttons.innerHTML = ""
    var status_button = document.createElement("div")
    status_button.innerHTML = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\
<path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\"/>\
<path d=\"M0 0h24v24H0z\" fill=\"none\"/></svg>"
    status_button.setAttribute("class", "flat-button")
    left_buttons.appendChild(status_button)
}

/**
 * Remove an interaction from the conversation
 * @param interaction_id
 */
/* exported removeInteraction */
function removeInteraction(interaction_id) {
    const messages = document.getElementById("messages")
    var interaction = document.querySelector(`#message_${interaction_id}`)
    var child = interaction
    var i = 0
    while( (child = child.previousSibling) != null )
        i++
    if (interaction)  interaction.parentNode.removeChild(interaction)
    if (i < messages.children.length) {
        var timestampAfter = messages.children[i].classList.contains("timestamp")
        var timestampBefore = messages.children[i].classList.contains("timestamp")
        if (timestampAfter && timestampBefore) {
            messages.children[i].parentNode.removeChild(messages.children[i])
        }
    }
}

/**
 * Build a message div for passed message object
 * @param message_object to treat
 */
function buildNewMessage(message_object) {
    const message_id = message_object["id"]
    const message_type = message_object["type"]
    const message_text = message_object["text"]
    const message_direction = message_object["direction"]
    const delivery_status = message_object["delivery_status"]
    const message_sender_contact_method = message_object["sender_contact_method"]

    var classes = [
        "message",
        `message_${message_direction}`,
        `message_type_${message_type}`
    ]

    var type = ""
    var message_div = document.createElement("div")
    message_div.setAttribute("id", `message_${message_id}`)
    message_div.setAttribute("class", classes.join(" "))

    // Build message for each types.
    // Add sender images if necessary (like if the interaction doesn't take the whole width)
    const need_sender = (message_type === "data_transfer" || message_type === "text")
    if (need_sender) {
        var message_sender_image = document.createElement("span")
        message_sender_image.setAttribute("class", `sender_image sender_image_${message_sender_contact_method}`)
        message_div.appendChild(message_sender_image)
    }

    // Build main content
    if (message_type === "data_transfer") {
        if (isImage(message_text) && delivery_status === "finished" && displayLinksEnabled) {
            message_div.append(mediaInteraction(message_id, message_text, null, false))
            message_div.querySelector("img").id = message_id
            message_div.querySelector("img").msg_obj = message_object
            /* FIXME in case of error during image load, we should display the standard file
               transfer box. This feature is broken and should be repared. */
            /* message_div.querySelector("img").onerror = function() {
                message_div = .getElementById("message_" + this.id)
                if (message_div.querySelector(".message_wrapper")) {
                    var wrapper = message_div.querySelector(".message_wrapper")
                    wrapper.parentNode.removeChild(wrapper)
                }
                message_div.append(fileInteraction(message_id))
                updateFileInteraction(message_div, this.msg_obj, true)
            } */
        } else {
            message_div.append(fileInteraction(message_id))
        }
    } else if (message_type === "text") {
        // TODO add the possibility to update messages (remove and rebuild)
        const htmlText = getMessageHtml(message_text)
        if (displayLinksEnabled) {
            const parser = new DOMParser()
            const DOMMsg = parser.parseFromString(htmlText, "text/xml")
            const links = DOMMsg.querySelectorAll("a")
            if (DOMMsg.childNodes.length && links.length) {
                var isTextToShow = (DOMMsg.childNodes[0].childNodes.length > 1)
                const ytid = (isVideo(message_text))? youtube_id(message_text) : ""
                if (!isTextToShow && (ytid || isImage(message_text))) {
                    type = "media"
                    message_div.append(mediaInteraction(message_id, message_text, ytid))
                }
            }
        }
        if (type !== "media") {
            type = "text"
            message_div.append(textInteraction(message_id, htmlText))
        }
    } else if (message_type === "call" || message_type === "contact") {
        message_div.append(actionInteraction())
    } else {
        const temp = document.createElement("div")
        temp.innerText = message_type
        message_div.appendChild(temp)
    }

    const menu_element = document.createElement("div")
    menu_element.setAttribute("class", "menu_interaction")
    menu_element.innerHTML = "<label for=\"showmenu\">\
      <svg fill=\"#888888\" height=\"12\" viewBox=\"0 0 24 24\" width=\"12\" xmlns=\"http://www.w3.org/2000/svg\">\
        <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\
        <path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>\
      </svg>\
    </label>\
    <input type=\"checkbox\" id=\"showmenu\" hidden />"
    menu_element.onclick = function() {
        const button = this.querySelector("#showmenu")
        button.checked = !button.checked
    }
    menu_element.onmouseleave = function() {
        const button = this.querySelector("#showmenu")
        button.checked = false
    }
    const dropdown = document.createElement("div")
    const dropdown_classes = [
        "dropdown",
        `dropdown_${message_id}`
    ]
    dropdown.setAttribute("class", dropdown_classes.join(" "))

    const remove = document.createElement("div")
    remove.setAttribute("class", "delete")
    remove.innerHTML = "Delete"
    remove.msg_id = message_id
    remove.onclick = function() {
        window.prompt(`DELETE_INTERACTION:${this.msg_id}`)
    }
    dropdown.appendChild(remove)

    menu_element.appendChild(dropdown)
    if (message_type !== "call") {
        message_div.appendChild(menu_element)
    } else {
        var wrapper = message_div.querySelector(".message_wrapper")
        wrapper.insertBefore(menu_element, wrapper.firstChild)
    }

    return message_div
}

/**
 * Build a timestamp for passed message object
 * @param message_object to treat
 */
function buildNewTimestamp(message_object) {
    const message_type = message_object["type"]
    const message_direction = message_object["direction"]
    const message_timestamp = message_object["timestamp"]

    const formattedTimestamp = getMessageTimestampText(message_timestamp, true)
    const date_elt = document.createElement("div")

    date_elt.innerText = formattedTimestamp
    var typeIsCallOrContact = (message_type === "call" || message_type === "contact")
    var timestamp_div_classes = ["timestamp", typeIsCallOrContact ? "timestamp_action" : `timestamp_${message_direction}`]
    date_elt.setAttribute("class", timestamp_div_classes.join(" "))
    date_elt.setAttribute("message_timestamp", message_timestamp)

    return date_elt
}

/**
 * Add a message to the conversation.
 * @param message_object to treat
 * @param new_message if it's a new message or if we need to update
 * @param insert_after if we want the message at the end or the top of the conversation
 * @param messages_div
 */
function addOrUpdateMessage(message_object, new_message, insert_after = true, messages_div) {
    const message_id = message_object["id"]
    const message_type = message_object["type"]
    const message_direction = message_object["direction"]
    const delivery_status = message_object["delivery_status"]

    var message_div = messages_div.querySelector("#message_" + message_id)
    if (new_message) {
        message_div = buildNewMessage(message_object)

        var date_elt = buildNewTimestamp(message_object)
        // Remove last timestamp if it's the same
        if (messages_div.querySelector(".timestamp"))
            cleanPreviousTimestamps(date_elt, messages_div.children.length, messages_div)

        // Add message and the new timestamp
        if (message_type === "call" || message_type === "contact") {
            message_div.querySelector(".message_wrapper").appendChild(date_elt)
        }

        if (insert_after) {
            messages_div.lastChild.classList.remove("last-message")
            messages_div.appendChild(message_div)
            if (! (message_type === "call" || message_type === "contact")) {
                messages_div.appendChild(date_elt)
            }
            messages_div.lastChild.classList.add("last-message")
        } else {
            if (! (message_type === "call" || message_type === "contact")) {
                messages_div.prepend(date_elt)
            }

            messages_div.prepend(message_div)
        }
    }

    if (isErrorStatus(delivery_status) && message_direction === "out") {
        const dropdown = messages_div.querySelector(`.dropdown_${message_id}`)
        const retry = document.createElement("div")
        retry.innerHTML = "Retry"
        retry.msg_id = message_id
        retry.onclick = function() {
            window.prompt(`RETRY_INTERACTION:${this.msg_id}`)
        }
        dropdown.insertBefore(retry, message_div.querySelector(".delete"))
    }

    // Update informations if needed
    if (message_type === "data_transfer")
        updateFileInteraction(message_div, message_object)
    if (message_type === "text" && message_direction === "out")
    // Modify sent status if necessary
        updateTextInteraction(message_div, delivery_status)
    if (message_type === "call")
        updateCallInteraction(message_div, message_object)
    if (message_type === "contact")
        updateContactInteraction(message_div, message_object)

    // Clean timestamps
    updateTimestamps(messages_div)
}

/**
 * Wrapper for addOrUpdateMessage.
 *
 * Add or update a message and make sure the scrollbar position
 * is refreshed correctly
 *
 * @param message_object message to be added
 */
/* exported addMessage */
function addMessage(message_object)
{
    const messages = document.getElementById("messages")
    if (messages)
        exec_keeping_scroll_position(addOrUpdateMessage, [message_object, true, undefined, messages])
}

/**
 * Update a message that was previously added with addMessage and
 * make sure the scrollbar position is refreshed correctly
 *
 * @param message_object message to be updated
 */
/* exported updateMessage */
function updateMessage(message_object)
{
    const messages = document.getElementById("messages")
    if (messages)
        exec_keeping_scroll_position(addOrUpdateMessage, [message_object, false, undefined, messages])
}

/**
 * Display history in reverse order
 * This function operates on passed root div.
 *
 * @param messages_div root div to modify
 * @param setMessages if true and #messages doesn't exist, #messages is set to the resulting messages div
 */
function printHistoryPart(messages_div, setMessages = false)
{
    isInitialLoading = true

    for (; historyBufferIndex < historyBuffer.length; ++historyBufferIndex) {
        addOrUpdateMessage(historyBuffer[historyBuffer.length - 1 - historyBufferIndex], true, false, messages_div)
    }

    messages_div.lastChild.classList.add("last-message")

    const messages = document.getElementById("messages")
    if (!messages && setMessages) {
        container.prepend(messages_div)
    }

    isInitialLoading = false
}

/**
 * Show the whole history in the chatview.
 * @param messages_array array containing history to be printed
 */
/* exported printHistory */
function printHistory(messages_array)
{
    historyBuffer = messages_array
    historyBufferIndex = 0

    var messages_div = document.createElement("div")
    messages_div.setAttribute("id", "messages")

    printHistoryPart(messages_div, true)
    setTimeout(back_to_bottom, 0)
}

/**
 * Sets the image for a given sender
 * set_sender_image object should contain the following keys:
 * - sender: the name of the sender
 * - sender_image: base64 png encoding of the sender image
 *
 * @param set_sender_image_object sender image object as previously described
 */
/* exported setSenderImage */
function setSenderImage(set_sender_image_object)
{
    var sender_contact_method = set_sender_image_object["sender_contact_method"],
        sender_image = set_sender_image_object["sender_image"],
        sender_image_id = "sender_image_" + sender_contact_method,
        currentSenderImage = document.getElementById(sender_image_id), // Remove the currently set sender image
        style

    if (currentSenderImage) {
        currentSenderImage.parentNode.removeChild(currentSenderImage)
    }

    // Create a new style element
    style = document.createElement("style")

    style.type = "text/css"
    style.id = sender_image_id
    style.innerHTML = "." + sender_image_id + " {content: url(data:image/png;base64," + sender_image + ");height: 35px;width: 35px;}"
    document.head.appendChild(style)
}

/* exported clearSenderImages */
function clearSenderImages()
{
    var styles = document.head.querySelectorAll("style"),
        i = styles.length

    while (i--){
        document.head.removeChild(styles[i])
    }
}

</script>
</html>
