using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; namespace DominionBase.Cards { public abstract class CardLabel { public virtual string Name { get; private set; } public virtual ICard AttachedCard { get; private set; } public CardLabel(ICard attachedCard) { AttachedCard = attachedCard; } } public class CardLabelCollection : List { public delegate void CardLabelsChangedEventHandler(object sender, CardLabelsChangedEventArgs e); public event CardLabelsChangedEventHandler CardLabelsChanged; public CardLabelCollection() { } public CardLabelCollection(int capacity) : base(capacity) { } public CardLabelCollection(IEnumerable collection) : base(collection) { } public new void Add(CardLabel cardLabel) { Contract.Requires(cardLabel != null, "cardLabel cannot be null"); base.Add(cardLabel); CardLabelsChanged?.Invoke(this, new CardLabelsChangedEventArgs(this, CardLabelsChangedEventArgs.Operation.Added, cardLabel)); } public new void Remove(CardLabel cardLabel) { Contract.Requires(cardLabel != null, "cardLabel cannot be null"); base.Remove(cardLabel); CardLabelsChanged?.Invoke(this, new CardLabelsChangedEventArgs(this, CardLabelsChangedEventArgs.Operation.Removed, cardLabel)); } public void RemoveMatching(Type cardLabelType) { Contract.Requires(cardLabelType != null, "cardLabelType cannot be null"); var matching = this.Where(c => c.GetType() == cardLabelType); if (matching.Any()) { RemoveAll(c => matching.Contains(c)); CardLabelsChanged?.Invoke(this, new CardLabelsChangedEventArgs(this, CardLabelsChangedEventArgs.Operation.Removed, matching)); } } } public class CardLabelsChangedEventArgs : EventArgs { public enum Operation { Reset, Added, Removed } public CardLabelCollection AddedLabels { get; } = new CardLabelCollection(); public CardLabelCollection RemovedLabels { get; } = new CardLabelCollection(); public Operation OperationPerformed { get; } public CardLabelCollection CardLabels { get; } public IPlayer Player { get; } public int Count => CardLabels.Count; public CardLabelsChangedEventArgs(CardLabelCollection cardLabels, Operation operation) { CardLabels = cardLabels; OperationPerformed = operation; } public CardLabelsChangedEventArgs(CardLabelCollection cardLabels, Operation operation, CardLabel labelChanged) : this(cardLabels, null, operation, labelChanged) { } public CardLabelsChangedEventArgs(CardLabelCollection cardLabels, Operation operation, IEnumerable labelsChanged) : this(cardLabels, null, operation, labelsChanged) { } public CardLabelsChangedEventArgs(CardLabelCollection cardLabels, IPlayer player, Operation operation) : this(cardLabels, operation) { Player = player; } public CardLabelsChangedEventArgs(CardLabelCollection cardLabels, IPlayer player, Operation operation, CardLabel labelChanged) : this(cardLabels, player, operation) { switch (operation) { case Operation.Added: AddedLabels.Add(labelChanged); break; case Operation.Removed: RemovedLabels.Add(labelChanged); break; } } public CardLabelsChangedEventArgs(CardLabelCollection cardLabels, IPlayer player, Operation operation, IEnumerable labelsChanged) : this(cardLabels, player, operation) { switch (operation) { case Operation.Added: AddedLabels.AddRange(labelsChanged); break; case Operation.Removed: RemovedLabels.AddRange(labelsChanged); break; } } } }