using MpcNET; using MpcNET.Commands.Database; using MpcNET.Commands.Reflection; using MpcNET.Tags; using MpcNET.Types; using MpcNET.Types.Filters; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Threading.Tasks; using System.Windows; using System.Windows.Interop; namespace unison { public partial class Shuffle : Window { private MPDHandler _mpd; bool _continuous = false; List _songList { get; } public Shuffle() { InitializeComponent(); _songList = new(); } private bool IsFilterEmpty() { if (Song.Text.Length == 0 && Artist.Text.Length == 0 && Album.Text.Length == 0 && Year.Text.Length == 0 && Genre.SelectedIndex == 0 && Directory.Text.Length == 0) return true; return false; } public bool GetContinuous() { return _continuous; } public void AddContinuousSongs() { if (IsFilterEmpty()) { // add a completely random song ContinuousShuffle_AddToQueueRandom(); return; } int AddedSongs = 0; NumberAddedSongs.Text = AddedSongs.ToString(); SearchStatus.Visibility = Visibility.Visible; HashSet SongIndex = new(); while (SongIndex.Count < 2) { int MaxIndex = new Random().Next(0, _songList.Count - 1); SongIndex.Add(MaxIndex); } foreach (int index in SongIndex) _mpd.AddSong(_songList[index]); SearchStatus.Visibility = Visibility.Collapsed; } public async void ListGenre() { if (Genre.Items.Count == 0) { _mpd = (MPDHandler)Application.Current.Properties["mpd"]; List Response = await _mpd.SafelySendCommandAsync(new ListCommand(MpdTags.Genre, null, null)); if (Response.Count > 0) { Genre.Items.Add(""); foreach (var genre in Response) Genre.Items.Add(genre); } } } public async void ListFolder() { if (Directory.Items.Count == 0) { _mpd = (MPDHandler)Application.Current.Properties["mpd"]; IEnumerable Response = await _mpd.SafelySendCommandAsync(new LsInfoCommand("")); if (Response != null) { Directory.Items.Add(""); foreach (var directory in Response) Directory.Items.Add(directory.Name); } } } private void Window_Closing(object sender, CancelEventArgs e) { e.Cancel = true; WindowState = WindowState.Minimized; Hide(); } public void InitHwnd() { WindowInteropHelper helper = new(this); helper.EnsureHandle(); } private void Reset_Clicked(object sender, RoutedEventArgs e) { Song.Text = ""; Artist.Text = ""; Album.Text = ""; Year.Text = ""; Genre.SelectedIndex = 0; Directory.SelectedIndex = 0; } private async void ContinuousShuffle_Checked(object sender, RoutedEventArgs e) { if (ContinuousShuffle.IsChecked == true) { AddToQueueGroup.IsEnabled = false; _continuous = true; _songList.Clear(); if (!IsFilterEmpty()) { /*await*/ GetSongsFromFilter(); } } else { AddToQueueGroup.IsEnabled = true; _continuous = false; } } private async void ContinuousShuffle_AddToQueueRandom() { for (int i = 0; i < 2; i++) { // generate random number int song = new Random().Next(0, _mpd.GetStats().Songs - 1); // query random song CommandList commandList = new CommandList(new IMpcCommand[] { new SearchCommand(MpdTags.Title, "", song, song + 1) }); string Response = await _mpd.SafelySendCommandAsync(commandList); await Task.Delay(1); if (Response.Length > 0) { // parse song and add it to queue int start = Response.IndexOf("[file, "); int end = Response.IndexOf("],"); string filePath = Response.Substring(start + 7, end - (start + 7)); _mpd.AddSong(filePath); } } SearchStatus.Visibility = Visibility.Collapsed; } private async void AddToQueueRandom() { int AddedSongs = 0; NumberAddedSongs.Text = AddedSongs.ToString(); SearchStatus.Visibility = Visibility.Visible; for (int i = 0; i < int.Parse(SongNumber.Text); i++) { // generate random number int song = new Random().Next(0, _mpd.GetStats().Songs - 1); // query random song CommandList commandList = new CommandList(new IMpcCommand[] { new SearchCommand(MpdTags.Title, "", song, song + 1) }); string Response = await _mpd.SafelySendCommandAsync(commandList); await Task.Delay(1); if (Response.Length > 0) { // parse song and add it to queue int start = Response.IndexOf("[file, "); int end = Response.IndexOf("],"); string filePath = Response.Substring(start + 7, end - (start + 7)); _mpd.AddSong(filePath); AddedSongs++; NumberAddedSongs.Text = AddedSongs.ToString(); } } SearchStatus.Visibility = Visibility.Collapsed; } private async Task GetSongsFromFilter() { _songList.Clear(); SongFilterPanel.Visibility = Visibility.Visible; int song = _mpd.GetStats().Songs; List filtersA = new(); if (Song.Text != "") filtersA.Add(new FilterTag(MpdTags.Title, Song.Text, FilterOperator.Contains)); if (Artist.Text != "") filtersA.Add(new FilterTag(MpdTags.Artist, Artist.Text, FilterOperator.Contains)); if (Album.Text != "") filtersA.Add(new FilterTag(MpdTags.Album, Album.Text, FilterOperator.Contains)); if (Year.Text != "") filtersA.Add(new FilterTag(MpdTags.Date, Year.Text, FilterOperator.Contains)); if (Genre.Text != "") filtersA.Add(new FilterTag(MpdTags.Genre, Genre.Text, FilterOperator.Contains)); if (Directory.Text != "") filtersA.Add(new FilterBase(Directory.Text, FilterOperator.None)); Debug.WriteLine(Directory.Text); CommandList commandList = new CommandList(new IMpcCommand[] { new SearchCommand(filtersA, 0, song + 1) }); string Response = await _mpd.SafelySendCommandAsync(commandList); Debug.WriteLine(Response); // create a list of the file url string[] value = Response.Split(", [file, "); // there are no song in this filter if (value[0] == "") { SongFilterNumber.Text = _songList.Count.ToString(); return; } foreach (string file in value) { int start = 0; int end = file.IndexOf("],"); string filePath = file.Substring(start, end - start); Debug.WriteLine(filePath); _songList.Add(filePath); SongFilterNumber.Text = _songList.Count.ToString(); } // remove characters from first file _songList[0] = _songList[0].Substring(7, _songList[0].Length - 7); SongFilterPanel.Visibility = Visibility.Visible; SongFilterNumber.Text = _songList.Count.ToString(); } private async void AddToQueueFilter() { await GetSongsFromFilter(); int AddedSongs = 0; NumberAddedSongs.Text = AddedSongs.ToString(); SearchStatus.Visibility = Visibility.Visible; // more requested songs than available => add everything if (int.Parse(SongNumber.Text) > _songList.Count) { foreach (string path in _songList) { await Task.Delay(1); _mpd.AddSong(path); AddedSongs++; NumberAddedSongs.Text = AddedSongs.ToString(); } } // more available songs than requested => // we add unique indexes until we reach the requested amount else { HashSet SongIndex = new(); while (SongIndex.Count < int.Parse(SongNumber.Text)) { int MaxIndex = new Random().Next(0, _songList.Count - 1); SongIndex.Add(MaxIndex); } foreach (int index in SongIndex) _mpd.AddSong(_songList[index]); } SearchStatus.Visibility = Visibility.Collapsed; } private void AddToQueue_Clicked(object sender, RoutedEventArgs e) { _mpd = (MPDHandler)Application.Current.Properties["mpd"]; if (_mpd.GetStats() == null) return; if (IsFilterEmpty()) AddToQueueRandom(); else AddToQueueFilter(); } } }