namespace PainoBar_Helper { public partial class StationForm : Form { private readonly PianobarManager _pianobarManager; private List _stations; private List _filteredStations; private bool _stationsLoaded = false; public StationForm(PianobarManager pianobarManager) { InitializeComponent(); _pianobarManager = pianobarManager; _stations = new List(); _filteredStations = new List(); InitializeControls(); LoadStations(); } #region Initialization private void InitializeControls() { // Uses textBox1 (search box) and lstStations from the Designer // Uses btnSelectStation from the Designer if (lstStations != null) { lstStations.DoubleClick += LstStations_DoubleClick; } } private void LoadStations() { // Subscribe to output to capture station list _pianobarManager.OutputReceived += PianobarManager_OutputReceived; // Send command to show stations try { _pianobarManager.ShowStations(); // Show loading message if (lstStations != null) { lstStations.Items.Clear(); lstStations.Items.Add("Loading stations..."); } } catch (Exception ex) { MessageBox.Show($"Failed to load stations:\n{ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region Station Loading private void PianobarManager_OutputReceived(object? sender, string e) { // Parse station list from Pianobar output // Format is typically: "0) Station Name" var match = System.Text.RegularExpressions.Regex.Match(e, @"^\s*(\d+)\)\s*(.+)$"); if (match.Success) { string stationName = match.Groups[2].Value.Trim(); if (!_stations.Contains(stationName)) { _stations.Add(stationName); Invoke(() => UpdateStationList()); } } // Detect end of station list if (e.Contains("Select station:") || e.Contains("[?]")) { _stationsLoaded = true; _pianobarManager.OutputReceived -= PianobarManager_OutputReceived; Invoke(() => FinalizeStationList()); } } private void UpdateStationList() { if (lstStations == null) return; lstStations.Items.Clear(); foreach (var station in _filteredStations.Any() ? _filteredStations : _stations) { lstStations.Items.Add(station); } } private void FinalizeStationList() { if (lstStations != null) { if (_stations.Count == 0) { lstStations.Items.Clear(); lstStations.Items.Add("No stations available"); } } } #endregion #region Search // Wire this to textBox1.TextChanged in the Designer public void textBox1_TextChanged(object? sender, EventArgs e) { if (sender is not TextBox txtSearch) return; string searchText = txtSearch.Text.Trim(); if (string.IsNullOrWhiteSpace(searchText)) { _filteredStations.Clear(); } else { _filteredStations = _stations .Where(s => s.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0) .ToList(); } UpdateStationList(); } #endregion #region Station Selection // Wire this to btnSelectStation.Click in the Designer public void btnSelectStation_Click(object? sender, EventArgs e) { SelectCurrentStation(); } private void LstStations_DoubleClick(object? sender, EventArgs e) { SelectCurrentStation(); } private void SelectCurrentStation() { if (lstStations == null) return; if (lstStations.SelectedIndex < 0) { MessageBox.Show("Please select a station.", "No Selection", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } string selectedStation = lstStations.SelectedItem?.ToString() ?? string.Empty; if (string.IsNullOrEmpty(selectedStation)) return; // Find the index in the original station list int stationIndex = _stations.IndexOf(selectedStation); if (stationIndex < 0) return; try { // Send the station index to Pianobar // Pianobar expects the station number (0-based index) _pianobarManager.SendCommand(stationIndex.ToString()); DialogResult = DialogResult.OK; Close(); } catch (Exception ex) { MessageBox.Show($"Failed to select station:\n{ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region Cancel // Wire this to btnCancelStation.Click in the Designer (or Cancel button) public void btnCancelStation_Click(object? sender, EventArgs e) { // Send 'q' to cancel station selection in Pianobar try { _pianobarManager.SendCommand('q'); } catch { } DialogResult = DialogResult.Cancel; Close(); } #endregion #region Cleanup protected override void OnFormClosing(FormClosingEventArgs e) { _pianobarManager.OutputReceived -= PianobarManager_OutputReceived; base.OnFormClosing(e); } #endregion } }