135 lines
6.0 KiB
C#
135 lines
6.0 KiB
C#
namespace Modules.Library.Domain.Entities.MediaContent.Items.Anime;
|
|
|
|
public abstract class AnimeItem : Entity, IOrderableItem
|
|
{
|
|
protected readonly AnimeTitle _title = default!;
|
|
|
|
public CommonProperties.CommonProperties CommonProperties { get; protected set; } = default!;
|
|
public ushort Order { get; protected set; }
|
|
public ushort Variant { get; protected set; }
|
|
public bool Completed { get; protected set; }
|
|
public override bool Deleted { get; protected set; }
|
|
public TimeSpan ExpirationTime { get; protected set; }
|
|
|
|
|
|
internal static Action<AnimeItem, ushort> SetOrderAction => (item, value) => item.Order = value;
|
|
internal static Action<AnimeItem, ushort> SetVariantAction => (item, value) => item.Variant = value;
|
|
|
|
|
|
private protected AnimeItem() { }
|
|
|
|
internal AnimeItem(AnimeTitle title)
|
|
{
|
|
_title = title;
|
|
CommonProperties = new CommonProperties.CommonProperties();
|
|
}
|
|
|
|
internal AnimeItem(AnimeTitle title, Guid nameOriginalLanguageId, string nameOriginal)
|
|
{
|
|
_title = title;
|
|
CommonProperties = new CommonProperties.CommonProperties(nameOriginalLanguageId, nameOriginal);
|
|
}
|
|
|
|
public abstract void SetOrder(ushort order);
|
|
|
|
public abstract void SetVariant(ushort variant);
|
|
|
|
private static ushort GetNewOrder(IEnumerable<AnimeItem> items) =>
|
|
(ushort)(items.Select(q => (int)q.Order).DefaultIfEmpty(-1).Max() + 1);
|
|
|
|
private static ushort GetNewVariant(IEnumerable<AnimeItem> items, ushort order) =>
|
|
(ushort)(items.Where(q => q.Order == order)
|
|
.Select(q => (int)q.Variant).DefaultIfEmpty(-1).Max() + 1);
|
|
|
|
internal static (ushort Order, ushort Variant) GetOrderAndVariant(IEnumerable<AnimeItem> episodes, ushort? order = null, ushort? variant = null)
|
|
{
|
|
if (!order.HasValue) order = GetNewOrder(episodes);
|
|
else if (order < 0 || order > episodes.Select(q => q.Order).DefaultIfEmpty((ushort)0).Max())
|
|
throw new ArgumentOutOfRangeException(nameof(order));
|
|
|
|
if (!variant.HasValue) variant ??= GetNewVariant(episodes, order.Value);
|
|
else if (variant < 0 || variant > episodes.Select(q => q.Variant).DefaultIfEmpty((ushort)0).Max())
|
|
throw new ArgumentOutOfRangeException(nameof(order));
|
|
return (order.Value, variant.Value);
|
|
}
|
|
|
|
/*
|
|
internal protected void SortItems(IEnumerable<AnimeItem> items) =>
|
|
base.SortItems(items, SetVariantAction, SetOrderAction);
|
|
*/
|
|
|
|
private protected virtual void SetItemOrder(IEnumerable<AnimeItem> items, ushort lastOrder, ushort newOrder)
|
|
{
|
|
if (lastOrder < 0 || lastOrder >= items.Count()) throw new ArgumentOutOfRangeException(nameof(lastOrder));
|
|
if (newOrder < 0 || newOrder >= items.Count()) throw new ArgumentOutOfRangeException(nameof(newOrder));
|
|
var minValue = Math.Min(lastOrder, newOrder);
|
|
var maxValue = Math.Max(lastOrder, newOrder);
|
|
var itemOrderGroups = items.GroupBy(q => q.Order)
|
|
.Select(q => new
|
|
{
|
|
Order = q.Key,
|
|
Items = items.Where(x => x.Order == q.Key)
|
|
.OrderBy(x => x.Variant).ToList()
|
|
})
|
|
.Where(q => q.Order >= minValue && q.Order <= maxValue).ToList();
|
|
var targetItem = itemOrderGroups.First(q => q.Order == newOrder);
|
|
bool seen = false;
|
|
for (int i = 0; i < itemOrderGroups.Count; i++)
|
|
{
|
|
if (object.ReferenceEquals(itemOrderGroups[i], targetItem))
|
|
{
|
|
itemOrderGroups[i].Items.ForEach(q => q.Order = newOrder);
|
|
//itemOrderGroups[i].Order = newOrder;
|
|
seen = true;
|
|
}
|
|
else if (seen && itemOrderGroups[i].Order <= newOrder)
|
|
{
|
|
itemOrderGroups[i].Items.ForEach(q => q.Order = (ushort)(itemOrderGroups[i].Order - 1));
|
|
//orderedItems[i].Order--;// move it left
|
|
}
|
|
else if (itemOrderGroups[i].Order >= newOrder)
|
|
{
|
|
itemOrderGroups[i].Items.ForEach(q => q.Order = (ushort)(itemOrderGroups[i].Order + 1));
|
|
//orderedItems[i].Order++; // move it right
|
|
}
|
|
}
|
|
}
|
|
|
|
private protected virtual void SetItemVariant(IEnumerable<AnimeItem> items, ushort order, ushort lastVariant, ushort newVariant)
|
|
{
|
|
if (order < 0 || order >= items.GroupBy(q => q.Order).Count()) throw new ArgumentOutOfRangeException(nameof(order));
|
|
var variantItems = items.Where(q => q.Order == order).ToList();
|
|
if (lastVariant < 0 || lastVariant >= variantItems.Count()) throw new ArgumentOutOfRangeException(nameof(lastVariant));
|
|
if (newVariant < 0 || newVariant >= variantItems.Count()) throw new ArgumentOutOfRangeException(nameof(newVariant));
|
|
var minValue = Math.Min(lastVariant, newVariant);
|
|
var maxValue = Math.Max(lastVariant, newVariant);
|
|
var orderedItems = variantItems.Where(q => q.Variant >= minValue && q.Variant <= maxValue).ToList();
|
|
var targetItem = orderedItems.First(q => q.Variant == newVariant);
|
|
bool seen = false;
|
|
for (int i = 0; i < orderedItems.Count; i++)
|
|
{
|
|
if (object.ReferenceEquals(orderedItems[i], targetItem))
|
|
{
|
|
orderedItems[i].Variant = newVariant;
|
|
seen = true;
|
|
}
|
|
else if (seen && orderedItems[i].Variant <= newVariant)
|
|
{
|
|
orderedItems[i].Variant--;// move it left
|
|
}
|
|
else if (orderedItems[i].Variant >= newVariant)
|
|
{
|
|
orderedItems[i].Variant++; // move it right
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public virtual void SetCompleted() => StructureAction(() => Completed = true);
|
|
public virtual void SetNotCompleted() => StructureAction(() => Completed = true);
|
|
public virtual void SetExpirationTime(TimeSpan value) => StructureAction(() => ExpirationTime = value);
|
|
|
|
public virtual void Delete() => StructureAction(() => Deleted = true);
|
|
|
|
protected abstract void StructureAction(Action action);
|
|
} |