<!DOCTYPE html>
<html lang="en">
<head>
    <title>WLED frame rate test tool</title>
    <style>
        body {
            background-color: #222;
            color: #fff;
            font-family: Helvetica, Verdana, sans-serif;
        }
        input {
            background-color: #333;
            color: #fff;
        }
        #ip {
            width: 100px;
        }
        #secs {
            width: 36px;
        }
        #csva {
            position: absolute;
            top: -100px; /*gtfo*/
        }
        button {
            background-color: #333;
            color: #fff;
        }
        table, th, td {
            border: 1px solid #aaa;
            border-collapse: collapse;
            text-align: center;
        }
        .red {
            color: #d20;
        }
    </style>
    <script>
        var gotfx = false, running = false;
        var pos = 0, prev = 0, min = 999, max = 0, fpslist = [], names = [], names_checked = [];
        var to;
        function S() {
            document.getElementById('ip').value = localStorage.getItem('locIpFps');
            if (document.getElementById('ip').value) req(false);
        }
        function loadC() {
            hide(false);
            var list = localStorage.getItem('fpsFxSelection');
            if (!list) return;
            list = JSON.parse(list);
            var chks = document.querySelectorAll('.fxcheck');
            for (let i = 0; i < chks.length; i++) {
               if (i < list.length) chks[i].checked = list[i];
            }
        }
        function saveC() {
            var list = [];
            var chks = document.querySelectorAll('.fxcheck');
            for (let i = 0; i < chks.length; i++) {
                list.push(chks[i].checked);
            }
            localStorage.setItem('fpsFxSelection', JSON.stringify(list));
        }
        function setC(c) {
            hide(false);
            var chks = document.querySelectorAll('.fxcheck');
            for (let i = 0; i < chks.length; i++) {
                chks[i].checked = (c == 255);
            }
            if (c == 1 && chks.length > 100) {
                chks[1].checked = true;  //Blink
                chks[15].checked = true; //Running
                chks[16].checked = true; //Saw
                chks[37].checked = true; //Running 2
                chks[44].checked = true; //Tetrix
                chks[63].checked = true; //Pride 2015
                chks[74].checked = true; //Colortwinkles
                chks[101].checked = true;//Pacifica
            }
        }
        function hide(h) {
            var trs = document.querySelectorAll('.trs');
            var chks = document.querySelectorAll('.fxcheck');
            for (let i = 0; i < trs.length; i++) {
                trs[i].style.display = (h && !chks[i].checked) ? "none":"table-row";
            }
        }
        function run(init) {
            if (init) {
                running = !running;
                document.getElementById('runbtn').innerText = running ? 'Stop':'Run';
                if (running) {pos = 0; prev = -1; min = 999; max = 0; fpslist = []; names_checked = []; hide(true);}
                clearTimeout(to);
                if (!running) {req({seg:{fx:0},v:true,stop:true}); return;}
            }
            if (!gotfx) {req(false); return;}
            var chks = document.querySelectorAll('.fxcheck');
            var fpsb = document.querySelectorAll('.fps');
            if (prev >= 0) {pos++};
            if (pos >= chks.length) {run(true); return;} //end
            while (!chks[pos].checked) {
                fpsb[pos].innerText = "-";
                pos++;
                if (pos >= chks.length) {run(true); return;} //end
            }
            names_checked.push(names[pos]);
            var extra = {};
            try {
                extra = JSON.parse(document.getElementById('ej').value);
            } catch (e) {

            }
            var cmd = {seg:{fx:pos},v:true};
            Object.assign(cmd, extra);
            req(cmd);
        }
        function req(command) {
            var ip = document.getElementById('ip').value;
            if (!ip) {alert("Please enter WLED IP"); return;}
            if (ip != localStorage.getItem('locIpFps')) localStorage.setItem('locIpFps', document.getElementById('ip').value);
            var url = command ? `http://${ip}/json/si` : `http://${ip}/json/effects`;
            var type = command ? 'post':'get';
            var req = undefined;
            if (command)
            {
                req = JSON.stringify(command);
            }
            fetch
            (url, {
                method: type,
                headers: {
                    "Content-type": "application/json; charset=UTF-8"
                },
                body: req
            })
            .then(res => {
                if (!res.ok) {
                    alert('Data malfunction');
                }
                return res.json();
            })
            .then(json => {
                if (!json) {
                    alert('Empty response'); return;
                }
                if (!command) {
                    names = json;
                    var tblc = '';
                    for (let i = 0; i < json.length; i++) {
		                tblc += `<tr class="trs"><td><input type="checkbox" class="fxcheck" /></td><td>${i}</td><td>${json[i]}</td><td class="fps"></td></tr>`
	                }
                    var tbl = `<table>
                        <tr>
                            <th>Test?</th><th>ID</th><th>Effect Name</th><th>FPS</th>
                        </tr>
                        ${tblc}
                    </table>`;
                    document.getElementById('tablecon').innerHTML = tbl;
                    setC(1);
                    loadC();
                    gotfx = true;
                    document.getElementById('runbtn').innerText = "Run";
                } else {
                    if (!json.info) return;
                    document.getElementById('leds').innerText = json.info.leds.count;
                    document.getElementById('seg').innerText = json.state.seg[0].len;
                    document.getElementById('bri').innerText = json.state.bri;
                    if (prev >= 0) {
                        var lastfps = parseInt(json.info.leds.fps); //previous FX
                        if (lastfps < min) min = lastfps;
                        if (lastfps > max) max = lastfps;
                        fpslist.push(lastfps);
                        var sum = 0;
                        for (let i = 0; i < fpslist.length; i++) {
                            sum += fpslist[i];
                        }
                        sum /= fpslist.length;
                        document.getElementById('fps_min').innerText = min;
                        document.getElementById('fps_max').innerText = max;
                        document.getElementById('fps_avg').innerText = Math.round(sum*10)/10;
                        var fpsb = document.querySelectorAll('.fps');
                        fpsb[prev].innerHTML = lastfps;
                    }
                    prev = pos;
                    var delay = parseInt(document.getElementById('secs').value)*1000;
                    delay = Math.min(Math.max(delay, 2000), 15000)
                    if (!command.stop) to = setTimeout(run,delay);
                }
            })
            .catch(function (error) {
		        alert('Comms malfunction');
		        console.log(error);
	        });
        }
        function csv(n) {
            var txt = "";
            for (let i = 0; i < fpslist.length; i++) {
                if (!n) txt += names_checked[i] + ',';
                txt += fpslist[i]; txt += "\n";
            }
            document.getElementById('csva').value = txt;
            var copyText = document.getElementById('csva');

            copyText.select();
            copyText.setSelectionRange(0, 999999);
            document.execCommand("copy");
        }
    </script>
</head>
<body onload="S()">
    <h2>Starship monitoring dashboard</h2>
    (or rather just a WLED frame rate tester lol)<br><br>
    IP: <input id="ip" /><br>
    Time per effect: <input type=number id=secs value=5 max=15 min=2 />s<br>
    Effects to test:
    <button type="button" onclick="setC(255)">All</button>
    <button type="button" onclick="setC(1)">Selection 1</button>
    <button type="button" onclick="setC(0)">None</button>
    <button type="button" onclick="loadC()">Get LS</button>
    <button type="button" class="red" onclick="saveC()">Save to LS</button><br>
    Extra JSON: <input id="ej" /><br>

    <button type="button" onclick="run(true)" id="runbtn">Fetch FX list</button><br>
    LEDs: <span id="leds">-</span>, Seg: <span id="seg">-</span>, Bri: <span id="bri">-</span><br>
    FPS min: <span id="fps_min">-</span>, max: <span id="fps_max">-</span>, avg: <span id="fps_avg">-</span><br><br>
    <div id="tablecon">
    </div><br>
    <button type="button" onclick="csv(false)">Copy csv to clipboard</button>
    <button type="button" onclick="csv(true)">Copy csv (FPS only)</button>
    <textarea id=csva></textarea>
</body>
</html>