// ==UserScript==
// @name         Geocaching: Show UserSuppliedContent
// @namespace    http://tampermonkey.net/
// @version      3.4
// @description  Shows UserSuppliedContent
// @copyright    2026
// @author       OUT14ND3R
// @match        https://www.geocaching.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    var popup = null;
    var mode = "source"; // ⭐ DEFAULT = RAW MODE
    var combinedHTML = null;

    function escapeHTML(str) {
        return str.replace(/[&<>"']/g, function (m) {
            return {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#39;'
            }[m];
        });
    }

    function waitForUSC(callback) {
        var observer = new MutationObserver(function () {
            var blocks = document.querySelectorAll("div.UserSuppliedContent");
            if (blocks.length > 0) {
                observer.disconnect();
                callback(blocks);
            }
        });

        observer.observe(document.body, { childList: true, subtree: true });

        var existing = document.querySelectorAll("div.UserSuppliedContent");
        if (existing.length > 0) {
            observer.disconnect();
            callback(existing);
        }
    }

    // ⭐⭐⭐ RAW HIGHLIGHTING ENGINE ⭐⭐⭐
    function highlightRaw(html) {
        var raw = escapeHTML(html);

        // Highlight alt="..."
        raw = raw.replace(/(alt=&quot;[^&]*&quot;)/g,
            '<span style="color:red; font-weight:bold">$1</span>');

        // Highlight title="..."
        raw = raw.replace(/(title=&quot;[^&]*&quot;)/g,
            '<span style="color:red; font-weight:bold">$1</span>');

        // Highlight src="..." in BLUE
        raw = raw.replace(/(src=&quot;[^&]*&quot;)/g,
            '<span style="color:blue; font-weight:bold">$1</span>');

        // Highlight HTML comments <!-- ... --> in GREEN
        raw = raw.replace(/(&lt;!--[\s\S]*?--&gt;)/g,
            '<span style="color:green; font-weight:bold">$1</span>');

        // Highlight class="txt_hidden" in PURPLE
        raw = raw.replace(/(class=&quot;txt_hidden&quot;)/g,
            '<span style="color:purple; font-weight:bold">$1</span>');

        // Highlight style="color:#ffffff;" in PURPLE
        raw = raw.replace(/(style=&quot;color:#ffffff;?&quot;)/gi,
            '<span style="color:purple; font-weight:bold">$1</span>');

        // Highlight style="color: white;" in PURPLE
        raw = raw.replace(/(style=&quot;color:\s*white;?&quot;)/gi,
            '<span style="color:purple; font-weight:bold">$1</span>');

        // ⭐ Highlight href="..." in LIGHT BLUE
        raw = raw.replace(/(href=&quot;[^&]*&quot;)/gi,
            '<span style="color:#00aaff; font-weight:bold">$1</span>');

        // ⭐⭐⭐ MAKE href CLICKABLE ⭐⭐⭐
        raw = raw.replace(
            /href=&quot;([^&]*)&quot;/gi,
            function (match, url) {
                return 'href=&quot;<a href="' + url +
                    '" target="_blank" style="color:#00aaff; font-weight:bold; text-decoration:underline">' +
                    url +
                    '</a>&quot;';
            }
        );

        // ⭐⭐⭐ MAKE src CLICKABLE ⭐⭐⭐
        raw = raw.replace(
            /src=&quot;([^&]*)&quot;/gi,
            function (match, url) {
                return 'src=&quot;<a href="' + url +
                    '" target="_blank" style="color:blue; font-weight:bold; text-decoration:underline">' +
                    url +
                    '</a>&quot;';
            }
        );

        return raw;
    }

    function createPopup() {
        if (popup) return popup;

        popup = document.createElement('div');
        popup.id = "usc_popup";
        popup.style.position = "fixed";
        popup.style.top = "120px";
        popup.style.right = "20px";
        popup.style.width = "520px";
        popup.style.height = "420px";
        popup.style.zIndex = "999999999";
        popup.style.background = "white";
        popup.style.border = "3px solid #333";
        popup.style.borderRadius = "6px";
        popup.style.boxShadow = "0 0 12px rgba(0,0,0,0.6)";
        popup.style.padding = "10px";
        popup.style.overflow = "auto";
        popup.style.display = "none";
        popup.style.setProperty("resize", "both", "important");
        popup.style.minWidth = "260px";
        popup.style.minHeight = "160px";

        var header = document.createElement('div');
        header.style.display = "flex";
        header.style.justifyContent = "space-between";
        header.style.alignItems = "center";
        header.style.marginBottom = "8px";

        var title = document.createElement('span');
        title.textContent = "UserSuppliedContent";

        var toggleBtn = document.createElement('input');
        toggleBtn.type = "submit";
        toggleBtn.value = "Show Rendered";
        toggleBtn.style.marginRight = "10px";
        toggleBtn.style.color = "blue";
        toggleBtn.setAttribute("onclick", "return false;");

        var content = document.createElement('div');
        content.id = "usc_content";

        // ⭐ DEFAULT RAW VIEW
        var raw = highlightRaw(combinedHTML);
        content.innerHTML =
            "<pre style='white-space: pre-wrap; word-break: break-word; font-family: monospace; font-size: 13px;'>" +
            raw +
            "</pre>";

        toggleBtn.addEventListener("click", function () {
            if (mode === "source") {
                content.innerHTML = combinedHTML;
                toggleBtn.value = "Show Raw Source";
                mode = "rendered";
            } else {
                var raw2 = highlightRaw(combinedHTML);
                content.innerHTML =
                    "<pre style='white-space: pre-wrap; word-break: break-word; font-family: monospace; font-size: 13px;'>" +
                    raw2 +
                    "</pre>";

                toggleBtn.value = "Show Rendered";
                mode = "source";
            }
        });

        var closeBtn = document.createElement('input');
        closeBtn.type = "submit";
        closeBtn.value = "X";
        closeBtn.style.color = "white";
        closeBtn.style.background = "red";
        closeBtn.style.border = "1px solid #900";
        closeBtn.style.borderRadius = "4px";
        closeBtn.style.padding = "2px 8px";
        closeBtn.style.cursor = "pointer";
        closeBtn.setAttribute("onclick", "return false;");
        closeBtn.addEventListener("click", function () {
            popup.style.display = "none";
        });

        header.appendChild(title);
        header.appendChild(toggleBtn);
        header.appendChild(closeBtn);

        popup.appendChild(header);
        popup.appendChild(content);
        document.body.appendChild(popup);

        return popup;
    }

    function addShowSourceButton() {
        if (!combinedHTML) return;
        if (document.getElementById("btnShowSource")) return;

        var showbutton = document.createElement('input');
        showbutton.id = "btnShowSource";
        showbutton.type = "submit";
        showbutton.value = "Show Source";
        showbutton.style.color = "red";
        showbutton.style.float = "right";
        showbutton.style.marginLeft = "10px";
        showbutton.setAttribute("onclick", "return false;");

        showbutton.addEventListener("click", function () {
            var p = createPopup();

            if (p.style.display === "none") {
                p.style.display = "";
                showbutton.value = "Hide Source";
            } else {
                p.style.display = "none";
                showbutton.value = "Show Source";
            }
        });

        var download = document.getElementById('Download');
        if (download) {
            var dds = download.getElementsByTagName('dd');
            if (dds.length > 0) {
                dds[0].insertBefore(showbutton, dds[0].firstChild);
            }
        }
    }

    waitForUSC(function (blocks) {

        // ⭐ ONLY BLOCK 2
        if (blocks.length >= 2) {
            combinedHTML =
                "<h3>Block 2</h3>\n" +
                blocks[1].innerHTML +
                "\n<hr>";
        } else {
            combinedHTML = "<h3>No Block 2 found</h3>";
        }

        addShowSourceButton();
    });

    var observer = new MutationObserver(function () {
        addShowSourceButton();
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });

})();
