<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dice-Tower</title>
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="/vendor/color-picker.js"></script>
    <style>
        .w3-theme-l6 {
            color: #000 !important;
            background-color: #999999 !important;
            border-radius: 10px;
        }

        .w3-theme-l4 {
            color: #fff !important;
            background-color: #666666 !important;
            border-radius: 10px;
        }

        .w3-theme-l1 {
            color: #fff !important;
            background-color: #333333 !important;
            border-radius: 10px;
        }

        .collapsible {
            background-color: #333333;
            color: black;
            margin-top: 10px;
            padding: 18px;
            width: 100%;
            border: none;
            text-align: left;
            outline: none;
            font-size: 15px;
        }

        .content {
            padding: 0 18px;
            display: none;
            overflow: hidden;
            background-color: #999999;
            color: #000;
            border-radius: 10px;
        }

        button {
            padding: 10px;
            border: #333333 3px solid;
            border-radius: 10px;
            background: #333333;
            color: #fff
        }

        button:hover {
            background: #444444;
        }

        button:active {
            background: #222222;
        }

        input {
            margin: 10px;
        }

        /* The switch - the box around the slider */
        .switch {
            position: relative;
            display: inline-block;
            width: 60px;
            height: 25px;
        }

        /* Hide default HTML checkbox */
        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        /* The slider */
        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            -webkit-transition: .4s;
            transition: .4s;
        }

        .slider:before {
            position: absolute;
            content: "";
            height: 18px;
            width: 26px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            -webkit-transition: .4s;
            transition: .4s;
        }

        input:checked + .slider {
            background-color: #333333;
        }

        input:focus + .slider {
            box-shadow: 0 0 1px #333333;
        }

        input:checked + .slider:before {
            -webkit-transform: translateX(26px);
            -ms-transform: translateX(26px);
            transform: translateX(26px);
        }

        .overlayButton {
            background: transparent;
            border: none;
            width: 5px;
            height: 5px;
            font-size: large;
            color: #000
        }


        .overlayButton:hover {
            background: transparent;
        }

        .tooltip {
            position: fixed;
            border-radius: 0.5rem;
            padding: 15px;
            color: #fff !important;
            background-color: #333333dd !important
        }

        #dice-box {
            position: relative;
            box-sizing: border-box;
            width: 100%;
            height: 100%;
            background: transparent;
            background-size: cover;
        }

        #dice-box canvas {
            width: 100%;
            height: 100%;
            margin: 20px
        }

        .checkbox {
            position: relative;
            padding-left: 100px;
            margin-bottom: 12px;
            margin-left: 10px;
            cursor: pointer;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }

        .checkbox input {
            position: absolute;
            opacity: 0;
            cursor: pointer;
            height: 0;
            width: 0;
        }

        .checkmark {
            margin-left: 75px;
            position: absolute;
            top: 0;
            left: 0;
            height: 15px;
            width: 15px;
            background-color: #eee;
        }

        .checkbox:hover input ~ .checkmark {
            background-color: #ccc;
        }

        /* When the checkbox is checked, add a blue background */
        .checkbox input:checked ~ .checkmark {
            background-color: #333333;
        }

        /* Create the checkmark/indicator (hidden when not checked) */
        .checkmark:after {
            content: "";
            position: absolute;
            display: none;
        }

        /* Show the checkmark when checked */
        .checkbox input:checked ~ .checkmark:after {
            display: block;
        }

        /* Style the checkmark/indicator */
        .checkbox .checkmark:after {
            left: 5px;
            top: 2px;
            width: 5px;
            height: 10px;
            border: solid white;
            border-width: 0 3px 3px 0;
            -webkit-transform: rotate(45deg);
            -ms-transform: rotate(45deg);
            transform: rotate(45deg);
        }

        #snackbar-container {
            visibility: hidden;
            position: fixed;
            width: 100%;
            z-index: 1;
            bottom: 200px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        #snackbar {
            visibility: hidden;
            text-align: center;
            border-radius: 0.5rem;
            padding: 15px;
            color: #fff !important;
            border: #fff 5px solid;
            background-color: #333333dd !important
        }

        #snackbar-container.show {
            visibility: visible;
        }

        #snackbar.show {
            visibility: visible;
            -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
            animation: fadein 0.5s, fadeout 0.5s 2.5s;
        }

    </style>
</head>
<body class="w3-theme-l1">
<div class="w3-container w3-content"
     style="height: 95vh; display: flex; flex-direction: column; justify-content: space-between;  padding: 25px">
    <h1 style="text-align: center">Dice-Tower</h1>
    <div class="w3-panel w3-theme-l4 w3-card w3-display-container"
         style="padding: 25px; text-align: center; margin-bottom: auto;">
        <label for="name" id="nameLabel">Name </label><input type="text" id="name" style="width: 50%; margin-top: 20px"
                                                             required onkeyup="start(event)"/><br/>
        <label for="room" id="roomLabel">Room </label><input type="text" id="room" style="width: 50%" required
                                                             onkeyup="start(event)"/><br/>
        <div>
            <button id="start" onclick="start()" style="align-self: center; margin-top: 20px">Start 🞂</button>
            <label class="checkbox" id="gm-container">Join as GM
                <input type="checkbox" id="gm" style="margin-left: 50px">
                <span class="checkmark"></span>
            </label>
        </div>
    </div>
    <div id="dice-tower" hidden class="w3-panel w3-theme-l4 w3-card w3-display-container"
         style="padding: 25px; margin-bottom: auto">
        <button type="button" class="collapsible" style="color: white; font-weight: bold">Overlay URLs <a>🞃</a></button>

        <div class="content">
            <div id="overlay-urls">
                <div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline;">
                    <label for="overlayId" id="overlayLabel">Dice-Overlay </label>
                    <input type="text" readonly id="overlayId" style="flex-grow: 1" onclick="copyToClipboard(this.id)"/>
                    <button id="overlay-hint-button" popovertarget="overlay-hint" data-trigger="hover"
                            class="overlayButton">🛈
                    </button>
                </div>
            </div>
            <div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline;"
                 hidden id="all-results-urls">
                <label for="resultsId">All-Results-Overlay </label>
                <input type="text" readonly id="resultsId" style="flex-grow: 1" onclick="copyToClipboard(this.id)"/>
                <button popovertarget="all-results-hint" data-trigger="hover" class="overlayButton">🛈</button>
            </div>
            <div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline;">
                <label for="myResultsId">My-Results-Overlay </label>
                <input type="text" readonly id="myResultsId" style="flex-grow: 1" onclick="copyToClipboard(this.id)"/>
                <button popovertarget="my-results-hint" data-trigger="hover" class="overlayButton">🛈</button>
            </div>
        </div>
        <button type="button" class="collapsible" style="color: white; font-weight: bold">Customize Dice <a>🞃</a>
        </button>
        <div class="content">
            <label for="theme">Theme </label>
            <select name="theme" id="theme" style="margin: 25px">
                <option value="default">Default</option>
                <option value="blueGreenMetal">Blue-Green Metal</option>
                <option value="diceOfRolling">Dice of Rolling</option>
                <option value="gemstone">Gemstone</option>
                <option value="gemstoneMarble">Marble Gemstone</option>
                <option value="rock">Rock</option>
                <option value="rust">Rust</option>
                <option value="smooth">Smooth</option>
                <option value="wooden">Wooden</option>
            </select>
            <color-picker id="themeColor"></color-picker>
            <div id="dice-box"></div>

            <button style="margin: 10px" id="preview">Preview 🔎</button>
            <button style="margin: 10px" onclick="saveDice()">Save 💾</button>
            <button popovertarget="save-dice-hint" data-trigger="hover" class="overlayButton">🛈</button>
        </div>
        <div style="display: flex; flex-direction: row; justify-content: space-between; align-items: center; margin: 20px 25px;">
            <label style="font-size: x-large; font-weight: bold;">Roll </label>
            <button style="border: transparent; border-radius: 100%; font-size: x-large; font-weight: bold; height: 50px; width: 50px"
                    onclick="removeDice()">-
            </button>
            <label style="font-size: x-large; font-weight: bold;" id="dice-amount">1</label>
            <button style="border: transparent; border-radius: 100%; font-size: x-large; font-weight: bold; height: 50px; width: 50px"
                    onclick="addDice()">+
            </button>
            <button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d4')">D4</button>
            <button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d6')">D6</button>
            <button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d8')">D8</button>
            <button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d10')">D10</button>
            <button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d12')">D12</button>
            <button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d20')">D20</button>
            <button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d100')">D100</button>
        </div>
        <div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline; margin: 20px 25px;">
            <label for="command">Command </label>
            <input type="text" id="command" style="flex-grow: 1" onkeyup="roll(event)"/>
            <button hidden id="roll" onclick="roll()">Roll 🎲</button>
            <button popovertarget="command-hint" data-trigger="hover" class="overlayButton">🛈</button>
        </div>

        <div style="margin: 20px 25px" id="all-results">
            <label for="resultSwitch">Show all results </label>
            <label class="switch">
                <input type="checkbox" id="resultSwitch">
                <span class="slider"></span>
            </label>
        </div>
    </div>
    <div id="results" hidden class="w3-panel w3-theme-l6 w3-card w3-display-container"
         style="padding: 25px; flex-grow: 1; margin-bottom: auto">
        <iframe id="resultFrame" title="results" style="width: 100%; height: 85%; overflow: hidden; border: 0"
                onload="this.height=this.contentWindow.document.body.scrollHeight;"></iframe>
    </div>

    <div popover id="overlay-hint" class="tooltip">
        <p style="color: red; font-weight: bold">Only the last loaded instance of that overlay rolls the dice!</p>
        <p>Query Params you can Change:</p>
        <ul>
            <li><strong>scale</strong> changes the size of the dice (any value over 1)</li>
            <li><strong>clearAfter</strong> time until dice are cleared (in seconds; remove param or set -1 to keep the
                dice)
            </li>
        </ul>
    </div>
    <div popover id="all-results-hint" class="tooltip">
        <p>Shows all Results in this room</p>
    </div>
    <div popover id="my-results-hint" class="tooltip">
        <p>Shows only my Results in this room</p>
    </div>
    <div popover id="save-dice-hint" class="tooltip">
        This saves your current theme and theme color for current Name
    </div>
    <div popover id="command-hint" class="tooltip">
        Example Commands: "1d6", "2d8 1d100", "1d4 and 1d6", "2d20 & 1d2, "5d6+10"
    </div>

    <div style="margin-top: 20px; flex-grow: 1" id="how-to">
        <div class="w3-panel w3-theme-l4 w3-card w3-display-container" style="padding: 25px; margin-bottom: auto">
            <h2 style="text-align: center">How-To</h2>
            <ul>
                <li>
                    Join a room by entering your character name and the name of the room.<br/>
                    <strong>If you are a GM, make sure to join the room first or let all other players rejoin to get all
                        Overlay-URLs.</strong>
                </li>

                <li>Open your Dice-Overlay either in a new Tab or as a browser source in OBS</li>
                <ul>
                    <li style="color: red; font-weight: bold">Only the last loaded instance of that overlay rolls the
                        dice!
                    </li>
                    <li>You can configure your Overlay with query parameters (more information at the info element next
                        to the link)
                    </li>
                </ul>
                <li>Configure your dice</li>
                <li>Save your dice configuration</li>
                <li>Start rolling</li>
            </ul>
        </div>
    </div>
</div>
<div id="snackbar-container">
    <div id="snackbar">.. they see them rolling</div>
</div>
<script>
    function addDice() {
        let amount = +document.getElementById('dice-amount').innerText
        document.getElementById('dice-amount').innerText = amount + 1
    }

    function removeDice() {
        let amount = +document.getElementById('dice-amount').innerText
        if (amount > 1) {
            document.getElementById('dice-amount').innerText = amount - 1
        }
    }

    function url() {
        return window.location.protocol + '//' + window.location.hostname + (window.location.port?.length > 0 ? ':' + window.location.port : '');
    }

    function start(event) {
        console.log(document.getElementById('gm').checked)

        if ((!event || event.keyCode === 13) && document.getElementById('name').value.length > 0 && document.getElementById('room').value.length > 0) {
            document.getElementById('overlayId').value = url() + '/overlay/' + document.getElementById('room').value + ':' + localStorage.getItem('userId') + '?scale=7&clearAfter=30';
            document.getElementById('resultsId').value = url() + '/overlay/' + document.getElementById('room').value + '/results';
            document.getElementById('myResultsId').value = document.getElementById('resultsId').value + '?name=' + encodeURIComponent(document.getElementById('name').value) + '&user=' + localStorage.getItem('userId');
            document.getElementById('resultFrame').src = document.getElementById('myResultsId').value;
            document.getElementById('roll').hidden = false;
            document.getElementById('start').hidden = true;
            document.getElementById('dice-tower').hidden = false;
            document.getElementById('name').hidden = true;
            document.getElementById('room').hidden = true;
            document.getElementById('gm-container').hidden = true;
            document.getElementById('how-to').hidden = true;
            document.getElementById('results').hidden = false;
            document.getElementById('all-results').hidden = !document.getElementById('gm').checked;
            document.getElementById('all-results-urls').style.display = document.getElementById('gm').checked ? 'fles' : 'none';
            document.getElementById('nameLabel').innerHTML = '<strong style="font-size:x-large;">' + document.getElementById('name').value + '</strong>';
            document.getElementById('roomLabel').innerHTML = '<strong style="font-size:medium;">' + document.getElementById('room').value + '</strong>';
            document.getElementById('overlayLabel').innerHTML = 'Dice-Overlay for <strong>' + document.getElementById('name').value + '</strong>';
            document.title = document.getElementById('name').value + ' - Dice-Tower';

            if (localStorage.getItem(document.getElementById('name').value + "-theme")) {
                document.getElementById('theme').value = localStorage.getItem(document.getElementById('name').value + "-theme")
            }
            if (localStorage.getItem(document.getElementById('name').value + "-themeColor")) {
                document.getElementById('themeColor').setColor(localStorage.getItem(document.getElementById('name').value + "-themeColor"));
            }
            let httpRequest = new XMLHttpRequest();
            httpRequest.open('POST', url() + '/dice/' + document.getElementById('room').value + '/register')
            httpRequest.setRequestHeader('Content-Type', 'application/json')
            httpRequest.send(JSON.stringify({
                name: document.getElementById('name').value,
                overlay: document.getElementById('overlayId').value,
                id: document.getElementById('room').value + ':' + localStorage.getItem('userId')
            }))
            if (document.getElementById('gm').checked) {
                document.getElementById('resultSwitch').checked = true;
                document.getElementById('resultFrame').src = document.getElementById('resultsId').value;
                const evtSource = new EventSource(url() + '/dice/' + document.getElementById('room').value + '/users');
                evtSource.addEventListener('message', function (event) {
                    let data = JSON.parse(event.data);
                    if (data.id !== document.getElementById('room').value + ':' + localStorage.getItem('userId')) {
                        let overlays = document.getElementById('overlay-urls');
                        let newOverlay = document.getElementById(data.id) ?? document.createElement('div');
                        newOverlay.replaceChildren(...[]);
                        newOverlay.id = data.id;
                        newOverlay.style.display = "flex";
                        newOverlay.style.flexDirection = "row";
                        newOverlay.style.justifyContent = "space-between";
                        newOverlay.style.alignItems = "baseline";
                        let newLabel = document.createElement('label');
                        newLabel.for = data.id + 'url';
                        newLabel.innerHTML = "Dice-Overlay for <strong>" + data.name + "</strong>";
                        let newInput = document.createElement('input');
                        newInput.type = "text";
                        newInput.readOnly = true;
                        newInput.id = data.id + 'url';
                        newInput.style.flexGrow = '1';
                        newInput.value = data.overlay;
                        newInput.onclick = () => copyToClipboard(newInput.id)
                        let hint = document.getElementById('overlay-hint-button').cloneNode(true);
                        newOverlay.appendChild(newLabel);
                        newOverlay.appendChild(newInput);
                        newOverlay.appendChild(hint);
                        overlays.appendChild(newOverlay);
                    }
                    showPopover();
                });
            }
        }
    }

    function rollEasy(dice) {
        document.getElementById('command').value = document.getElementById('dice-amount').innerText + dice;
        roll();
    }

    function roll(event) {
        if ((!event || event.keyCode === 13) && document.getElementById('command').value?.length > 0) {
            let httpRequest = new XMLHttpRequest();
            httpRequest.open('POST', url() + '/dice/' + document.getElementById('room').value + ':' + localStorage.getItem(`userId`))
            httpRequest.setRequestHeader('Content-Type', 'application/json')
            httpRequest.send(JSON.stringify({
                name: document.getElementById('name').value,
                command: document.getElementById('command').value,
                themeColor: document.getElementById('themeColor').value,
                theme: document.getElementById('theme').value
            }))
        }
    }

    function saveDice() {
        localStorage.setItem(document.getElementById('name').value + "-theme", document.getElementById('theme').value)
        localStorage.setItem(document.getElementById('name').value + "-themeColor", document.getElementById('themeColor').value)
    }

    let coll = document.getElementsByClassName("collapsible");

    for (let i = 0; i < coll.length; i++) {
        coll[i].addEventListener("click", function () {
            const content = this.nextElementSibling;
            if (content.style.display === "block") {
                content.style.display = "none";
                this.children[0].innerHTML = "🞃"
            } else {
                content.style.display = "block";
                this.children[0].innerHTML = "🞁"
            }
        });
    }

    function showPopover() {
        const popover = document.querySelectorAll("[popovertarget][data-trigger='hover']");

        popover.forEach((e) => {
            const target = document.querySelector("#" + e.getAttribute("popovertarget"));
            e.addEventListener("mouseover", () => {
                target.showPopover();
            });

            e.addEventListener("mouseout", () => {
                target.hidePopover();
            });
        });
    }

    showPopover();

    document.getElementById('resultSwitch').addEventListener('change', function () {
        if (!this.checked) {
            document.getElementById('resultFrame').src = document.getElementById('myResultsId').value;
        } else {
            document.getElementById('resultFrame').src = document.getElementById('resultsId').value;
        }
    })

    document.addEventListener("DOMContentLoaded", async () => {
        if (!localStorage.getItem("userId")) {
            localStorage.setItem("userId", self.crypto.randomUUID());
        }
    })

    function copyToClipboard(id) {
        let copyText = document.getElementById(id);
        copyText.select();
        copyText.setSelectionRange(0, 99999);
        navigator.clipboard.writeText(copyText.value);
        showSnackbar("Link copied to clipboard: <br/>" + copyText.value);
    }

    function showSnackbar(message) {
        let snackbar = document.getElementById("snackbar");
        let snackbarContainer = document.getElementById("snackbar-container");
        snackbar.innerHTML = message;
        snackbar.className = "show";
        snackbarContainer.className = "show";
        setTimeout(function () {
            snackbar.className = snackbar.className.replace("show", "");
            snackbarContainer.className = snackbarContainer.className.replace("show", "");
        }, 5000);
    }
</script>
<script type="module">
    import DiceBox from "/vendor/dice-box/dice-box.es.js";

    document.addEventListener("DOMContentLoaded", async () => {
        document.getElementById('preview').onclick = async () => {
            document.getElementById('dice-box').replaceChildren(...[])
            const diceBox = new DiceBox("#dice-box", {
                assetPath: "/vendor/assets/",
                theme: document.getElementById('theme').value,
                themeColor: document.getElementById('themeColor').value,
                scale: 14
            });
            await diceBox.init()
            diceBox.roll(['1d2', '1d4', '1d6', '1d8', '1d10', '1d12', '1d20', '1d100']);
        }
    })

</script>
</body>
<footer class="w3-theme-l1 w3-center w3-padding-16">
    <a href="https://git.arindy.de/arindy/dice-tower" target="_blank" class="w3-hover-text-black">Dice-Tower on my
        GitTea</a>
</footer>
</html>
