package udo.logic.command;

import java.util.logging.Level;
import java.util.logging.Logger;

import udo.logic.Logic;
import udo.storage.Task;
import udo.util.Config.CommandName;

//@author A0093587M
public class ModifyCommand extends Command {
    public static final String STATUS_MODIFIED =
            "Task: %s modified sucessfully";
    private static final Logger log = Logger.getLogger(ModifyCommand.class.getName());

    public ModifyCommand() {
        super();
        setCommandName(CommandName.MODIFY);
    }

    @Override
    public boolean isValid() {
        if (argIndex == null) {
            setStatus(Logic.formatErrorStr(Logic.ERR_UNSPECIFIED_INDEX));
            return false;
        }

        return super.isValid() && isIndexValid() && isDurationValid();
    }

    @Override
    public boolean execute() {
        log.log(Level.INFO, "Modifying task...");
        if (!super.execute()) {
            return false;
        }

        assert(argIndex != null);

        Integer storageIndex = getStorageIndex(argIndex);
        assert(storageIndex != null);

        Task task = storage.query(storageIndex);

        Task.TaskType newTaskType = getTaskType();
        if (task.getTaskType() == newTaskType) {
            fillTaskFromCommand(task, 0);
        } else {
            task.setTaskType(newTaskType);
            fillTaskFromCommand(task, 0);
            fillDefaults(task);
        }

        log.log(Level.INFO, "Modified task: ");
        log.log(Level.INFO, task.toString(), task);

        boolean isSuccessful = false;

        if (isTaskDatesValid(task)) {
            Task clash = findClashedTask(task, storage.query());
            isSuccessful = storage.modify(storageIndex, task);

            if (!isSuccessful) {
                setStatus(Logic.formatErrorStr(Logic.ERR_STORAGE));
            } else {
                if (clash == null || clash.getIndex() == storageIndex) {
                    setStatus(getModifySucessStatus(task));
                } else {
                    setStatus(getClashWarning(task.getContent(),
                                              clash.getContent()));
                }

                updateGuiTasks();
                updateReminder();
            }
        }

        updateGUIStatus();
        return isSuccessful;
    }

    private String getModifySucessStatus(Task task) {
        return String.format(STATUS_MODIFIED,
                             Logic.summarizeContent(task.getContent()));
    }

    @Override
    protected boolean parseArg(String arg) {
        return parseIndexContentPair(arg);
    }
}

@@ -21,16 +21,79 @@
 mmand;%0A%0A
+import java.util.Calendar;%0Aimport java.util.GregorianCalendar;%0A
 import j
@@ -199,16 +199,40 @@
 e.Task;%0A
+import udo.util.Config;%0A
 import u
@@ -1263,24 +1263,25 @@
 TaskType();%0A
+%0A
         if (
@@ -1363,32 +1363,93 @@
 0);%0A        
-%7D else %7B
+    fixStartEnd(task);%0A        %7D else %7B%0A            resetDates(task);
 %0A           
@@ -1480,16 +1480,17 @@
 kType);%0A
+%0A
         
@@ -2457,24 +2457,1518 @@
 ful;%0A    %7D%0A%0A
+    /**%0A     * Reset a task's datetime data when the task's type is modified%0A     * @param task%0A     */%0A    private void resetDates(Task task) %7B%0A        task.setDeadline(null);%0A        task.setStart(null);%0A        task.setEnd(null);%0A        task.setDuration(null);%0A        task.setReminder(null);%0A    %7D%0A%0A    /**%0A     * If the start or end time of an event is not specified by the information%0A     * given to the modify command, this method will attempt to fix it using%0A     * the task's duration given in the command or in the existing task%0A     * @param task%0A     */%0A    private void fixStartEnd(Task task) %7B%0A        if (task.getTaskType() == Task.TaskType.EVENT) %7B%0A            Integer duration = task.getDuration();%0A%0A            if (duration != null) %7B%0A                if (getOption(Config.OPT_START) == null) %7B%0A                    assert(task.getEnd() != null);%0A%0A                    GregorianCalendar cal = new GregorianCalendar();%0A                    cal.setTime(task.getEnd().getTime());%0A                    cal.add(-Calendar.MINUTE, duration);%0A%0A                    task.setStart(cal);%0A                %7D%0A%0A                if (getOption(Config.OPT_END) == null) %7B%0A                    assert(task.getStart() != null);%0A%0A                    GregorianCalendar cal = new GregorianCalendar();%0A                    cal.setTime(task.getStart().getTime());%0A                    cal.add(Calendar.MINUTE, duration);%0A%0A                    task.setEnd(cal);%0A                %7D%0A            %7D%0A        %7D%0A    %7D%0A%0A
     private 

Fix bug in partial modify with duration