{% extends "console-base.html" %}
{% load i18n %}
{% load static %}

{% block head %}
<!--
    noVNC example: lightweight example using minimal UI and features
    This is a self-contained file which doesn't import WebUtil or external CSS.
    Copyright (C) 2019 The noVNC Authors
    noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
    This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
    Connect parameters are provided in query string:
        http://example.com/?host=HOST&port=PORT&scale=true
-->
<title>WebVirtCloud - noVNC - Lite</title>

<meta charset="utf-8">

<!-- Always force latest IE rendering engine (even in intranet) &
                Chrome Frame. Remove this if you use the .htaccess -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<!-- Stylesheets -->
<link rel="stylesheet" href='{% static "js/novnc/app/styles/lite.css" %}'>

<!-- Promise polyfill for IE11 -->
<script src="{% static 'js/novnc/vendor/promise.js' %}"></script>

<!-- ES2015/ES6 modules polyfill -->
<script nomodule
    src="{% static 'js/novnc/vendor/browser-es-module-loader/dist/browser-es-module-loader.js' %}"></script>

<!-- actual script modules -->
<script type="module" crossorigin="anonymous">
    // RFB holds the API to connect and communicate with a VNC server
    import RFB from '{% static "js/novnc/core/rfb.js" %}';

    let rfb;
    let desktopName;

    // When this function is called we have
    // successfully connected to a server
    function connectedToServer(e) {
        status("Connected to " + desktopName);
    }

    // This function is called when we are disconnected
    function disconnectedFromServer(e) {
        if (e.detail.clean) {
            status("Disconnected");
        } else {
            status("Something went wrong, connection is closed");
        }
    }

    // When this function is called, the server requires
    // credentials to authenticate
    function credentialsAreRequired(e) {
        const password = prompt("Password Required:");
        rfb.sendCredentials({ password: password });
    }

    // When this function is called we have received
    // a desktop name from the server
    function updateDesktopName(e) {
        desktopName = e.detail.name;
    }

    // Since most operating systems will catch Ctrl+Alt+Del
    // before they get a chance to be intercepted by the browser,
    // we provide a way to emulate this key sequence.
    function sendCtrlAltDel() {
        rfb.sendCtrlAltDel();
        return false;
    }

    function fullscreen() {
        if (document.fullscreenElement || // alternative standard method
            document.mozFullScreenElement || // currently working methods
            document.webkitFullscreenElement ||
            document.msFullscreenElement) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        } else {
            if (document.documentElement.requestFullscreen) {
                document.documentElement.requestFullscreen();
            } else if (document.documentElement.mozRequestFullScreen) {
                document.documentElement.mozRequestFullScreen();
            } else if (document.documentElement.webkitRequestFullscreen) {
                document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
            } else if (document.body.msRequestFullscreen) {
                document.body.msRequestFullscreen();
            }
        }
        return false;
    }
    function sendCtrlAltFN(f) {
        rfb.sendCtrlAltFN(f);
        return false;
    }
    function machineShutdown() {
        rfb.machineShutdown();
        return false;
    }
    function machineReboot() {
        rfb.machineReboot();
        return false;
    }
    function machineReset() {
        rfb.machineReset();
        return false;
    }

    // Show a status text in the top bar
    function status(text) {
        document.getElementById('noVNC_status').textContent = text;
    }

    // This function extracts the value of one variable from the
    // query string. If the variable isn't defined in the URL
    // it returns the default value instead.
    function readQueryVariable(name, defaultValue) {
        // A URL with a query parameter can look like this:
        // https://www.example.com?myqueryparam=myvalue
        //
        // Note that we use location.href instead of location.search
        // because Firefox < 53 has a bug w.r.t location.search
        const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
            match = document.location.href.match(re);

        if (match) {
            // We have to decode the URL since want the cleartext value
            return decodeURIComponent(match[1]);
        }

        return defaultValue;
    }

    document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
    document.getElementById('machineShutdownButton').onclick = machineShutdown;
    document.getElementById('machineRebootButton').onclick = machineReboot;
    document.getElementById('machineResetButton').onclick = machineReset;
    document.getElementById('fullscreen_button').onclick = fullscreen;

    document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
    document.getElementById('ctrlaltf1').addEventListener('click', function () { sendCtrlAltFN(0); });
    document.getElementById('ctrlaltf2').addEventListener('click', function () { sendCtrlAltFN(1); });
    document.getElementById('ctrlaltf3').addEventListener('click', function () { sendCtrlAltFN(2); });
    document.getElementById('ctrlaltf4').addEventListener('click', function () { sendCtrlAltFN(3); });
    document.getElementById('ctrlaltf5').addEventListener('click', function () { sendCtrlAltFN(4); });
    document.getElementById('ctrlaltf6').addEventListener('click', function () { sendCtrlAltFN(5); });
    document.getElementById('ctrlaltf7').addEventListener('click', function () { sendCtrlAltFN(6); });
    document.getElementById('ctrlaltf8').addEventListener('click', function () { sendCtrlAltFN(7); });
    document.getElementById('ctrlaltf9').addEventListener('click', function () { sendCtrlAltFN(8); });
    document.getElementById('ctrlaltf10').addEventListener('click', function () { sendCtrlAltFN(9); });
    document.getElementById('ctrlaltf11').addEventListener('click', function () { sendCtrlAltFN(10); });
    document.getElementById('ctrlaltf12').addEventListener('click', function () { sendCtrlAltFN(11); });

    // Read parameters specified in the URL query string
    // By default, use the host and port of server that served this file
    const host = readQueryVariable('host', '{{ ws_host }}');
    let port = readQueryVariable('port', '{{ ws_port }}');

    {% if perms.instances.passwordless_console %}
        const password = '{{ console_passwd }}';
    {% else %}
        const password = readQueryVariable('password');
    {% endif %}

    //const path = readQueryVariable('path', 'websockify');
    const path = readQueryVariable('path', '{{ ws_path }}');

    // | | |         | | |
    // | | | Connect | | |
    // v v v         v v v

    status("Connecting");

    // Build the websocket URL used to connect
    let url;
    if (window.location.protocol === "https:") {
        url = 'wss';
    } else {
        url = 'ws';
    }
    url += '://' + host;
    if (port) {
        url += ':' + port;
    }
    url += '/' + path;

    // Creating a new RFB object will start a new connection
    rfb = new RFB(document.getElementById('noVNC_container'), url,
        { credentials: { password: password } });

    // Add listeners to important events from the RFB module
    rfb.addEventListener("connect", connectedToServer);
    rfb.addEventListener("disconnect", disconnectedFromServer);
    rfb.addEventListener("credentialsrequired", credentialsAreRequired);
    rfb.addEventListener("desktopname", updateDesktopName);

    // Set parameters that can be changed on an active connection
    rfb.scaleViewport = {{ scale }};
    rfb.viewOnly = {{ view_only }};
    rfb.resizeSession = {{ resize_session }};
    rfb.clipViewport = {{ clip_viewport }};

</script>
{% endblock %}

{% block content %}
<div id="noVNC_status_bar">
    <div id="noVNC_left_dummy_elem"></div>
    <div id="noVNC_status">{% trans 'Loading' %}</div>
    <div id="noVNC_buttons">
        <input type="button" value="Send CtrlAltDel" id="sendCtrlAltDelButton" class="noVNC_shown">
        <span id="noVNC_power_buttons" class="noVNC_hidden">
            <input type="button" value="Shutdown" id="machineShutdownButton">
            <input type="button" value="Reboot" id="machineRebootButton">
            <input type="button" value="Reset" id="machineResetButton">
        </span>
    </div>
</div>
<div id="noVNC_container">
    <!-- This is where the remote screen will appear -->
</div>
{% endblock %}