package seedu.todo.controllers;

import java.util.HashMap;
import java.util.Map;

import seedu.todo.commons.exceptions.ParseException;
import seedu.todo.commons.util.StringUtil;
import seedu.todo.controllers.concerns.Renderer;
import seedu.todo.controllers.concerns.Tokenizer;
import seedu.todo.models.TodoListDB;
import seedu.todo.ui.UiManager;

/**
 * @@author A0093907W
 * 
 * Controller to undo a database commit.
 */
public class UndoController implements Controller {
    
    private static final String MESSAGE_SUCCESS = "Successfully undid %s %s!\nTo redo, type \"redo\".";
    private static final String MESSAGE_MULTIPLE_FAILURE = "We cannot undo %s %s! At most, you can undo %s %s.";
    private static final String MESSAGE_FAILURE = "There is no command to undo!";

    @Override
    public float inputConfidence(String input) {
        return input.toLowerCase().startsWith("undo") ? 1 : 0;
    }
    
    /**
     * Get the token definitions for use with <code>tokenizer</code>.<br>
     * This method exists primarily because Java does not support HashMap
     * literals...
     * 
     * @return tokenDefinitions
     */
    private static Map<String, String[]> getTokenDefinitions() {
        Map<String, String[]> tokenDefinitions = new HashMap<String, String[]>();
        tokenDefinitions.put("default", new String[] {"undo"});
        return tokenDefinitions;
    }

    @Override
    public void process(String input) throws ParseException {
        
        Map<String, String[]> parsedResult;
        parsedResult = Tokenizer.tokenize(getTokenDefinitions(), input);
        
        int numUndo = 1;
        if (parsedResult.get("default")[1] != null) {
            numUndo = Integer.parseInt(parsedResult.get("default")[1]);
        }
        
        // We don't really have a nice way to support SQL transactions, so yeah >_<
        TodoListDB db = TodoListDB.getInstance();
        if (numUndo <= 0 || db.undoSize() <= 0) {
            UiManager.updateConsoleMessage(MESSAGE_FAILURE);
            return;
        }
        if (db.undoSize() < numUndo) {
            UiManager.updateConsoleMessage(String.format(MESSAGE_MULTIPLE_FAILURE,
                    numUndo, StringUtil.pluralizer(numUndo, "command", "commands"),
                    db.undoSize(), StringUtil.pluralizer(db.undoSize(), "command", "commands")));
            return;
        }
        for (int i = 0; i < numUndo; i++) {
            if (!db.undo()) {
                UiManager.updateConsoleMessage(MESSAGE_FAILURE);
                return;
            }
        }
        db = TodoListDB.getInstance();
        
        // Render
        Renderer.renderIndex(db, String.format(MESSAGE_SUCCESS, numUndo,
                StringUtil.pluralizer(numUndo, "command", "commands")));
    }
}

@@ -1890,32 +1890,828 @@
 .getInstance();%0A
+        %0A        // Attempt to undo DB. If fail, exit method.%0A        if (attemptUndo(numUndo, db)) %7B%0A            return;%0A        %7D%0A        %0A        // Reload DB%0A        db = TodoListDB.getInstance();%0A        %0A        // Render%0A        Renderer.renderIndex(db, String.format(MESSAGE_SUCCESS, numUndo,%0A                StringUtil.pluralizer(numUndo, %22command%22, %22commands%22)));%0A    %7D%0A    %0A    /**%0A     * Attempt to undo the DB by %3Ccode%3EnumUndo%3C/code%3E steps. If this fails, this%0A     * method will update the console message with appropriate error messages.%0A     * %0A     * @param numUndo   Number of steps to undo%0A     * @param db        TodoListDB instance%0A     * @return          true if undo attempt successful, false otherwise%0A     */%0A    private boolean attemptUndo(int numUndo, TodoListDB db) %7B%0A
         if (numU
@@ -2815,32 +2815,38 @@
           return
+ false
 ;%0A        %7D%0A    
@@ -3155,32 +3155,38 @@
           return
+ false
 ;%0A        %7D%0A    
@@ -3334,32 +3334,38 @@
           return
+ false
 ;%0A            %7D%0A
@@ -3386,210 +3386,19 @@
     
-db = TodoListDB.getInstance();%0A        %0A        // Render%0A        Renderer.renderIndex(db, String.format(MESSAGE_SUCCESS, numUndo,%0A                StringUtil.pluralizer(numUndo, %22command%22, %22commands%22)))
+return true
 ;%0A  

Extract attemptUndo