<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">
      <div id="messages"></div>
      <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 messages          = document.getElementById("messages")
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

/**
 * 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) {
    var atEnd = messages.scrollTop >= messages.scrollHeight - messages.clientHeight - scrollDetectionThresh
    func(...args)
    if (atEnd) {
        messages.scrollTop = messages.scrollHeight
    }
}

/**
 * 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 in the navbar. 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() {
    updateTimestamps()
}

setInterval(updateView, 60000)

window.onresize = function() {
    updateTimestamps()
}

/* 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 #sendMessage #message value
 */
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()
{
    messages.innerHTML = ""
}

/**
 * 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
 */
function cleanPreviousTimestamps (baseNode, endIndex) {
    // Remove previous elements with the same formatted timestamp
    exec_keeping_scroll_position(function() {
        for (var c = endIndex - 1 ; c >= 0 ; --c) {
            const child = messages.children[c]
            if (child.className.indexOf("timestamp") !== -1) {
                if (child.className === baseNode.className &&
            child.innerHTML === baseNode.innerHTML) {
                    messages.removeChild(child)
                } else {
                    break // A different timestamp is met, we can stop here.
                }
            }
        }
    }, [])
}

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

                    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)
                }
            }
        }
    }, [])
}

/**
 * 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) {
    exec_keeping_scroll_position(function() {
        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
}

/**
 * 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
        exec_keeping_scroll_position(function() {
            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")
    var informations_txt = getMessageTimestampText(message_object["timestamp"], true)
    if (message_object["totalSize"] && message_object["progress"]) {
        if (message_delivery_status === "finished") {
            informations_txt += " - " + humanFileSize(message_object["totalSize"])
        } else {
            informations_txt += " - " + humanFileSize(message_object["progress"])
                         + " / " + humanFileSize(message_object["totalSize"])
        }
    }
    informations_txt += " - " + message_delivery_status
    informations_div.innerText = informations_txt

    // 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()
    message_div.querySelector(".filename").innerText = message_text.split("/").pop()
    updateProgressBar(message_div.querySelector(".message_progress_bar"), message_object)
    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))
}

/**
 * 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'")
    if (ytid) {
        imageElt.src = `http://img.youtube.com/vi/${ytid}/0.jpg`
    } else {
        imageElt.src = link
    }
    linkElt.appendChild(imageElt)
    if (ytid) {
        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)
        media_wrapper.appendChild(containerElt)
    } 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
 * @TODO retry button
 */
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.appendChild(sending)
        }
        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.appendChild(failure_div)
        }
        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)
}

/**
 * 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
 */
function addOrUpdateMessage(message_object, new_message, insert_after = true) {
    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 message_timestamp = message_object["timestamp"]
    const delivery_status = message_object["delivery_status"]
    const message_sender_contact_method = message_object["sender_contact_method"]

    var message_div = document.getElementById("message_" + message_id)
    var type = ""
    if (new_message) {
    // Build new message
        var classes = [
            "message",
            `message_${message_direction}`,
            `message_type_${message_type}`
        ]

        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
                message_div.querySelector("img").onerror = function() {
                    message_div = document.getElementById("#message_" + this.id)
                    /* FIXME in many cases, message_div is null here and this code doesn't do anything */
                    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)
        }

        // Get timestamp to add
        const formattedTimestamp = getMessageTimestampText(message_timestamp, true)
        // Create the timestamp object
        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)

        // Remove last timestamp if it's the same
        if (messages.getElementsByClassName(".timestamp"))
            cleanPreviousTimestamps(date_elt, messages.children.length)

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

    // 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()
}

/**
 * Wrapper for addOrUpdateMessage.
 *
 * This function adds or updates a message and makes sure the scrollbar position
 * is refreshed correctly.
 *
 * @param message_object message to be added
 */
/* exported addMessage */
function addMessage(message_object)
{
    exec_keeping_scroll_position(addOrUpdateMessage, [message_object, true])
}

/**
 * Update a message that was previously added with addMessage
 * @param message_object message to be updated
 */
/* exported updateMessage */
function updateMessage(message_object)
{
    exec_keeping_scroll_position(addOrUpdateMessage, [message_object, false])
}

/**
 * This function displays the history in reverse order and makes sure the
 * scrollbar position is refreshed correctly.
 */
function printHistoryPart()
{
    if(historyBuffer.length == 0 || historyBufferIndex === historyBuffer.length) {
        // nothing to print
        return
    }

    exec_keeping_scroll_position(function() {
        // Show 10 messages
        for (var i = 0; i < 10; ++i) {
            addOrUpdateMessage(historyBuffer[historyBuffer.length - 1 - historyBufferIndex], true, false)
            historyBufferIndex ++

            if (historyBufferIndex === historyBuffer.length)
                break
        }
    }, [])

    // Make a short pause to minimize ressources consumption
    // show quickly the first hundred messages
    if (historyBufferIndex !== historyBuffer.length)
        setTimeout(printHistoryPart, (historyBufferIndex > 100) ? 100 : 1)
}

/**
 * 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
    setTimeout(printHistoryPart, 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>
