using DataLayer;
using Dinah.Core.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace LibationUiBase.GridView
{
/// The View Model for a LibraryBook that is ContentType.Parent
public class SeriesEntry : GridEntry
{
public List Children { get; }
public override DateTime DateAdded => Children.Max(c => c.DateAdded);
private bool suspendCounting = false;
public void ChildRemoveUpdate()
{
if (suspendCounting) return;
var removeCount = Children.Count(c => c.Remove == true);
remove = removeCount == 0 ? false : removeCount == Children.Count ? true : null;
RaisePropertyChanged(nameof(Remove));
}
public override bool? Remove
{
get => remove;
set
{
remove = value ?? false;
suspendCounting = true;
foreach (var item in Children)
item.Remove = value;
suspendCounting = false;
RaisePropertyChanged(nameof(Remove));
}
}
public SeriesEntry(LibraryBook parent, LibraryBook child) : this(parent, new[] { child }) { }
public SeriesEntry(LibraryBook parent, IEnumerable children)
{
LastDownload = new();
SeriesIndex = -1;
Children = children
.Select(c => new LibraryBookEntry(c, this))
.OrderByDescending(c => c.SeriesOrder)
.ToList();
UpdateLibraryBook(parent);
LoadCover();
}
///
/// Creates for all episodic series in an enumeration of .
///
/// Can be called from any thread, but requires the calling thread's to be valid.
public static async Task> GetAllSeriesEntriesAsync(IEnumerable libraryBooks)
{
var seriesEntries = await GetAllProductsAsync(libraryBooks, lb => lb.Book.IsEpisodeParent(), lb => new SeriesEntry(lb, []));
var seriesDict = seriesEntries.ToDictionarySafe(s => s.AudibleProductId);
await GetAllProductsAsync(libraryBooks, lb => lb.Book.IsEpisodeChild(), CreateAndLinkEpisodeEntry);
//sort episodes by series order descending and update SeriesEntry
foreach (var series in seriesEntries)
{
series.Children.Sort((a, b) => -a.SeriesOrder.CompareTo(b.SeriesOrder));
series.UpdateLibraryBook(series.LibraryBook);
}
return seriesEntries.Where(s => s.Children.Count != 0).ToList();
//Create a LibraryBookEntry for an episode and link it to its series parent
LibraryBookEntry CreateAndLinkEpisodeEntry(LibraryBook episode)
{
foreach (var s in episode.Book.SeriesLink)
{
if (seriesDict.TryGetValue(s.Series.AudibleSeriesId, out var seriesParent))
{
var entry = new LibraryBookEntry(episode, seriesParent);
seriesParent.Children.Add(entry);
return entry;
}
}
return null;
}
}
public void RemoveChild(LibraryBookEntry lbe)
{
Children.Remove(lbe);
PurchaseDate = GetPurchaseDateString();
Length = GetBookLengthString();
}
protected override string GetBookTags() => null;
protected override int GetLengthInMinutes() => Children.Count == 0 ? 0 : Children.Sum(c => c.LibraryBook.Book.LengthInMinutes);
protected override DateTime GetPurchaseDate() => Children.Count == 0 ? default : Children.Min(c => c.LibraryBook.DateAdded);
}
}