using DominionBase.Enums; using DominionBase.Piles; using DominionBase.Players; using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Xml; namespace DominionBase.Cards.Nocturne { public class DruidBoons : List, ITableable { public virtual event PileChangedEventHandler PileChanged; public virtual event TokensChangedEventHandler TokensChanged; internal IGame _Game; protected bool _AsynchronousChanging { get; private set; } protected PileChangedEventArgs _AsynchronousPileChangedEventArgs { get; private set; } public Type TableableType => TypeClass.DruidBoons; public IEnumerable Types { get { return this.Select(b => b.Type); } } public IDisplayable Randomizer { get; } public bool CanUndo => false; #region IGameObject properties public Guid UniqueId { get; } = Guid.NewGuid(); public string Name { get; protected set; } public string ImageName => Type.Name; public Type Type => GetType(); #endregion #region ICardBase properties public virtual Cost BaseCost { get; } = new Cost(); public Type BaseType => GetType(); public virtual Categories Category => this.Select(b => b.Category).Aggregate((x, y) => x | y); public virtual bool HasCost => false; public virtual bool HasVPs => false; public virtual string SetupText { get; } = string.Empty; public virtual Source Source { get; } = Source.All; public string Text => string.Empty; public virtual List GetSerializingTypes() { return new List(); } #endregion #region IDisplayable properties public CardBack CardBack { get; } = CardBack.Standard; public IDisplayable DisplayCard => this; public Edition Edition { get; } public virtual Facing Facing { get; private set; } = Facing.FaceUp; public virtual bool IsStackable => false; public virtual Location Location { get; } = Location.Special; public virtual Orientation Orientation { get; } = Orientation.Landscape; public IDisplayable RootCard => this; public virtual Traits Traits => this.Select(b => b.Traits).Aggregate((x, y) => x | y); public virtual DisplayableCollection Stack() { return new DisplayableCollection(this); } public virtual void TearDown(IGame game) { } public int CompareTo(IDisplayable obj) { Contract.Requires(obj != default(IDisplayable), "obj cannot be null"); if (ReferenceEquals(this, obj)) return 0; if (obj is Project oProj) return CompareTo(oProj); if (obj is Card || obj is ISupply || obj is Event || obj is Landmark || obj is State || obj is IBoon || obj is IHex) return 1; var c = string.Compare(Name, obj.Name, StringComparison.CurrentCulture); if (c != 0) return c; return UniqueId.CompareTo(obj.UniqueId); } #endregion #region IComparable properties public int CompareTo(DruidBoons druidBoons) { Contract.Requires(druidBoons != default(DruidBoons), "druidBoons cannot be null"); if (ReferenceEquals(this, druidBoons)) return 0; return UniqueId.CompareTo(druidBoons.UniqueId); } public int CompareTo(ITableable obj) { Contract.Requires(obj != default(ITableable), "obj cannot be null"); if (obj is IDisplayable oDisp) return CompareTo(oDisp); return string.Compare(Name, obj.Name, StringComparison.CurrentCulture); } #endregion internal DruidBoons(string name, IGame game) { Name = name; _Game = game; } public static DruidBoons CreateInstance(Type type) { return (DruidBoons)Activator.CreateInstance(type); } #region IDisposable variables, properties, & methods // Track whether Dispose has been called. private bool disposed; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // Check to see if Dispose has already been called. if (!disposed) { // If disposing equals true, dispose all managed // and unmanaged resources. if (disposing) { // Dispose managed resources. } // Call the appropriate methods to clean up // unmanaged resources here. // If disposing is false, // only the following code is executed. // Note disposing has been done. disposed = true; } } ~DruidBoons() { Dispose(false); } #endregion public void BeginChanges() { _AsynchronousChanging = true; _AsynchronousPileChangedEventArgs = null; } public void EndChanges() { _AsynchronousChanging = false; if (_AsynchronousPileChangedEventArgs != null) { PileChanged?.Invoke(this, _AsynchronousPileChangedEventArgs); } _AsynchronousPileChangedEventArgs = null; } public TokenCollection Tokens { get; } = new TokenCollection(); public void AddToken(Token token) { Tokens.Add(token); if (TokensChanged != null) { var etcea = new TokensChangedEventArgs(token); TokensChanged(this, etcea); } var pcea = new PileChangedEventArgs(Operation.Refresh); if (_AsynchronousChanging) _AsynchronousPileChangedEventArgs = pcea; else PileChanged?.Invoke(this, pcea); } public Token RemoveToken(Type tokenType) { var foundToken = Tokens.FirstOrDefault(t => t.GetType() == tokenType); return foundToken != null ? RemoveToken(foundToken) : null; } public Token RemoveToken(Token token) { Tokens.Remove(token); if (TokensChanged != null) { var etcea = new TokensChangedEventArgs(token); TokensChanged(this, etcea); } var pcea = new PileChangedEventArgs(Operation.Refresh); if (_AsynchronousChanging) _AsynchronousPileChangedEventArgs = pcea; else PileChanged?.Invoke(this, pcea); return token; } public void AddPlayer(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); player.PhaseChanged += Player_PhaseChangedEvent; player.PlayerModeChanged += Player_PlayerModeChangedEvent; } public void RemovePlayer(IPlayer player) { Contract.Requires(player != null, "player cannot be null"); player.PhaseChanged -= Player_PhaseChangedEvent; player.PlayerModeChanged -= Player_PlayerModeChangedEvent; } void Player_PhaseChangedEvent(object sender, PhaseChangedEventArgs e) { PhaseChanged(sender, e); } void Player_PlayerModeChangedEvent(object sender, PlayerModeChangedEventArgs e) { PlayerModeChanged(sender, e); } internal virtual void PhaseChanged(object sender, PhaseChangedEventArgs e) { } internal virtual void PlayerModeChanged(object sender, PlayerModeChangedEventArgs e) { } public virtual void Reset() { } public virtual void Clear() { } public void FullSetup() { Setup(); SnapshotSetup(); FinalizeSetup(); } public virtual void Setup() { } public virtual void SnapshotSetup() { } public virtual void FinalizeSetup() { Finalize(_Game); } public virtual void Finalize(IGame game) { } public XmlNode GenerateXml(XmlDocument doc) { if (doc == null) throw new ArgumentNullException(nameof(doc)); var xeDruidBoons = doc.CreateElement("druidBoons"); return xeDruidBoons; } public static DruidBoons Load(Game game, XmlNode xnEntity) { if (xnEntity == null) throw new ArgumentNullException(nameof(xnEntity)); var xnType = xnEntity.SelectSingleNode("type"); if (xnType == null) return null; var type = Type.GetType(xnType.InnerText); var druidBoons = CreateInstance(type); druidBoons.Load(xnEntity); return druidBoons; } public void Load(XmlNode xnEntity) { if (xnEntity == null) return; var boonType = Type.GetType(xnEntity.Attributes["type"].Value); var druidBoons = CreateInstance(boonType); //boon.LoadInstance(xnEntity); } } }