package seedu.jimi.logic.commands;

import java.util.HashSet;
import java.util.Set;

import javafx.collections.transformation.FilteredList;
import seedu.jimi.commons.core.Messages;
import seedu.jimi.commons.core.UnmodifiableObservableList;
import seedu.jimi.commons.exceptions.IllegalValueException;
import seedu.jimi.model.ModelManager;
import seedu.jimi.model.tag.Tag;
import seedu.jimi.model.tag.UniqueTagList;
import seedu.jimi.model.task.FloatingTask;
import seedu.jimi.model.task.Name;
import seedu.jimi.model.task.ReadOnlyTask;
import seedu.jimi.model.task.UniqueTaskList;
import seedu.jimi.model.task.UniqueTaskList.DuplicateTaskException;
import seedu.jimi.model.task.UniqueTaskList.TaskNotFoundException;

/**
 * 
 * @author zexuan
 *
 * Edits an existing task/event in Jimi.
 */
public class EditCommand extends Command{

    public static final String COMMAND_WORD = "edit";

    public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits an existing task/event in Jimi. \n"
            + "Example: " + COMMAND_WORD
            + " 2 by 10th July at 12 pm";

    public static final String MESSAGE_EDIT_TASK_SUCCESS = "Updated task details: %1$s";
    public static final String MESSAGE_DUPLICATE_TASK = "This task already exists in Jimi";

    private final int taskIndex; //index of task/event to be edited
    private UniqueTagList newTagList;
    private Name newName; 

    /**
     * Convenience constructor using raw values.
     * //TODO: change to support FloatingTask, Task and Events types as well
     * 
     * @throws IllegalValueException if any of the raw values are invalid
     */
    public EditCommand(String name, Set<String> tags, int taskIndex) throws IllegalValueException {
        final Set<Tag> tagSet = new HashSet<>();
        for (String tagName : tags) {
            tagSet.add(new Tag(tagName));
        }
        this.taskIndex = taskIndex;
        
        //if new fields are to be edited, instantiate them, else set them to the oldName
        if(name != null) {
            this.newName = new Name(name);
        } 

        if(tagSet != null) {
            this.newTagList = new UniqueTagList(tagSet);
        }
    }
    
    @Override
    public CommandResult execute() {
        FilteredList<FloatingTask> lastShownList = ((ModelManager) model).getModifiableTaskList();

        if (lastShownList.size() < taskIndex) {
            indicateAttemptToExecuteIncorrectCommand();
            return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX);
        }

        FloatingTask taskToEdit = lastShownList.get(taskIndex - 1);
        
        if(newName != null) {
            taskToEdit.setName(newName);
        }
            
        if(newTagList != null) {
            taskToEdit.setTags(newTagList);
        }
        
        ((ModelManager) model).editFloatingTask(taskToEdit, taskIndex - 1);
        
        return new CommandResult(String.format(MESSAGE_EDIT_TASK_SUCCESS, taskToEdit));
    }

}

@@ -1386,16 +1386,84 @@
 ewName; 
+%0A    private UnmodifiableObservableList%3CReadOnlyTask%3E lastShownList;
 %0A%0A    /*
@@ -1956,32 +1956,162 @@
 Index;%0A        %0A
+        lastShownList = model.getFilteredTaskList();%0A        ReadOnlyTask taskToEdit = lastShownList.get(taskIndex - 1);%0A        %0A
         //if new
@@ -2198,24 +2198,30 @@
  if(name
- != null
+.length() != 0
 ) %7B%0A    
@@ -2268,18 +2268,123 @@
        %7D
- 
 %0A
+        else %7B%0A            this.newName = taskToEdit.getName(); //assigns old task name%0A        %7D%0A        
 %0A       
@@ -2391,22 +2391,25 @@
  if(
+!
 tagSet
- != null
+.isEmpty()
 ) %7B%0A
@@ -2479,19 +2479,114 @@
   %7D%0A
+        else %7B%0A            this.newTagList = taskToEdit.getTags(); //assigns old tag list%0A        %7D%0A
     %7D%0A
-    %0A
     
@@ -2636,108 +2636,8 @@
 ) %7B%0A
-        FilteredList%3CFloatingTask%3E lastShownList = ((ModelManager) model).getModifiableTaskList();%0A%0A
     
@@ -2831,16 +2831,24 @@
       %7D%0A
+        
 %0A       
@@ -2848,24 +2848,24 @@
         
-Floating
+ReadOnly
 Task tas
@@ -2871,216 +2871,44 @@
 skTo
-Edit = lastShownList.get(taskIndex - 1);%0A        %0A        if(newName != null) %7B%0A            taskToEdit.setName(newName);%0A        %7D%0A            %0A        if(newTagList != null) %7B%0A            taskToEdit.setTags(
+Replace = new FloatingTask(newName, 
 newT
@@ -2912,34 +2912,24 @@
 ewTagList);%0A
-        %7D%0A
         %0A   
@@ -2973,26 +2973,47 @@
 ingTask(
-taskToEdit
+new FloatingTask(taskToReplace)
 , taskIn
@@ -3111,20 +3111,23 @@
 , taskTo
-Edit
+Replace
 ));%0A    
@@ -3128,11 +3128,10 @@
 ;%0A    %7D%0A
-%0A
 %7D%0A

Modify EditCommand to reduce coupling