<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Point Cloud Viewer (Updated for Binary PCD)</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            font-family: Arial, sans-serif;
        }

        #container {
            position: relative;
            width: 100vw;
            height: 100vh;
        }

        #info {
            position: absolute;
            top: 10px;
            left: 10px;
            background: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 10px;
            border-radius: 5px;
            z-index: 10;
        }

        #controls {
            position: absolute;
            top: 10px;
            right: 10px;
            background: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 10px;
            border-radius: 5px;
            z-index: 10;
        }

        #controls select,
        #controls button {
            display: block;
            margin: 5px 0;
            padding: 5px;
        }

        #loading {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: white;
            background: rgba(0, 0, 0, 0.7);
            padding: 20px;
            border-radius: 5px;
            z-index: 20;
            display: none;
        }
    </style>
</head>

<body>
    <div id="container"></div>
    <div id="info">
        <h3>Point Cloud Viewer</h3>
        <p>Use mouse to orbit, zoom, and pan.</p>
    </div>
    <div id="controls">
        <label for="pcdSelect">Select PCD File:</label>
        <select id="pcdSelect">
            <option value="">-- Loading files... --</option>
        </select>
        <button id="screenshotBtn">Take Screenshot</button>
    </div>
    <div id="loading">Loading Point Cloud...</div>

    <script src="{{ url_for('static', filename='js/three.min.js') }}"></script>
    <script src="{{ url_for('static', filename='js/OrbitControls.min.js') }}"></script>
    <script src="{{ url_for('static', filename='js/PCDLoader.min.js') }}"></script>

    <script>
        let scene, camera, renderer, controls, pointCloud = null;
        const container = document.getElementById('container');
        const pcdSelect = document.getElementById('pcdSelect');
        const screenshotBtn = document.getElementById('screenshotBtn');
        const loadingDiv = document.getElementById('loading');

        init();
        loadPCDFileList();

        function init() {
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0xdddddd);

            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.z = 20;

            renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setPixelRatio(window.devicePixelRatio);
            container.appendChild(renderer.domElement);

            controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.enableDamping = false;
            controls.dampingFactor = 0.05;
            controls.screenSpacePanning = true;
            controls.minDistance = 1;
            controls.maxDistance = 1000;

            const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
            scene.add(ambientLight);

            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
            directionalLight.position.set(10, 20, 15);
            scene.add(directionalLight);

            window.addEventListener('resize', onWindowResize, false);
            animate();
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function animate() {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        }

        function loadPCDFileList() {
            fetch('/api/pcd_files')
                .then(response => response.json())
                .then(files => {
                    pcdSelect.innerHTML = '';
                    const defaultOption = document.createElement('option');
                    defaultOption.text = '-- Select a PCD file --';
                    defaultOption.value = '';
                    pcdSelect.appendChild(defaultOption);

                    files.forEach(file => {
                        const option = document.createElement('option');
                        option.text = file;
                        option.value = file;
                        pcdSelect.appendChild(option);
                    });
                })
                .catch(error => {
                    console.error('Error loading PCD file list:', error);
                    pcdSelect.innerHTML = '<option value="">-- Error loading files --</option>';
                });
        }

        pcdSelect.addEventListener('change', function () {
            const selectedFile = this.value;
            if (selectedFile) {
                loadAndDisplayPCD(selectedFile);
            } else {
                if (pointCloud) {
                    scene.remove(pointCloud);
                    pointCloud.geometry.dispose();
                    pointCloud.material.dispose();
                    pointCloud = null;
                }
            }
        });

        function loadAndDisplayPCD(filename) {
            if (pointCloud) {
                scene.remove(pointCloud);
                pointCloud.geometry.dispose();
                pointCloud.material.dispose();
            }

            loadingDiv.style.display = 'block';

            const loader = new THREE.PCDLoader();
            loader.load(
                `/api/load_pcd_stream/${encodeURIComponent(filename)}`,
                function (pointsData) {
                    loadingDiv.style.display = 'none';

                    if (pointsData.material) {
                        pointsData.material.size = 0.05;
                    } else {
                        pointsData.material = new THREE.PointsMaterial({ size: 0.05, color: 0x00aaff });
                    }

                    pointCloud = pointsData;
                    scene.add(pointCloud);

                    if (pointCloud.geometry.boundingBox) {
                        pointCloud.geometry.computeBoundingBox();
                        const size = pointCloud.geometry.boundingBox.getSize(new THREE.Vector3());
                        const maxDim = Math.max(size.x, size.y, size.z);
                        camera.position.set(0, 0, maxDim * 1.5);
                        controls.target.copy(pointCloud.geometry.boundingBox.getCenter(new THREE.Vector3()));
                    } else {
                        camera.position.set(0, 0, 20);
                        controls.target.set(0, 0, 0);
                    }
                    controls.update();
                },
                undefined,
                function (error) {
                    loadingDiv.style.display = 'none';
                    console.error('Error loading PCD file:', error);
                    alert(`Failed to load PCD file: ${error.message}`);
                }
            );
        }

        screenshotBtn.addEventListener('click', function () {
            const canvas = renderer.domElement;
            const link = document.createElement('a');
            link.download = `pointcloud_screenshot_${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.png`;
            link.href = canvas.toDataURL('image/png');
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        });
    </script>
</body>

</html>