// Public Domain - Hauptlogik des Radioplayers (Schaltzentrale) document.addEventListener('DOMContentLoaded', function () { // --- UI ELEMENTE --- const presetContainer = document.getElementById('preset-container'); const stopButton = document.querySelector('.stop-button'); const currentStationName = document.getElementById('current-station-name'); const presetModal = document.getElementById('preset-modal'); const tableBody = document.querySelector('#sortable-tbody'); let currentSound = null; // --- INITIALISIERUNG --- if (window.UI) window.UI.initializeFooter(); initializeEventListeners(); // Manager verknüpfen if (window.SleepTimer) { window.SleepTimer.init(() => stopPlayback()); } if (window.PresetManager) { window.PresetManager.load((loadedPresets) => { displayPresets(loadedPresets); initSortable(); }); } // --- EVENT LISTENER --- function initializeEventListeners() { // Stop Button if (stopButton) { stopButton.onclick = stopPlayback; } // Preset Modal öffnen const editBtn = document.getElementById('edit-presets-button'); if (editBtn) { editBtn.onclick = openPresetModal; } // Sleep Timer Modal öffnen const sleepBtn = document.getElementById('open-sleep-timer-modal'); if (sleepBtn) { sleepBtn.onclick = openSleepModal; } // Sleep Timer Modal schließen (X-Button) const closeSleepBtn = document.getElementById('close-sleep-timer-modal'); if (closeSleepBtn) { closeSleepBtn.onclick = () => { const sm = document.getElementById('sleep-timer-modal'); sm.classList.add('hidden'); sm.style.display = 'none'; }; } // Sleep Timer wirklich ausschalten const offSleepBtn = document.getElementById('off-sleep-timer-modal'); if (offSleepBtn) { offSleepBtn.onclick = () => { if (window.SleepTimer) { window.SleepTimer.clear(); // Stoppt den Timeout und resettet die UI } const sm = document.getElementById('sleep-timer-modal'); if (sm) { sm.classList.add('hidden'); sm.style.display = 'none'; } }; } // Zeit-Optionen im Sleep Timer document.querySelectorAll('.time-option').forEach(btn => { btn.onclick = () => { const minutes = parseInt(btn.getAttribute('data-time')) / 60000; window.SleepTimer.start(minutes); const sm = document.getElementById('sleep-timer-modal'); sm.classList.add('hidden'); sm.style.display = 'none'; }; }); } // --- PLAYER LOGIK --- function playStream(url, item) { stopPlayback(); if (window.MetaHandler) window.MetaHandler.stop(); currentSound = new Howl({ src: [url], html5: true, volume: 0.5, // In der playStream Funktion innerhalb von onplay: onplay: () => { stopButton.classList.remove('hidden'); const stationName = item.querySelector('h3').textContent; if (window.UI) window.UI.updateDocumentTitle(stationName); // Wir setzen das Icon für den Sender currentStationName.innerHTML = ` ${stationName}`; if (window.MetaHandler) window.MetaHandler.start(url); }, onstop: () => { stopButton.classList.add('hidden'); currentStationName.textContent = 'Wähle einen Sender aus'; if (window.UI) window.UI.updateDocumentTitle(''); if (window.MetaHandler) window.MetaHandler.stop(); } }); currentSound.play(); } function stopPlayback() { if (currentSound) { currentSound.stop(); currentSound = null; } } // --- PRESET UI --- function displayPresets(presets) { presetContainer.innerHTML = ''; presets.forEach(preset => { const presetItem = document.createElement('div'); presetItem.classList.add('preset-item'); presetItem.innerHTML = `

${preset.name}

`; presetItem.onclick = () => playStream(preset.url, presetItem); presetContainer.appendChild(presetItem); }); } function renderPresetsTable() { if (!tableBody) return; tableBody.innerHTML = ''; window.PresetManager.presets.forEach((preset, index) => { const row = document.createElement('tr'); row.setAttribute('data-index', index); row.innerHTML = ` ☰ `; tableBody.appendChild(row); }); } // --- MODAL WRAPPER --- function openPresetModal() { if (!presetModal) return; presetModal.classList.remove('hidden'); presetModal.style.display = 'block'; renderPresetsTable(); if (window.PresetManager) window.PresetManager.generateExportCode(); } function openSleepModal() { const sm = document.getElementById('sleep-timer-modal'); if (sm) { sm.classList.remove('hidden'); sm.style.display = 'block'; if (window.SleepTimer) window.SleepTimer.updateButtonUI(); } } // --- GLOBALE HELFER (für HTML onclicks & Manager) --- window.closeModal = () => { if (presetModal) { presetModal.classList.add('hidden'); presetModal.style.display = 'none'; } }; window.addPreset = () => { window.PresetManager.presets.push({ name: 'Neuer Sender', url: '' }); renderPresetsTable(); }; window.deletePreset = (index) => { window.UI.showConfirm("Löschen", "Sender wirklich entfernen?", (conf) => { if (conf) { window.PresetManager.presets.splice(index, 1); renderPresetsTable(); window.PresetManager.generateExportCode(); } }); }; window.saveAndClose = () => { window.PresetManager.save(); location.reload(); }; window.changeName = (i, v) => { window.PresetManager.presets[i].name = v; window.PresetManager.generateExportCode(); }; window.changeURL = (i, v) => { window.PresetManager.presets[i].url = v; window.PresetManager.generateExportCode(); }; window.exportPreset = () => window.PresetManager.exportToFile(); window.importPreset = () => { window.UI.showConfirm("Vorsicht", "Alle Sender werden überschrieben!", (conf) => { if (conf) { const input = document.createElement('input'); input.type = 'file'; input.accept = 'application/json'; input.onchange = e => { const reader = new FileReader(); reader.onload = ev => { try { window.PresetManager.presets = JSON.parse(ev.target.result); window.PresetManager.save(); location.reload(); } catch (err) { window.UI.showAlert("Fehler", "Ungültige Datei."); } }; reader.readAsText(e.target.files[0]); }; input.click(); } }); }; window.importFromString = () => { const field = document.getElementById('import-string-field'); const code = field ? field.value.trim() : ""; if (!code) return window.UI.showAlert("Fehler", "Bitte Code einfügen."); window.UI.showConfirm("Vorsicht", "Alle Sender werden überschrieben!", (conf) => { if (conf) window.PresetManager.importFromString(code); }); }; function initSortable() { if (!tableBody) return; new Sortable(tableBody, { handle: '.drag-handle', animation: 150, onEnd: () => { const newOrder = Array.from(tableBody.children).map(row => parseInt(row.getAttribute('data-index'))); window.PresetManager.presets = newOrder.map(index => window.PresetManager.presets[index]); window.PresetManager.generateExportCode(); } }); } });