<!DOCTYPE html>
<html>
<head>
    <style>
        body { margin: 0; overflow: hidden; background: #000; }
        #ui {
            position: fixed;
            top: 10px;
            left: 10px;
            color: #0f0;
            background: rgba(0,20,0,0.7);
            padding: 15px;
            border: 1px solid #0f0;
            font-family: monospace;
            z-index: 100;
        }
        .control { margin: 10px 0; }
        #matrix {
            position: fixed;
            top: 0;
            left: 0;
            z-index: -1;
            color: #0f0;
            font-family: monospace;
            font-size: 12px;
            opacity: 0.2;
        }
    </style>
</head>
<body>
    <div id="ui">
        <div class="control">
            <button onclick="initAudio()">Start Audio</button>
        </div>
        <div class="control">
            <label>Particle Speed: <input type="range" id="speed" min="1" max="200" value="100"></label>
        </div>
        <div class="control">
            <label>Energy Level: <input type="range" id="energy" min="1" max="100" value="50"></label>
        </div>
        <div class="control">
            <label>Power: <input type="range" id="power" min="1" max="100" value="75"></label>
        </div>
        <div class="control">
            <button onclick="addParticle()">Add Particle</button>
            <button onclick="addDarkMatter()">Add Dark Matter</button>
        </div>
        <div>Particles: <span id="particleCount">0</span></div>
    </div>
    <div id="matrix"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        let scene, camera, renderer, particles = [], darkMatter = [], plasmaParticles = [];
        let audioContext;
        const TUBE_RADIUS = 20;

        function initAudio() {
            audioContext = new (window.AudioContext || window.webkitAudioContext)();
        }

        function playCollisionSound() {
            const oscillator1 = audioContext.createOscillator();
            const oscillator2 = audioContext.createOscillator();
            const gainNode = audioContext.createGain();
            
            oscillator1.connect(gainNode);
            oscillator2.connect(gainNode);
            gainNode.connect(audioContext.destination);
            
            oscillator1.frequency.setValueAtTime(440 + Math.random() * 220, audioContext.currentTime);
            oscillator2.frequency.setValueAtTime(220 + Math.random() * 110, audioContext.currentTime);
            
            oscillator1.type = 'sine';
            oscillator2.type = 'square';
            
            gainNode.gain.setValueAtTime(0.2, audioContext.currentTime);
            gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3);
            
            oscillator1.start();
            oscillator2.start();
            oscillator1.stop(audioContext.currentTime + 0.3);
            oscillator2.stop(audioContext.currentTime + 0.3);
        }

        function init() {
            initAudio();
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            // Torus (Accelerator Tube)
            const tubeGeometry = new THREE.TorusGeometry(TUBE_RADIUS, 2, 32, 100);
            const tubeMaterial = new THREE.MeshPhongMaterial({
                color: 0x00ff00,
                transparent: true,
                opacity: 0.3,
                wireframe: true
            });
            const tube = new THREE.Mesh(tubeGeometry, tubeMaterial);
            scene.add(tube);

            // Lighting
            const light = new THREE.PointLight(0xffffff, 1);
            light.position.set(0, 0, 50);
            scene.add(light);
            scene.add(new THREE.AmbientLight(0x404040));

            camera.position.z = 50;

            // Matrix Rain
            initMatrix();
        }

        function initMatrix() {
            const matrix = document.getElementById('matrix');
            const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()";
            setInterval(() => {
                let str = '';
                for(let i = 0; i < 50; i++) {
                    for(let j = 0; j < 100; j++) {
                        str += chars[Math.floor(Math.random() * chars.length)];
                    }
                    str += '\n';
                }
                matrix.textContent = str;
            }, 50);
        }

        function addParticle() {
            const geometry = new THREE.SphereGeometry(0.3, 16, 16);
            const material = new THREE.MeshPhongMaterial({
                color: 0x00ff00,
                emissive: 0x00ff00,
                emissiveIntensity: 0.5
            });
            
            const particle = new THREE.Mesh(geometry, material);
            particle.userData = {
                angle: Math.random() * Math.PI * 2,
                speed: Math.random() * 0.02 + 0.01,
                direction: Math.random() > 0.5 ? 1 : -1,
                phase: Math.random() * Math.PI * 2,
                energy: 100
            };
            
            particles.push(particle);
            scene.add(particle);
            updateParticleCount();
        }

        function addDarkMatter() {
            const geometry = new THREE.SphereGeometry(1, 32, 32);
            const material = new THREE.MeshPhongMaterial({
                color: 0x000066,
                transparent: true,
                opacity: 0.3
            });
            
            const dm = new THREE.Mesh(geometry, material);
            dm.position.set(
                (Math.random() - 0.5) * TUBE_RADIUS * 2,
                (Math.random() - 0.5) * TUBE_RADIUS * 2,
                (Math.random() - 0.5) * TUBE_RADIUS * 2
            );
            
            darkMatter.push(dm);
            scene.add(dm);
        }

        function createPlasmaExplosion(position) {
            const particleCount = 30;
            for(let i = 0; i < particleCount; i++) {
                const geometry = new THREE.SphereGeometry(0.1, 8, 8);
                const material = new THREE.MeshPhongMaterial({
                    color: 0x00ff00,
                    emissive: 0x00ff00,
                    emissiveIntensity: 1
                });
                
                const plasma = new THREE.Mesh(geometry, material);
                plasma.position.copy(position);
                
                const velocity = new THREE.Vector3(
                    (Math.random() - 0.5) * 0.5,
                    (Math.random() - 0.5) * 0.5,
                    (Math.random() - 0.5) * 0.5
                );
                
                plasma.userData = {
                    velocity: velocity,
                    lifetime: 100,
                    maxLifetime: 100
                };
                
                plasmaParticles.push(plasma);
                scene.add(plasma);
            }
        }

        function updateParticles() {
            const speed = document.getElementById('speed').value / 50;
            const energy = document.getElementById('energy').value / 100;
            const power = document.getElementById('power').value / 100;

            // Update particles
            particles.forEach((particle, index) => {
                particle.userData.angle += particle.userData.speed * speed * particle.userData.direction;
                
                particle.position.x = Math.cos(particle.userData.angle) * TUBE_RADIUS;
                particle.position.y = Math.sin(particle.userData.angle) * TUBE_RADIUS;
                particle.position.z = Math.sin(particle.userData.phase) * 2;
                
                particle.userData.phase += 0.01 * particle.userData.direction;

                // Collision detection
                for(let i = index + 1; i < particles.length; i++) {
                    const other = particles[i];
                    if(particle.position.distanceTo(other.position) < 0.6) {
                        createPlasmaExplosion(particle.position);
                        particle.userData.energy -= power * 10;
                        other.userData.energy -= power * 10;
                        playCollisionSound();
                    }
                }

                if(particle.userData.energy <= 0) {
                    scene.remove(particle);
                    particles.splice(index, 1);
                    updateParticleCount();
                }
            });

            // Update plasma particles
            plasmaParticles.forEach((plasma, index) => {
                plasma.position.add(plasma.userData.velocity);
                plasma.userData.lifetime--;
                plasma.material.opacity = plasma.userData.lifetime / plasma.userData.maxLifetime;
                
                if(plasma.userData.lifetime <= 0) {
                    scene.remove(plasma);
                    plasmaParticles.splice(index, 1);
                }
            });
        }

        function updateParticleCount() {
            document.getElementById('particleCount').textContent = particles.length;
        }

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

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