<?php
// Funktion zum Auslesen der MP3-Dateien aus dem Ordner "sounds"
function getMp3Files() {
    $dir = 'sounds/';
    $files = [];

    if (is_dir($dir)) {
        $scan = scandir($dir);
        foreach ($scan as $file) {
            if (is_file($dir . $file)) {
                $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
                if ($extension === 'mp3' || $extension === 'ogg') {
                    $files[] = $dir . $file;
                }
            }
        }
    }

    return $files;
}

// MP3-Dateien laden
$mp3Files = getMp3Files();

// Titeldaten aus der JSON-Datei laden
$titleData = [];
$jsonFile = 'data/musik_titel.json';
if (file_exists($jsonFile)) {
    $jsonContent = file_get_contents($jsonFile);
    $titleData = json_decode($jsonContent, true) ?: [];
}

// Trackinformationen für JavaScript vorbereiten
$tracksInfo = [];
foreach ($mp3Files as $file) {
    $fileName = basename($file);
    $title = isset($titleData[$fileName]) ? $titleData[$fileName] : $fileName;
    $tracksInfo[] = [
        'path' => $file,
        'fileName' => $fileName,
        'title' => $title
    ];
}

$tracksInfoJson = json_encode($tracksInfo);
?>

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MP3-Player</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #333;
            color: #FFF;
            margin: 0;
            padding: 20px 0;
        }

        .container {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 100%;
        }

        .player-container {
            background-color: #444;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
            width: 300px;
            text-align: center;
            margin-bottom: 20px;
        }

        .visualizer-container {
            width: 300px;
            height: 50px;
            margin: 0 auto 10px;
            background-color: #333;
            border-radius: 4px 4px 2px 2px;
            overflow: hidden;
        }

        #visualizer {
            width: 100%;
            height: 100%;
        }

        .title-container {
            width: 300px;
            margin: 0 auto 15px;
            overflow: hidden;
        }

        .track-title {
            font-size: 16px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            color: #FFF;
            position: relative;
            width: 100%;
        }

        /* Verbesserte Marquee-Effekt Styling */
        .track-title.marquee {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: unset;
            animation: marquee 15s linear infinite;
            display: inline-block;
            padding-left: 100%;
            width: max-content;
        }

        @keyframes marquee {
            0% {
                transform: translateX(0);
            }
            100% {
                transform: translateX(-200%);
            }
        }

        .time-display {
            font-size: 12px;
            margin: 5px 0 15px 0;
            color: #CCC;
            display: flex;
            justify-content: space-between;
        }

        .controls {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-top: 20px;
        }

        button {
            background-color: #CD0000;
            color: white;
            font-size: 16px;
            font-weight: 600;
            border: none;
            padding: 10px 20px;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        button:hover {
            background-color: #FF0000;
        }

        .progress-container {
            margin-top: 20px;
            width: 100%;
            height: 5px;
            background-color: #222;
            border-radius: 5px;
            cursor: pointer;
        }

        .progress-bar {
            height: 100%;
            background-color: #FF0000;
            border-radius: 5px;
            width: 0;
        }

        .volume-container {
            margin-top: 15px;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
        }

        .volume-icon {
            color: #FFF;
            font-size: 14px;
            width: 20px;
        }

        .volume-slider {
            -webkit-appearance: none;
            width: 80%;
            height: 5px;
            border-radius: 5px;
            background: #222;
            outline: none;
        }

        .volume-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 15px;
            height: 14px;
            border-radius: 50%;
            background: #FF0000;
            cursor: pointer;
        }

        .volume-slider::-moz-range-thumb {
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background: #FF0000;
            cursor: pointer;
            border: none;
        }

        .file-list-container {
            margin-top: 20px;
            border: 1px solid #444;
            border-radius: 4px;
            max-height: 150px;
            overflow-y: auto;
            /* Firefox scrollbar styling */
            scrollbar-width: thin;
            scrollbar-color: #FF0000 #222;
        }

        /* WebKit browsers (Chrome, Safari) scrollbar styling */
        .file-list-container::-webkit-scrollbar {
            width: 10px;
        }

        .file-list-container::-webkit-scrollbar-track {
            background: #222;
            border-radius: 4px;
        }

        .file-list-container::-webkit-scrollbar-thumb {
            background-color: #FF0000;
            border-radius: 4px;
            border: 2px solid #222;
        }

        .file-list-container::-webkit-scrollbar-thumb:hover {
            background-color: #FF3333;
        }

        .file-list {
            list-style-type: none;
            padding: 0;
            margin: 0;
        }

        .file-list li {
            padding: 8px 12px;
            cursor: pointer;
            text-align: left;
            border-bottom: 1px solid #444;
            color: #FFFFFF;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .file-list li:last-child {
            border-bottom: none;
        }

        .file-list li:hover {
            background-color: #555;
        }

        .file-list li.active {
            background-color: #666;
        }

        .file-list .duration {
            float: right;
            color: #AAA;
            font-size: 0.9em;
        }

        .loading-text {
            padding: 8px 12px;
            color: #CCC;
            font-style: italic;
        }

        .footer-text {
            font-family: Arial, sans-serif;
            font-size: 9px;
            color: #FFFFFF;
            margin-top: 5px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="player-container">
            <!-- Peak-Meter Visualisierung -->
            <div class="visualizer-container">
                <canvas id="visualizer"></canvas>
            </div>

            <!-- Titel-Container mit fester Breite -->
            <div class="title-container">
                <div class="track-title" id="trackTitle">Musik-Dateien werden geladen<img src="icons/laden.gif" width="14" height="14"></div>
            </div>

            <div class="controls">
                <button id="playButton">Play</button>
                <button id="pauseButton">Pause</button>
                <button id="stopButton">Stop</button>
            </div>

            <!-- Lautstärkeregler -->
            <div class="volume-container">
                <div class="volume-icon"><img src="icons/lautstaerke.png" alt="Lautstärke" width="16" height="14"></div>
                <input type="range" class="volume-slider" id="volumeSlider" min="0" max="1" step="0.01" value="0.7">
            </div>

            <div class="progress-container" id="progressContainer">
                <div class="progress-bar" id="progressBar"></div>
            </div>

            <!-- Zeit-Anzeige direkt unter dem Fortschrittsbalken -->
            <div class="time-display">
                <span id="currentTime">0:00</span>
                <span id="duration">0:00</span>
            </div>

            <!-- Dateiliste -->
            <div class="file-list-container">
                <ul class="file-list" id="fileList">
                    <?php if (empty($tracksInfo)): ?>
                    <li class="loading-text">Keine MP3- oder OGG-Dateien gefunden</li>
                    <?php endif; ?>
                </ul>
            </div>
        </div>

        <div class="footer-text">PHP MP3-Player &copy; S.G.Schiffer 2025 - <a style='text-decoration:none;color:#FF0000;font-weight:600;' href='https://www.sgs-visual.de' target='_blank'>sgs-visual.de</a></div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // Elemente auswählen
            const playButton = document.getElementById('playButton');
            const pauseButton = document.getElementById('pauseButton');
            const stopButton = document.getElementById('stopButton');
            const volumeSlider = document.getElementById('volumeSlider');
            const trackTitle = document.getElementById('trackTitle');
            const progressBar = document.getElementById('progressBar');
            const progressContainer = document.getElementById('progressContainer');
            const fileList = document.getElementById('fileList');
            const canvas = document.getElementById('visualizer');
            const canvasCtx = canvas.getContext('2d');
            const currentTimeDisplay = document.getElementById('currentTime');
            const durationDisplay = document.getElementById('duration');

            // Funktion zum Kürzen von Texten
            function truncateString(str, maxLength) {
                if (str.length <= maxLength) return str;
                return str.substring(0, maxLength) + '...';
            }

            // Funktion zum Formatieren der Zeit (Sekunden in MM:SS)
            function formatTime(seconds) {
                if (isNaN(seconds) || seconds === Infinity) return '0:00';

                seconds = Math.floor(seconds);
                const minutes = Math.floor(seconds / 60);
                const secs = String(seconds % 60).padStart(2, '0');
                return `${minutes}:${secs}`;
            }

            // Canvas-Größe an Container anpassen
            function resizeCanvas() {
                const container = canvas.parentElement;
                canvas.width = container.offsetWidth;
                canvas.height = container.offsetHeight;
            }

            resizeCanvas();
            window.addEventListener('resize', resizeCanvas);

            // Audio-Kontext und Analyser für den Peak-Meter erstellen
            let audioContext = null;
            let analyser = null;
            let dataArray = null;
            let source = null;
            let animationId = null;

            // Audio-Element erstellen
            const audio = new Audio();
            audio.volume = volumeSlider.value; // Initiale Lautstärke setzen
            let currentTrack = null;
            let currentTrackInfo = null;

            // Lautstärkeregler
            volumeSlider.addEventListener('input', function() {
                audio.volume = this.value;
            });

            // Web Audio API für Peak-Meter initialisieren
            function initAudio() {
                if (audioContext) return;

                audioContext = new (window.AudioContext || window.webkitAudioContext)();
                analyser = audioContext.createAnalyser();
                analyser.fftSize = 256;
                source = audioContext.createMediaElementSource(audio);
                source.connect(analyser);
                analyser.connect(audioContext.destination);

                dataArray = new Uint8Array(analyser.frequencyBinCount);

                // Visualisierung starten
                visualize();
            }

            // Peak-Meter zeichnen
            function visualize() {
                if (!audioContext) return;

                analyser.getByteFrequencyData(dataArray);

                const width = canvas.width;
                const height = canvas.height;
                const barWidth = width / dataArray.length * 2;

                canvasCtx.clearRect(0, 0, width, height);

                // Peak-Meter Hintergrund zeichnen
                canvasCtx.fillStyle = '#333';
                canvasCtx.fillRect(0, 0, width, height);

                // Peak-Meter zeichnen
                for (let i = 0; i < dataArray.length; i++) {
                    // Barren-Höhe berechnen (0-255 auf Canvas-Höhe skalieren)
                    const barHeight = (dataArray[i] / 255) * height;

                    // Peak-Meter Farbverlauf basierend auf der Lautstärke
                    let r = 220; // Rot-Komponente
                    let g = 0 - (dataArray[i] / 2); // Grün-Komponente (sinkt mit höherer Amplitude)
                    let b = 0; // Blau-Komponente

                    canvasCtx.fillStyle = `rgb(${r}, ${g}, ${b})`;
                    canvasCtx.fillRect(i * barWidth, height - barHeight, barWidth - 1, barHeight);
                }

                // Animation fortsetzen
                animationId = requestAnimationFrame(visualize);
            }

            // MP3- oder OGG-Dateien mit Titeln aus PHP laden
            const tracksInfo = <?php echo $tracksInfoJson; ?>;

            // Funktion zum Laden der Titeldauer
            function loadTrackDuration(trackPath, trackInfo) {
                return new Promise((resolve) => {
                    // Temporäres Audio-Element zur Ermittlung der Dauer erstellen
                    const tempAudio = new Audio(trackPath);

                    tempAudio.addEventListener('loadedmetadata', function() {
                        // Dauer in Sekunden
                        const durationSeconds = tempAudio.duration;

                        // Dauer formatieren (MM:SS)
                        const formattedDuration = formatTime(durationSeconds);

                        // Daten zur Trackinformation hinzufügen
                        trackInfo.duration = durationSeconds;
                        trackInfo.formattedDuration = formattedDuration;

                        resolve(trackInfo);
                    });

                    tempAudio.addEventListener('error', function() {
                        console.log("Fehler beim Laden der Dauer für:", trackPath);
                        trackInfo.duration = 0;
                        trackInfo.formattedDuration = "0:00";
                        resolve(trackInfo);
                    });
                });
            }

            // Verbesserte Funktion zur Prüfung der Titelbreite und Anwendung des Marquee-Effekts
            function checkTitleWidth() {
                const titleContainer = trackTitle.parentElement;
                const titleWidth = trackTitle.scrollWidth;
                const containerWidth = titleContainer.clientWidth;

                // Reset any previous marquee
                trackTitle.classList.remove('marquee');
                trackTitle.style.animation = 'none';
                trackTitle.offsetHeight; // Trigger reflow to restart animation

                if (titleWidth > containerWidth) {
                    trackTitle.classList.add('marquee');
                    // Adjust animation duration based on text length
                    const animDuration = Math.max(15, titleWidth / 50); // Longer text = slower scrolling
                    trackTitle.style.animation = `marquee ${animDuration}s linear infinite`;
                }
            }

            // Fortschrittsbalken und Zeitanzeige aktualisieren
            audio.addEventListener('timeupdate', function() {
                const progress = (audio.currentTime / audio.duration) * 100;
                progressBar.style.width = progress + '%';

                // Zeit-Anzeige aktualisieren
                currentTimeDisplay.textContent = formatTime(audio.currentTime);
            });

            // Klick auf Fortschrittsbalken
            progressContainer.addEventListener('click', function(e) {
                const clickPosition = e.offsetX / this.offsetWidth;
                audio.currentTime = clickPosition * audio.duration;
            });

            // Play-Button
            playButton.addEventListener('click', function() {
                // Web Audio API initialisieren (benötigt User-Interaktion)
                initAudio();

                if (audio.src) {
                    audio.play();
                } else if (tracksInfo.length > 0) {
                    loadAndPlayTrack(tracksInfo[0].path, tracksInfo[0]);
                }
            });

            // Pause-Button
            pauseButton.addEventListener('click', function() {
                audio.pause();
            });

            // Stop-Button
            stopButton.addEventListener('click', function() {
                audio.pause();
                audio.currentTime = 0;
                progressBar.style.width = '0';
                currentTimeDisplay.textContent = '0:00';

                // Peak-Meter zurücksetzen
                if (audioContext && dataArray) {
                    dataArray.fill(0);
                    visualize();
                }
            });

            // Funktion zum Laden und Abspielen eines Tracks
            function loadAndPlayTrack(trackPath, trackInfo) {
                // Alte "active" Klasse entfernen
                const activeTracks = document.querySelectorAll('.file-list li.active');
                activeTracks.forEach(track => track.classList.remove('active'));

                // Aktuellen Track setzen
                audio.src = trackPath;
                currentTrack = trackPath;
                currentTrackInfo = trackInfo;

                // Titel anzeigen (mit dem Titel aus der JSON-Datei)
                trackTitle.textContent = trackInfo.title;

                // Wenn Dauer bekannt ist, anzeigen
                if (trackInfo.formattedDuration) {
                    durationDisplay.textContent = trackInfo.formattedDuration;
                } else {
                    durationDisplay.textContent = '0:00';

                    // Dauer laden, falls nicht vorhanden
                    loadTrackDuration(trackPath, trackInfo).then(updatedInfo => {
                        durationDisplay.textContent = updatedInfo.formattedDuration;

                        // Listeneintrag aktualisieren
                        const listItem = document.querySelector(`li[data-path="${trackPath}"]`);
                        if (listItem) {
                            // Dauer-Span finden oder erstellen
                            let durationSpan = listItem.querySelector('.duration');
                            if (!durationSpan) {
                                durationSpan = document.createElement('span');
                                durationSpan.className = 'duration';
                                listItem.appendChild(durationSpan);
                            }
                            durationSpan.textContent = updatedInfo.formattedDuration;
                        }
                    });
                }

                // Prüfen, ob Marquee-Effekt benötigt wird
                setTimeout(checkTitleWidth, 50); // Kurze Verzögerung, um DOM-Update abzuwarten

                // Neue "active" Klasse hinzufügen
                const listItems = document.querySelectorAll('.file-list li');
                listItems.forEach(item => {
                    if (item.dataset.path === trackPath) {
                        item.classList.add('active');
                    }
                });

                // Audio API initialisieren (falls noch nicht geschehen)
                initAudio();

                // Abspielen
                audio.play();
            }

            // Fehlerbehandlung
            audio.addEventListener('error', function() {
                trackTitle.textContent = 'Fehler: Datei nicht gefunden';
                durationDisplay.textContent = '0:00';
            });

            // Wenn Track zu Ende ist, nächsten Track abspielen
            audio.addEventListener('ended', function() {
                if (!currentTrack) return;

                const currentIndex = tracksInfo.findIndex(info => info.path === currentTrack);
                if (currentIndex > -1 && currentIndex < tracksInfo.length - 1) {
                    const nextTrack = tracksInfo[currentIndex + 1];
                    loadAndPlayTrack(nextTrack.path, nextTrack);
                }
            });

            // Dateien in der Liste anzeigen mit begrenzter Textlänge und Dauer
            async function displayFileList() {
                // Liste leeren, falls bereits Einträge vorhanden
                if (tracksInfo.length > 0) {
                    fileList.innerHTML = '';
                }

                // Für jede Datei die Dauer vorab laden
                const loadDurationPromises = tracksInfo.map(track =>
                    loadTrackDuration(track.path, track)
                );

                // Warten bis alle Dauern geladen sind
                await Promise.allSettled(loadDurationPromises);

                // Dateien zur Liste hinzufügen (mit den Titeln aus der JSON-Datei und Dauer)
                tracksInfo.forEach(track => {
                    const listItem = document.createElement('li');

                    // Haupttitel-Element
                    const titleSpan = document.createElement('span');
                    titleSpan.textContent = truncateString(track.title, 30);
                    listItem.appendChild(titleSpan);

                    // Dauer-Element
                    const durationSpan = document.createElement('span');
                    durationSpan.className = 'duration';
                    durationSpan.textContent = track.formattedDuration || '0:00';
                    listItem.appendChild(durationSpan);

                    // Metadaten setzen
                    listItem.dataset.path = track.path;
                    listItem.title = track.title; // Tooltip mit vollem Titel

                    // Event-Listener für Klick
                    listItem.addEventListener('click', function() {
                        loadAndPlayTrack(track.path, track);
                    });

                    fileList.appendChild(listItem);
                });

                // Standardmäßig ersten Track auswählen, aber nicht abspielen
                if (tracksInfo.length > 0) {
                    const firstTrack = tracksInfo[0];
                    audio.src = firstTrack.path;
                    currentTrack = firstTrack.path;
                    currentTrackInfo = firstTrack;
                    trackTitle.textContent = firstTrack.title;
                    durationDisplay.textContent = firstTrack.formattedDuration || '0:00';

                    // Prüfen, ob Marquee-Effekt benötigt wird
                    setTimeout(checkTitleWidth, 50);

                    // Ersten Eintrag als aktiv markieren
                    const firstItem = fileList.querySelector('li');
                    if (firstItem) {
                        firstItem.classList.add('active');
                    }
                }
            }

            // MP3- bzw. OGG-Dateien anzeigen mit Dauer
            displayFileList();

            // Bei Änderung der Fenstergröße Marquee-Effekt neu prüfen
            window.addEventListener('resize', checkTitleWidth);
        });
    </script>
</body>
</html>