
<!DOCTYPE html>
<html>
    <head>
        <title>Viewer</title>
        <style type="text/css">
            body, html
            {
                margin: 0; padding: 0; height: 100%; overflow: hidden;
            }

            #viewer
            {
                position:absolute; left: 0; right: 0; bottom: 0; top: 0px;
            }
        </style>
    </head>
    <body>
        <p>Awating load request</p>
        This page will display series when loaded from other pages.
        <div id="viewerContainer" style="width:100%; height:100%; position:relative;">
            <iframe id="viewer" style="width: 100%; height: 100%; border: none; padding: 0px;" ></iframe>
            <div id="resourceDisplay" style="display:none; position:absolute; inset:0; background:#000; align-items:center; justify-content:center; z-index:100000;">
                <div id="resourceInner" style="position:relative; width:100%; height:100%; display:flex; align-items:center; justify-content:center;">
                </div>
                <button id="resourceClose" style="position:absolute; top:8px; right:8px; z-index:9999;" class="btn btn-sm btn-light">Close</button>
            </div>
        </div>

        <script type="text/javascript">
            var win2 = false;

            document.addEventListener("DOMContentLoaded", function() {
                document.title = "Case: {{current_case.title}}";
                console.log('ready');
                const bc = new BroadcastChannel("viva_load");
                function isMediaUrl(url) {
                    if (!url) return false;
                    const lower = url.toLowerCase();
                    if (lower.match(/\.(jpe?g|png|gif|webp|svg)(?:$|\?|#)/)) return 'image';
                    if (lower.match(/\.(mp4|webm|ogg)(?:$|\?|#)/)) return 'video';
                    if (lower.indexOf('youtube.com') !== -1 || lower.indexOf('youtu.be') !== -1) return 'embed';
                    if (lower.indexOf('vimeo.com') !== -1) return 'embed';
                    return false;
                }

                function showResource(url) {
                    const type = isMediaUrl(url);
                    const disp = document.getElementById('resourceDisplay');
                    const inner = document.getElementById('resourceInner');
                    inner.innerHTML = '';
                    if (!type) {
                    // fallback: open in iframe
                        document.getElementById('viewer').src = url;
                        disp.style.display = 'none';
                        return;
                    }
                // create a transform wrapper so we can pan/zoom the content uniformly
                    const transformWrap = document.createElement('div');
                    transformWrap.style.display = 'flex';
                    transformWrap.style.alignItems = 'center';
                    transformWrap.style.justifyContent = 'center';
                    transformWrap.style.width = '100%';
                    transformWrap.style.height = '100%';
                    transformWrap.style.overflow = 'hidden';
                    transformWrap.style.touchAction = 'none';
                    transformWrap.style.position = 'relative';

                    if (type === 'image') {
                        const img = document.createElement('img');
                        img.src = url;
                        img.style.maxWidth = '95%';
                        img.style.maxHeight = '95%';
                        img.style.objectFit = 'contain';
                        img.style.cursor = 'grab';
                        img.draggable = false;
                        transformWrap.appendChild(img);
                    } else if (type === 'video') {
                        const v = document.createElement('video');
                        v.controls = true; v.autoplay = false; v.style.maxWidth = '95%'; v.style.maxHeight = '95%'; v.style.objectFit = 'contain';
                        v.style.cursor = 'grab';
                        const s = document.createElement('source'); s.src = url; v.appendChild(s); transformWrap.appendChild(v);
                    } else if (type === 'embed') {
                        let embed = url;
                        try {
                            const m = url.match(/(?:v=|v\/|embed\/|youtu\.be\/)([A-Za-z0-9_-]{6,})/);
                            if (m && m[1]) embed = 'https://www.youtube.com/embed/' + m[1];
                            else if (url.indexOf('vimeo.com') !== -1) {
                                const m2 = url.match(/vimeo\.com\/(\d+)/);
                                if (m2 && m2[1]) embed = 'https://player.vimeo.com/video/' + m2[1];
                            }
                        } catch(e){}
                        const iframe = document.createElement('iframe');
                        iframe.src = embed; iframe.setAttribute('frameborder','0'); iframe.setAttribute('allowfullscreen','');
                        iframe.style.width = '95%'; iframe.style.height = '85%'; iframe.style.maxWidth = '95%'; iframe.style.maxHeight = '95%';
                        transformWrap.appendChild(iframe);
                    }

                    inner.appendChild(transformWrap);

                // Setup zoom/pan controls for the transformWrap
                    (function enablePanZoom(target){
                        let scale = 1; let minScale = 0.5; let maxScale = 6; let startX=0, startY=0; let translateX=0, translateY=0; let dragging=false;
                        const content = target.firstElementChild;

                        function updateTransform(){
                            if (content) content.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
                        }

                    // Wheel to zoom (allow wheel-only zoom while overlay is shown)
                        target.addEventListener('wheel', function(e){
                        // require overlay active (safety) - if not active, ignore
                            const dispEl = document.getElementById('resourceDisplay');
                            if (!dispEl || dispEl.style.display === 'none') return;
                            e.preventDefault();
                            const delta = -e.deltaY || e.wheelDelta;
                            const zoomFactor = delta > 0 ? 1.12 : 0.9;
                            const newScale = Math.min(maxScale, Math.max(minScale, scale * zoomFactor));
                        // adjust translate to zoom to mouse position
                            const rect = content.getBoundingClientRect();
                            const mx = e.clientX - rect.left; const my = e.clientY - rect.top;
                            const dx = (mx - rect.width/2); const dy = (my - rect.height/2);
                        // compute scale ratio
                            const ratio = newScale/scale - 1;
                            translateX -= dx * ratio;
                            translateY -= dy * ratio;
                            scale = newScale; updateTransform();
                        }, {passive:false});

                    // Pointer drag to pan
                        target.addEventListener('pointerdown', function(e){
                            dragging = true; startX = e.clientX; startY = e.clientY; target.setPointerCapture(e.pointerId); content.style.cursor = 'grabbing';
                        });
                        target.addEventListener('pointermove', function(e){
                            if (!dragging) return; e.preventDefault(); const dx = e.clientX - startX; const dy = e.clientY - startY; startX = e.clientX; startY = e.clientY; translateX += dx; translateY += dy; updateTransform();
                        });
                        target.addEventListener('pointerup', function(e){ dragging = false; try{ target.releasePointerCapture(e.pointerId);}catch(_){} if (content) content.style.cursor = 'grab'; });
                        target.addEventListener('pointercancel', function(e){ dragging=false; if (content) content.style.cursor='grab'; });

                    // double click to reset
                        target.addEventListener('dblclick', function(e){ scale = 1; translateX = 0; translateY = 0; updateTransform(); });

                    // Escape to close
                        document.addEventListener('keydown', function(ev){ if (ev.key === 'Escape'){ document.getElementById('resourceDisplay').style.display='none'; document.getElementById('resourceInner').innerHTML=''; } });
                    })(transformWrap);
                }
                disp.style.display = 'flex';
            }

            // Centralized hide helper
                function hideResource() {
                    const disp = document.getElementById('resourceDisplay');
                    const inner = document.getElementById('resourceInner');
                    if (disp) disp.style.display = 'none';
                    if (inner) inner.innerHTML = '';
                }

            // Robust close: delegate clicks on the overlay so pointer capture doesn't block the button
                (function(){
                    const disp = document.getElementById('resourceDisplay');
                    if (!disp) return;
                    disp.addEventListener('click', function(e){
                    // if click was on the close button (or inside it), hide
                        const close = e.target.closest && e.target.closest('#resourceClose');
                        if (close) { hideResource(); }
                    });
                })();

                bc.onmessage = (event) => {
                    console.log("message received");
                    console.log(event);
                    // Always hide any existing resource overlay on a new load
                    try { hideResource(); } catch (e) { /* ignore if not available */ }
                    if (event.data.type == "open") {
                        // If URL looks like an image/video/embed, render in the resource panel
                        if (event.data.url && isMediaUrl(event.data.url)) {
                            showResource(event.data.url);
                            bc.postMessage({"type": "open-complete", "url" : event.data.url});
                            return;
                        }
                        document.getElementById("viewer").src = event.data.url;
                        bc.postMessage({"type": "open-complete", "url" : event.data.url});
                    }
                };
            });
        </script>

    </body>
</html>
