//Rozdział 19.
//Memento
// Rachunek bankowy

public class BankAccount
{
    private int balance;
    public BankAccount(int balance)
    {
        this.balance = balance;
    }

    // todo: wszystko pozostałe :)
}

public Memento Deposit(int amount)
{
    balance += amount;
    return new Memento(balance);
}
 public void Restore(Memento m)
{
    balance = m.Balance;
}
 public class Memento
{
    public int Balance { get; }
    public Memento(int balance)
    {
        Balance = balance;
    }
}
var ba = new BankAccount(100);
var m1 = ba.Deposit(50);
var m2 = ba.Deposit(25);
WriteLine(ba); // 175

// przywrócenie do m1
ba.Restore(m1);
WriteLine(ba); // 150

// przywrócenie do m2
ba.Restore(m2);
WriteLine(ba); // 175

// Cofnij i ponów

public class BankAccount
{
    private int balance;
    private List<Memento> changes = new List<Memento>();
    private int current;
    public BankAccount(int balance)
    {
        this.balance = balance;
        changes.Add(new Memento(balance));
    }
}

public Memento Deposit(int amount)
{
    balance += amount;
    var m = new Memento(balance);
    changes.Add(m);
    ++current;
    return m;
}

public void Restore(Memento m)
{
    if (m != null)
    {
        balance = m.Balance;
        changes.Add(m);
        current = changes.Count - 1;
    }
}

public Memento Undo()
{
    if (current > 0)
    {
        var m = changes[--current];
        balance = m.Balance;
        return m;
    }
    return null;
}

public Memento Redo()
{
    if (current + 1 < changes.Count)
    {
        var m = changes[++current];
        balance = m.Balance;
        return m;
    }
    return null;
}

var ba = new BankAccount(100);
ba.Deposit(50);
ba.Deposit(25);
WriteLine(ba);

ba.Undo();
WriteLine($"Undo 1: {ba}"); // Undo 1: 150

ba.Undo();
WriteLine($"Undo 2: {ba}"); // Undo 2: 100

ba.Redo();
WriteLine($"Redo 2: {ba}"); // Redo 2: 150
