using System.Collections.Generic; namespace PKHeX.Core { /// /// Tracks slot changes and provides the ability to revert a change. /// public class SlotChangelog { private readonly SaveFile SAV; private readonly Stack UndoStack = new Stack(); private readonly Stack RedoStack = new Stack(); 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() { if (!CanUndo) return null; var change = UndoStack.Pop(); var revert = GetReversion(change.Info, SAV); AddRedo(revert); change.Revert(SAV); return change.Info; } public ISlotInfo Redo() { if (!CanRedo) return null; 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) { switch (info) { case SlotInfoParty p: return new PartyReversion(p, sav); default: return 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 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 class SingleSlotReversion : SlotReversion { private readonly PKM PKM; public SingleSlotReversion(ISlotInfo info, SaveFile sav) : base(info) => PKM = info.Read(sav); public override void Revert(SaveFile sav) => Info.WriteTo(sav, PKM, PKMImportSetting.Skip); } } }