using System.Collections.Generic; namespace PKHeX.Core { /// /// Tracks slot changes and provides the ability to revert a change. /// public sealed class SlotChangelog { private readonly SaveFile SAV; private readonly Stack UndoStack = new(); private readonly Stack RedoStack = new(); public SlotChangelog(SaveFile sav) => SAV = sav; public bool CanUndo => UndoStack.Count != 0; public bool CanRedo => RedoStack.Count != 0; public void AddNewChange(ISlotInfo info) { var revert = GetReversion(info, SAV); AddUndo(revert); } public ISlotInfo Undo() { var change = UndoStack.Pop(); var revert = GetReversion(change.Info, SAV); AddRedo(revert); change.Revert(SAV); return change.Info; } public ISlotInfo Redo() { var change = RedoStack.Pop(); var revert = GetReversion(change.Info, SAV); AddUndo(revert); change.Revert(SAV); return change.Info; } private void AddRedo(SlotReversion change) { RedoStack.Push(change); } private void AddUndo(SlotReversion change) { UndoStack.Push(change); RedoStack.Clear(); } private static SlotReversion GetReversion(ISlotInfo info, SaveFile sav) => info switch { SlotInfoParty p => new PartyReversion(p, sav), _ => new SingleSlotReversion(info, sav) }; private abstract class SlotReversion { internal readonly ISlotInfo Info; protected SlotReversion(ISlotInfo info) => Info = info; public abstract void Revert(SaveFile sav); } private sealed class PartyReversion : SlotReversion { private readonly IList Party; public PartyReversion(ISlotInfo info, SaveFile s) : base(info) => Party = s.PartyData; public override void Revert(SaveFile sav) => sav.PartyData = Party; } private sealed class SingleSlotReversion : SlotReversion { private readonly PKM Entity; public SingleSlotReversion(ISlotInfo info, SaveFile sav) : base(info) => Entity = info.Read(sav); public override void Revert(SaveFile sav) => Info.WriteTo(sav, Entity, PKMImportSetting.Skip); } } }