package udo.logic;

import udo.gui.GUI;
import udo.logic.command.Command;
import udo.storage.Storage;

public class Logic {
    private GUI gui;
    private Storage storage;

    private static final String ERR_FORMAT = "Error: %s";
    public static final String ERR_INVALID_CMD_NAME = "Invalid command";
    public static final String ERR_UNSUPPORTED_CMD = "Unsupported command";
    public static final String ERR_INVALID_CMD_ARG =
            "Invalid command's argument";
    public static final String ERR_UNSPECIFIED_INDEX =
            "A valid task's index is required";
    public static final String ERR_LATE_DEADLINE =
            "Deadline has already passed";
    public static final String ERR_NON_POSITIVE_DUR =
            "Task's duration must be positive";
    public static final String ERR_STORAGE =
            "Tasks' storage input/output error";
    public static final String ERR_INVALID_INDEX =
            "Specified task's index is not valid";
    public static final String ERR_EMPTY_CONTENT =
            "task's content cannot be empty";

    public static final String STATUS_ADDED = "Task: %s added sucessfully";
    public static final String STATUS_DELETED =
            "Task: %s deleted sucessfully";
    public static final String STATUS_MODIFIED =
            "Task: %s modified sucessfully";
    public static final Integer MAX_STATUS_LENGTH = 40;

    private InputParser parser;

    private static String status;

    public Logic(GUI gui) {
        this.gui = gui;
        parser = new InputParser();
        storage = new Storage();
        /* TODO:
         * Initialize and start up passive thread for reminder
         */
    }

    /**
     * Execute the command given in the command string
     * @param command the command string
     */
    public boolean executeCommand(String command) {
        Command parsedCommand = parser.parseCommand(command);
        if (parser.getErrorStatus() != null) {
            status = parser.getErrorStatus();
            gui.displayStatus(status);
            return false;
        }
        
        parsedCommand.setGUI(gui);
        parsedCommand.setStorage(storage);

        return parsedCommand.execute();
    }

    /**
     * @param parsedCommand
     * @return
     */
    public static String summarizeContent(String taskContent) {
        if (taskContent == null) {
            return "";
        }

        if (taskContent.length() > MAX_STATUS_LENGTH) {
            taskContent = taskContent.substring(0, MAX_STATUS_LENGTH);
            taskContent += "...";
        }
        return taskContent;
    }

    public static String formatErrorStr(String errorInvalidCmdName) {
        return String.format(ERR_FORMAT, errorInvalidCmdName);
    }

    public static void main(String[] argv) {
        Logic logic = new Logic(new GUI());
        logic.executeCommand("go to school /deadline tomorrow");
        logic.executeCommand("add go to school /start tomorrow 2pm /end tomorrow 4pm");
        logic.executeCommand("add AAAI conference /start in 2 days /end tuesday");
        logic.executeCommand("add match midterm /start next friday /end 11/02/15");
        logic.executeCommand("add watch a movie /duration 2 hours 30 minutes");
        logic.executeCommand("submit the report /dl next friday /reminder next thursday");
    }
}
@@ -1413,16 +1413,51 @@
  parser;
+%0A    private Logic logicObj = null;
 %0A%0A    pr
@@ -1494,54 +1494,24 @@
    p
-ublic
+rivate
  Logic(
-GUI gui) %7B%0A        this.gui = gui;
+) %7B
 %0A   
@@ -1656,16 +1656,16 @@
 eminder%0A
-
         
@@ -1669,24 +1669,249 @@
     */%0A    %7D
+%0A    %0A    public Logic getInstance() %7B%0A        if (logicObj == null) %7B%0A            logicObj = new Logic();%0A        %7D%0A        %0A        return logicObj;%0A    %7D%0A    %0A    public void setGUI(GUI gui) %7B%0A        this.gui = gui;%0A    %7D
 %0A%0A    /**%0A  
@@ -3048,17 +3048,8 @@
 gic(
-new GUI()
 );%0A 

Implement singleton between GUI and Logic