<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Galaxy Exploration - 3D WebGL</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.128/examples/js/controls/OrbitControls.js"></script>
    <style>
        body { margin: 0; background: black; }
        canvas { display: block; }
        #info { position: absolute; top: 10px; left: 10px; color: white; font-size: 16px; }
        #controls { position: absolute; top: 50px; left: 10px; color: white; font-size: 16px; }
    </style>
</head>
<body>
    <div id="info"></div>
    <div id="controls">
        <button onclick="changeSpeed(0.0001)">Slow</button>
        <button onclick="changeSpeed(0.001)">Normal</button>
        <button onclick="changeSpeed(0.01)">Fast</button>
        <button onclick="focusOnBlackHole()">Focus on Black Hole</button>
    </div>

    <script>
        // Initialize scene, camera, renderer
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // Add orbit controls for interaction
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;

        // Galaxy Parameters
        const galaxyRadius = 50;
        const galaxyThickness = 2;
        const starCount = 10000;
        const spiralArmsCount = 2; // Number of spiral arms
        const spiralGeometry = new THREE.BufferGeometry();
        const spiralPositions = new Float32Array(starCount * 3);
        const starInfo = [];

        // Create stars in spiral arms
        for (let i = 0; i < starCount; i++) {
            const angle = Math.random() * Math.PI * 2;
            const arm = Math.floor(Math.random() * spiralArmsCount);
            const radius = Math.random() * galaxyRadius;
            const armAngle = arm * Math.PI / spiralArmsCount + angle * 2;

            // Generate spiral arm positions
            spiralPositions[i * 3] = radius * Math.cos(armAngle);
            spiralPositions[i * 3 + 1] = (Math.random() - 0.5) * galaxyThickness;
            spiralPositions[i * 3 + 2] = radius * Math.sin(armAngle);

            // Store star info
            starInfo.push({
                name: `Star ${i}`,
                distance: radius,
                size: Math.random() * 0.5 + 0.5, // Random star size
                position: new THREE.Vector3(spiralPositions[i * 3], spiralPositions[i * 3 + 1], spiralPositions[i * 3 + 2])
            });
        }

        spiralGeometry.setAttribute('position', new THREE.BufferAttribute(spiralPositions, 3));
        const material = new THREE.PointsMaterial({ color: 0xffffff, size: 0.05 });
        const galaxy = new THREE.Points(spiralGeometry, material);
        scene.add(galaxy);

        // Add black hole
        const blackHoleGeometry = new THREE.SphereGeometry(2, 32, 32);
        const blackHoleMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 });
        const blackHole = new THREE.Mesh(blackHoleGeometry, blackHoleMaterial);
        blackHole.position.set(0, 0, 0);
        scene.add(blackHole);

        // Set camera position
        camera.position.z = 100;

        // Create raycaster for star selection
        const raycaster = new THREE.Raycaster();
        const mouse = new THREE.Vector2();

        // Add event listener for mouse click
        window.addEventListener('click', onMouseClick, false);
        window.addEventListener('mousemove', onMouseMove, false);

        let rotationSpeed = 0.001; // Default speed

        function onMouseClick(event) {
            event.preventDefault();
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

            // Update raycaster based on mouse position
            raycaster.update(camera, renderer.domElement);

            // Check for intersection with stars
            const intersects = raycaster.intersectObject(galaxy);
            if (intersects.length > 0) {
                const star = intersects[0].object;
                const starIndex = intersects[0].index;
                const selectedStar = starInfo[starIndex];

                document.getElementById('info').innerHTML = `
                    <strong>${selectedStar.name}</strong><br>
                    Distance: ${selectedStar.distance.toFixed(2)} light years<br>
                    Size: ${selectedStar.size.toFixed(2)} Solar radii
                `;
            }
        }

        function onMouseMove(event) {
            event.preventDefault();
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        }

        function changeSpeed(speed) {
            rotationSpeed = speed;
        }

        function focusOnBlackHole() {
            new TWEEN.Tween(camera.position)
                .to({ x: 0, y: 0, z: 20 }, 2000)
                .easing(TWEEN.Easing.Quadratic.Out)
                .start();
        }

        // Animation loop
        function animate() {
            requestAnimationFrame(animate);

            galaxy.rotation.x += rotationSpeed;
            galaxy.rotation.y += rotationSpeed;

            controls.update(); // Update the controls
            renderer.render(scene, camera);
        }

        animate();
    </script>
</body>
</html>