|  | "use strict";
let overlayLoaded = false;
let baseLoaded = false;
let running = false;
let radius = 200;
let softness = 25;
let width;
let height;
let paintMode = false;
let scale;
document.addEventListener("DOMContentLoaded", e => {
    document.querySelector("#reset-button").addEventListener("click", reset);
    document.querySelector("#load-button").addEventListener("click", e => {
        console.log("Trying to load...");
        const baseInput = document.querySelector("#base-url").value;
        const overlayInput = document.querySelector("#overlay-url").value;
        
        let success = true;
        try {
            let baseURL = new URL(baseInput)
            console.log(baseURL);
        } catch {
            document.querySelector("#base-url").value = "";
            document.querySelector("#base-url").placeholder = "Invalid URL...";
            success = false;
        }
        try {
            let overlayURL = new URL(overlayInput)
            console.log(overlayURL);
        } catch {
            document.querySelector("#overlay-url").value = "";
            document.querySelector("#overlay-url").placeholder = "Invalid URL...";
            success = false;
        }
        if (!success) {
            return;
        }
        const overlayImg = document.querySelector("#overlay-img");
        const baseImg = document.querySelector("#base-img");
        overlayImg.src = overlayInput;
        baseImg.src = baseInput;
        setURL();
        
        load();
        try {
            localStorage.setItem("base", baseInput);
            localStorage.setItem("overlay", overlayInput);
        } catch {
            console.error("Couldn't set something in local storage :(")
        }
    });
    let url = new URL(window.location);
    
    const overlay = document.querySelector("#overlay");
    
    document.addEventListener("mousedown", e => {
        let x = e.clientX - e.target.getBoundingClientRect().x;
        let y = e.clientY - e.target.getBoundingClientRect().y;
        updateOverlay([[x,y]], e.buttons % 2 != 0);
    });
    
    document.addEventListener("mousemove", e => {
        let x = e.clientX - e.target.getBoundingClientRect().x;
        let y = e.clientY - e.target.getBoundingClientRect().y;
        updateOverlay([[x,y]], e.buttons % 2 != 0);
    });
    document.addEventListener("touchstart", e => {
        let offsetX = e.target.getBoundingClientRect().x;
        let offsetY = e.target.getBoundingClientRect().y;
        let touches = [];
        
        for (let i=0; i < e.touches.length; i++) {
            let x = e.touches[i].clientX - offsetX;
            let y = e.touches[i].clientY - offsetY;
            touches.push([x,y]);
        }
        updateOverlay(touches, true);
    });
    document.addEventListener("touchmove", e => {
        let offsetX = e.target.getBoundingClientRect().x;
        let offsetY = e.target.getBoundingClientRect().y;
        let touches = [];
        
        for (let i=0; i < e.touches.length; i++) {
            let x = e.touches[i].clientX - offsetX;
            let y = e.touches[i].clientY - offsetY;
            touches.push([x,y]);
        }
        updateOverlay(touches, true);
    });
    
    document.querySelector("#radius-slider").addEventListener("input", e => {
        try {
            radius = parseInt(e.target.value);
            document.querySelector("#radius-input").value = radius;
        } catch {
            console.warn("That wasn't a valid radius: " + e.target.value);
        }
    });
    
    document.querySelector("#radius-slider").addEventListener("change", e => {
        try {
            radius = parseInt(e.target.value);
            document.querySelector("#radius-input").value = radius;
        } catch {
            console.warn("That wasn't a valid radius: " + e.target.value);
        }
        setURL();
    });
    
    document.querySelector("#radius-input").addEventListener("input", e => {
        try {
            radius = parseInt(e.target.value);
            document.querySelector("#radius-slider").value = radius;
        } catch {
            console.warn("That wasn't a valid radius: " + e.target.value);
        }
    });
    
    document.querySelector("#radius-input").addEventListener("change", e => {
        try {
            radius = parseInt(e.target.value);
            document.querySelector("#radius-slider").value = radius;
        } catch {
            console.warn("That wasn't a valid radius: " + e.target.value);
        }
        setURL();
    });
    
    document.querySelector("#softness-slider").addEventListener("input", e => {
        try {
            softness = parseInt(e.target.value);
            document.querySelector("#softness-input").value = softness;
        } catch {
            console.warn("That wasn't a valid softness: " + e.target.value);
        }
    });
    
    document.querySelector("#softness-slider").addEventListener("change", e => {
        try {
            softness = parseInt(e.target.value);
            document.querySelector("#softness-input").value = softness;
        } catch {
            console.warn("That wasn't a valid softness: " + e.target.value);
        }
        setURL();
    });
    
    document.querySelector("#softness-input").addEventListener("input", e => {
        try {
            softness = parseInt(e.target.value);
            document.querySelector("#softness-slider").value = softness;
        } catch {
            console.warn("That wasn't a valid softness: " + e.target.value);
        }
    });
    
    document.querySelector("#softness-input").addEventListener("change", e => {
        try {
            softness = parseInt(e.target.value);
            document.querySelector("#softness-slider").value = softness;
        } catch {
            console.warn("That wasn't a valid softness: " + e.target.value);
        }
        setURL();
    });
    // see if we have params already; if so, use them!
    const overlayImg = document.querySelector("#overlay-img");
    const baseImg = document.querySelector("#base-img");
    const baseInput = document.querySelector("#base-url");
    const overlayInput = document.querySelector("#overlay-url");
    if (url.searchParams.has("base") && url.searchParams.has("overlay")) {
        let baseURL = url.searchParams.get("base");
        let overlayURL = url.searchParams.get("overlay");
        baseImg.src = baseURL;
        overlayImg.src = overlayURL;
        baseInput.value = baseURL;
        overlayInput.value = overlayURL;
        load();
    } else {
    
        try {
            baseInput.value = localStorage.getItem("base");
            overlayInput.value = localStorage.getItem("overlay");
        } catch {
            console.error("Couldn't get something from local storage :(")
        }
    }
    if (url.searchParams.has("radius")) {
        try {
            radius = parseInt(url.searchParams.get("radius"));
            document.querySelector("#radius-slider").value = radius;
            document.querySelector("#radius-input").value = radius;
        } catch {
            console.warn("That was a bogus radius...");
        }
    }
    if (url.searchParams.has("softness")) {
        try {
            softness = parseInt(url.searchParams.get("softness"));
            document.querySelector("#softness-slider").value = softness;
            document.querySelector("#softness-input").value = softness;
        } catch {
            console.warn("That was a bogus softness...");
        }
    }
    window.addEventListener("resize", e => {
        if (running) {
            setup();
        }
    })
    
    document.querySelector("#fullscreen-button").addEventListener("click", function toggleFullScreen() {
        var doc = window.document;
        var docEl = doc.documentElement;
    
        var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
        var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;
    
        if (!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
            requestFullScreen.call(docEl);
        }
        else {
            cancelFullScreen.call(doc);
        }
    });
    
    document.querySelector("#paint-mode").addEventListener("change", e => {
        paintMode = e.target.checked;
    });
});
function load() {
    document.querySelector("#menu").classList.remove("start");
    const overlayImg = document.querySelector("#overlay-img");
    const baseImg = document.querySelector("#base-img");
    overlayImg.addEventListener("load", function overlayLoad() {
        console.log("The overlay is loaded");
        overlayLoaded = true;
        if (overlayLoaded && baseLoaded) {
            setup();
        }
        overlayImg.removeEventListener("load", overlayLoad);
    })
    baseImg.addEventListener("load", function baseLoad() {
        console.log("The base is loaded");
        baseLoaded = true;
        if (overlayLoaded && baseLoaded) {
            setup();
        }
        
        baseImg.removeEventListener("load", baseLoad);
    })
}
function reset() {
    running = false;
    const overlay = document.querySelector("#overlay");
    const base = document.querySelector("#base");
    const overlayResized = document.querySelector("#overlay-resized");
    const baseResized = document.querySelector("#base-resized");
    document.querySelector("#menu").classList.add("start");
    overlay.classList.add("hidden");
    base.classList.add("hidden");
}
function setup() {
    running = true;
    const overlay = document.querySelector("#overlay");
    const base = document.querySelector("#base");
    const overlayResized = document.querySelector("#overlay-resized");
    const baseResized = document.querySelector("#base-resized");
    overlay.classList.remove("hidden");
    base.classList.remove("hidden");
    const overlayImg = document.querySelector("#overlay-img");
    const baseImg = document.querySelector("#base-img");
    /** @type {CanvasRenderingContext2D} */
    const overlayCtx = overlay.getContext("2d");
    /** @type {CanvasRenderingContext2D} */
    const baseCtx = base.getContext("2d");
    /** @type {CanvasRenderingContext2D} */
    const overlayCtxResized = overlayResized.getContext("2d");
    /** @type {CanvasRenderingContext2D} */
    const baseCtxResized = baseResized.getContext("2d");
    const availableWidth = document.querySelector("#fill-div").getBoundingClientRect().width;
    const availableHeight = document.querySelector("#fill-div").getBoundingClientRect().height;
    const scaleW = availableWidth / baseImg.width;
    const scaleH = availableHeight / baseImg.height;
    scale = Math.min(scaleW, scaleH);
    width = Math.floor(availableWidth * scale / scaleW);
    height = Math.floor(availableHeight * scale / scaleH);
    [baseCtx, baseCtxResized, overlayCtx, overlayCtxResized].forEach(ctx => {
        ctx.canvas.width = width;
        ctx.canvas.height = height;
        ctx.canvas.style.left = (availableWidth - width) / 2 + "px";
        ctx.canvas.style.top = (availableHeight - height) / 2 + "px";
    });
    
    baseCtxResized.drawImage(baseImg, 0, 0, width, height);
    baseCtx.drawImage(baseResized, 0, 0, width, height);
    overlayCtxResized.drawImage(overlayImg, 0, 0, width, height);
    console.log("Done");
}
function updateOverlay(points, clicked) {
    const overlay = document.querySelector("#overlay");
    const overlayResized = document.querySelector("#overlay-resized");
    /** @type {CanvasRenderingContext2D} */
    const overlayCtx = overlay.getContext("2d");
    /** @type {CanvasRenderingContext2D} */
    const overlayCtxResized = overlay.getContext("2d");
    const w = overlayCtx.canvas.width;
    const h = overlayCtx.canvas.height;
    overlayCtx.save();
    overlayCtx.globalCompositeOperation = "source-over";
    if (!paintMode)
        overlayCtx.clearRect(0, 0, w, h);
    if (!paintMode || clicked) {
        points.forEach(point => {
            const [x,y] = point;
            overlayCtx.beginPath();
            overlayCtx.ellipse(x, y, radius * scale, radius * scale, 0, 0, 2 * Math.PI);
        
            const gradient = overlayCtx.createRadialGradient(x, y, 0, x, y, Math.floor(radius * scale));
            gradient.addColorStop((100-softness)/100, '#000000FF');
            gradient.addColorStop(1, '#00000000');
            overlayCtx.fillStyle = gradient;
        
            overlayCtx.fill();
        })
    }
    
    
    overlayCtx.globalCompositeOperation = "source-in";
    overlayCtx.drawImage(overlayResized, 0, 0);
    overlayCtx.restore();
}
function setURL() {
        let shareURL = new URL(window.location);
 
        // for some reason, the parser gets confused by urlencoded urls...
        // so, to get rid of all parameters, we do this
 
        let keys = Array.from(shareURL.searchParams.keys());
        do {
            keys = Array.from(shareURL.searchParams.keys());
            keys.forEach(key => {
                shareURL.searchParams.delete(key);
            });
        } while (keys.length > 0)
        const overlayImg = document.querySelector("#overlay-img");
        const baseImg = document.querySelector("#base-img");
 
        shareURL.searchParams.append("base", baseImg.src);
        shareURL.searchParams.append("overlay", overlayImg.src);
        shareURL.searchParams.append("radius", radius);
        shareURL.searchParams.append("softness", softness);
        window.history.replaceState(null, "X-Ray Viewer", shareURL);
}
 |