package harmony.mastermind.logic.commands;

import java.util.ArrayList;
import java.util.Stack;

import harmony.mastermind.storage.StorageMemory;
import harmony.mastermind.memory.GenericMemory;
import harmony.mastermind.memory.Memory;

public class History {
    private static ArrayList<GenericMemory> current = null;
    private static Stack<ArrayList<GenericMemory>> back = new Stack<ArrayList<GenericMemory>>();
    private static Stack<ArrayList<GenericMemory>> forward = new Stack<ArrayList<GenericMemory>>();

    //@@author A0143378Y
    // Creates a snapshot of changes in the memory and moves previous state into the back stack. forward stack is reinitialized
    public static void advance(Memory memory) {
        forward = new Stack<ArrayList<GenericMemory>>();
        back.push(current);
        current = new ArrayList<GenericMemory>();
        duplicateMemory(memory);
    }

    //@@author A0143378Y
    // Duplicates memory into the current ArrayList
    private static void duplicateMemory(Memory memory) {
        for (int i = 0; i< memory.getSize(); i++) { // Duplicating of memory into snapshot
            current.add(new GenericMemory(memory.get(i).getType(),
                    memory.get(i).getName(),
                    memory.get(i).getDescription(),
                    memory.get(i).getStart(),
                    memory.get(i).getEnd(),
                    memory.get(i).getState()));
        }
    }

    //@@author A0143378Y
    // Retrieves most recent snapshot in the forward stack and swap it with current memory. Current memory gets pushed into back stack
    public static void redo(Memory memory) {
        if (forward.isEmpty() || (forward.peek() == null)) {
            System.out.println("Nothing to redo!");
            return;
        }
        
        redoMemorySwap(memory);
        StorageMemory.saveToStorage(memory);
        System.out.println("Redo successful.");
    }
    
    //@@author A0143378Y
    // Swaps memory used for redo
    private static void redoMemorySwap(Memory memory) {
        assert forward.size() > 0;
        back.push(current);
        current = forward.pop();
        memory.setList(current);
    }

    //@@author A0143378Y
    // Retrieves most recent snapshot in the back stack and swap it with current memory. Current memory gets pushed into forward stack
    public static void undo(Memory memory) {
        if (back.isEmpty() || (back.peek() == null)) {
            System.out.println("Nothing to undo!");
            return;
        }

        ArrayList<GenericMemory> temp = duplicateTemp(memory);
        undoMemorySwap(memory, temp);
        StorageMemory.saveToStorage(memory);
        System.out.println("Undo successful.");
    }
    
    //@@author A0143378Y
    // Swaps memory used for undo
    private static void undoMemorySwap(Memory memory, ArrayList<GenericMemory> temp) {
        forward.push(temp);
        current = back.pop();
        assert current != null;
        memory.setList(current);
    }

    //@@author A0143378Y
    // Duplicate current memory into temp ArrayList
    private static ArrayList<GenericMemory> duplicateTemp(Memory memory) {
        ArrayList<GenericMemory> temp = new ArrayList<GenericMemory>(); // Duplicating of memory into forward stack
        for (int i = 0; i < memory.getSize(); i++) {
            temp.add(new GenericMemory(memory.get(i).getType(),
                    memory.get(i).getName(),
                    memory.get(i).getDescription(),
                    memory.get(i).getStart(),
                    memory.get(i).getEnd(),
                    memory.get(i).getState()));
        }
        return temp;
    }

}

@@ -1433,2233 +1433,6 @@
   %7D%0A
-%0A    //@@author A0143378Y%0A    // Retrieves most recent snapshot in the forward stack and swap it with current memory. Current memory gets pushed into back stack%0A    public static void redo(Memory memory) %7B%0A        if (forward.isEmpty() %7C%7C (forward.peek() == null)) %7B%0A            System.out.println(%22Nothing to redo!%22);%0A            return;%0A        %7D%0A        %0A        redoMemorySwap(memory);%0A        StorageMemory.saveToStorage(memory);%0A        System.out.println(%22Redo successful.%22);%0A    %7D%0A    %0A    //@@author A0143378Y%0A    // Swaps memory used for redo%0A    private static void redoMemorySwap(Memory memory) %7B%0A        assert forward.size() %3E 0;%0A        back.push(current);%0A        current = forward.pop();%0A        memory.setList(current);%0A    %7D%0A%0A    //@@author A0143378Y%0A    // Retrieves most recent snapshot in the back stack and swap it with current memory. Current memory gets pushed into forward stack%0A    public static void undo(Memory memory) %7B%0A        if (back.isEmpty() %7C%7C (back.peek() == null)) %7B%0A            System.out.println(%22Nothing to undo!%22);%0A            return;%0A        %7D%0A%0A        ArrayList%3CGenericMemory%3E temp = duplicateTemp(memory);%0A        undoMemorySwap(memory, temp);%0A        StorageMemory.saveToStorage(memory);%0A        System.out.println(%22Undo successful.%22);%0A    %7D%0A    %0A    //@@author A0143378Y%0A    // Swaps memory used for undo%0A    private static void undoMemorySwap(Memory memory, ArrayList%3CGenericMemory%3E temp) %7B%0A        forward.push(temp);%0A        current = back.pop();%0A        assert current != null;%0A        memory.setList(current);%0A    %7D%0A%0A    //@@author A0143378Y%0A    // Duplicate current memory into temp ArrayList%0A    private static ArrayList%3CGenericMemory%3E duplicateTemp(Memory memory) %7B%0A        ArrayList%3CGenericMemory%3E temp = new ArrayList%3CGenericMemory%3E(); // Duplicating of memory into forward stack%0A        for (int i = 0; i %3C memory.getSize(); i++) %7B%0A            temp.add(new GenericMemory(memory.get(i).getType(),%0A                    memory.get(i).getName(),%0A                    memory.get(i).getDescription(),%0A                    memory.get(i).getStart(),%0A                    memory.get(i).getEnd(),%0A                    memory.get(i).getState()));%0A        %7D%0A        return temp;%0A    %7D%0A%0A
 %7D%0A

remove unused lines...