package app;

import java.util.Stack;
import controllers.common.Move;
import view.ButtonGroupView;

/**
 * Singleton for handling undo and redo.
 * @author Dylan
 */
public class UndoManager{
	/**Holds the only instance if the undoManager that can be reached.**/
	private static UndoManager instance = new UndoManager();
	/**Stack for tracking moves to be undone**/
	static Stack<Move> undoStack;
	/**Stack for tracking moves to be redone**/
	static Stack<Move> redoStack;
	
	/**Breaks singleton standard to micro manage the undo/redo buttons for the current view.
	 * This value is set in the constructor of ButtonGroupView, essentially telling the 
	 * Undo Manager that the button group view will be using this set of buttons for the given
	 * view instantiation.
	 */
	ButtonGroupView bgv;
	

	/**Private constructor prevents further instantiations**/
	private UndoManager(){
		if(instance != null){throw new IllegalStateException("Alredy Instantiated");}
		undoStack = new Stack<Move>();
		redoStack = new Stack<Move>();
	}

	public void pushMove(Move m){
		//TODO set undo button enabled
		bgv.setUndoEnabled(true);
		UndoManager.undoStack.push(m);
		UndoManager.redoStack.clear();
	}
	
	/**
	 * Undoes the move on top of the undo stack by:
	 * 1) Popping the move
	 * 2) Calling the move's undo
	 * 3) Pushing the move onto the redo stack
	 * Undo fails if there are no moves in the stack for it to undo.
	 * @return true if the undo could be done
	 */
	public boolean undo(){
		if(UndoManager.undoStack.empty()){ 
			bgv.setUndoEnabled(false);
			//TODO Set undo button disabled
			return false;
		}
		//TODO enable the redo button
		bgv.setRedoEnabled(true);
		Move m = UndoManager.undoStack.pop();
		m.undo();
		UndoManager.redoStack.push(m);
		return true;
	}
	
	/**
	 * Redoes the move on top of the redo stack by:
	 * 1) Popping the move
	 * 2) Calling the move's redo
	 * 3) Pushing the move onto the undo stack
	 * Redo fails if there are no moves in the stack for it to redo.
	 * @return true if the redo could be done
	 */
	public boolean redo(){
		if(UndoManager.redoStack.empty()){ 
			bgv.setRedoEnabled(false);
			//TODO set redo button disabled
			return false;
		}
		Move m = UndoManager.redoStack.pop();
		m.redo();
		UndoManager.undoStack.push(m);
		return true;
	}
	
	/**
	 * Gives the singleton a button group to be modified. This value is a changing value,
	 * given when a button group view is instantiated/
	 * @param bgv - the button group being manipulated
	 */
	public void giveButtonGroup(ButtonGroupView bgv){
		this.bgv = bgv;
	}
	
	/**
	 * Clears the stacks of all undos and redos. This is for the
	 * sake of operating between builder view instances.
	 */
	public void flush(){
		UndoManager.redoStack.clear();
		UndoManager.undoStack.clear();
	}
	
	/**
	 * Returns the singular instance of the UndoManager that is created
	 * @return the UndoManager object
	 */
	public static UndoManager getInstance(){
		return instance;
	}
}

@@ -1056,16 +1056,42 @@
 e m)%7B%0A%09%09
+bgv.setUndoEnabled(true); 
 //TODO s
@@ -1117,36 +1117,8 @@
 led%0A
-%09%09bgv.setUndoEnabled(true);%0A
 %09%09Un
@@ -1515,22 +1515,34 @@
 ())%7B
- 
+return false;%7D
 %0A%09%09
-%09
 bgv.set
-Un
+Re
 doEn
@@ -1551,74 +1551,14 @@
 led(
-false);%0A%09%09%09//TODO Set undo button disabled%0A%09%09%09return false;%0A%09%09%7D%0A%09%09
+true);
 //TO
@@ -1587,36 +1587,8 @@
 ton%0A
-%09%09bgv.setRedoEnabled(true);%0A
 %09%09Mo
@@ -1660,32 +1660,122 @@
 oStack.push(m);%0A
+%09%09if(UndoManager.undoStack.empty())%7Bbgv.setUndoEnabled(false);%7D//TODO IF emptied, disable%0A
 %09%09return true;%0A%09
@@ -2106,18 +2106,31 @@
 pty())%7B 
+return false;%7D
 %0A
-%09
 %09%09bgv.se
@@ -2122,34 +2122,34 @@
 alse;%7D%0A%09%09bgv.set
-Re
+Un
 doEnabled(false)
@@ -2146,71 +2146,43 @@
 led(
-false);%0A%09%09%09//TODO set redo button disabled%0A%09%09%09return false;%0A%09%09%7D
+true);//TODO enable the undo button
 %0A%09%09M
@@ -2263,16 +2263,106 @@
 ush(m);%0A
+%09%09if(UndoManager.undoStack.empty())%7Bbgv.setRedoEnabled(false);%7D//TODO if emptied, disable%0A
 %09%09return

Undo responds correctly. Not sure about redo (can't see it)