Files
Painobar-helper/StationForm.cs
T
2026-08-11 22:42:01 -04:00

247 lines
7.3 KiB
C#

namespace PainoBar_Helper
{
public partial class StationForm : Form
{
private readonly PianobarManager _pianobarManager;
private List<string> _stations;
private List<string> _filteredStations;
private bool _stationsLoaded = false;
private bool _stationEntriesStarted = false;
public StationForm(PianobarManager pianobarManager)
{
InitializeComponent();
_pianobarManager = pianobarManager;
_stations = new List<string>();
_filteredStations = new List<string>();
InitializeControls();
}
#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;
}
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
if (!_stationsLoaded)
LoadStations();
}
private void LoadStations()
{
_stations.Clear();
_filteredStations.Clear();
_stationsLoaded = false;
_stationEntriesStarted = false;
// 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)
{
var line = StripAnsiCodes(e).Trim();
if (string.IsNullOrEmpty(line))
return;
// Parse station list from Pianobar output
// Handles formats like: "0) Station", "*0) Station", " 12) Station"
var match = System.Text.RegularExpressions.Regex.Match(line, @"^\s*\*?\s*(\d+)\)\s*(.+)$");
if (match.Success)
{
_stationEntriesStarted = true;
string stationName = match.Groups[2].Value.Trim();
if (!_stations.Contains(stationName))
{
_stations.Add(stationName);
if (!IsDisposed && IsHandleCreated)
BeginInvoke(() => UpdateStationList());
}
return;
}
// Detect end of station list only after we started receiving entries
if (_stationEntriesStarted && line.Contains("Select station:", StringComparison.OrdinalIgnoreCase))
{
_stationsLoaded = true;
_pianobarManager.OutputReceived -= PianobarManager_OutputReceived;
if (!IsDisposed && IsHandleCreated)
BeginInvoke(() => FinalizeStationList());
}
}
private static string StripAnsiCodes(string value)
{
return System.Text.RegularExpressions.Regex.Replace(value, @"\x1B\[[0-9;]*[A-Za-z]", string.Empty);
}
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
}
}