// ==UserScript==
// @name         noVNC Paste for Proxmox
// @namespace    http://tampermonkey.net/
// @version      0.2a
// @description  Pastes text into a noVNC window (for use with Proxmox specifically)
// @author       Chester Enright
// @match        https://*
// @include      /^.*novnc.*/
// @require http://code.jquery.com/jquery-3.3.1.min.js
// @grant        none
// ==/UserScript==
const delay = 1
;
(function () {
    'use strict';

    let capsLockOn = false;
    const KEY_DELAY = 50;
    const SHIFT_NEEDED = /[A-Z!@#$%^&*()_+{}:"<>?~|]/;

    function simulateKeyEvent(el, eventType, key, options = {}) {
        const evt = new KeyboardEvent(eventType, { key, ...options });
        el.dispatchEvent(evt);
    }

    window.sendString = function(text) {
        const el = document.getElementById("novnc-canvas");
        if (!el) {
            console.error("Canvas element not found");
            return;
        }

        text.split('').forEach((char, index) => {
            setTimeout(() => {
                if (char === '\n') {
                    // Simulate "Enter" key press for line breaks
                    simulateKeyEvent(el, "keydown", "Enter");
                    simulateKeyEvent(el, "keyup", "Enter");
                } else {
                    const needsShift = SHIFT_NEEDED.test(char);
                    const isUpperCase = char >= 'A' && char <= 'Z';

                    if (needsShift) {
                        simulateKeyEvent(el, "keydown", "Shift", { keyCode: 16 });
                    }

                    if (isUpperCase && capsLockOn) {
                        simulateKeyEvent(el, "keydown", char.toLowerCase());
                        simulateKeyEvent(el, "keyup", char.toLowerCase());
                    } else {
                        simulateKeyEvent(el, "keydown", char);
                        simulateKeyEvent(el, "keyup", char);
                    }

                    if (needsShift) {
                        simulateKeyEvent(el, "keyup", "Shift", { keyCode: 16 });
                    }

                    if (char === "CapsLock") {
                        capsLockOn = !capsLockOn;
                        console.log("Caps Lock state changed:", capsLockOn);
                    }
                }
            }, index * KEY_DELAY);
        });
    };

    function waitForCanvas() {
        return new Promise((resolve) => {
            const checkCanvas = () => {
                const canvas = $("canvas");
                if (canvas.length > 0) {
                    canvas.attr("id", "novnc-canvas");
                    resolve(canvas);
                } else {
                    setTimeout(checkCanvas, 500);
                }
            };
            checkCanvas();
        });
    }

    async function setupNoVNCPaste() {
        try {
            console.log("Starting up noVNC Copy/Paste (for Proxmox) - Improved Version with Line Breaks");

            const canvas = await waitForCanvas();

            canvas.on("mousedown", (e) => {
                if (e.button == 2) { // Right Click
                    navigator.clipboard.readText()
                        .then(text => {
                            window.sendString(text);
                        })
                        .catch(err => {
                            console.error("Failed to read clipboard:", err);
                        });
                }
            });

            console.log("noVNC Copy/Paste setup completed");
        } catch (error) {
            console.error("Error setting up noVNC Copy/Paste:", error);
        }
    }

    $(document).ready(setupNoVNCPaste);
})();