package watodo.model.task;

import java.util.Objects;

import watodo.commons.util.CollectionUtil;
import watodo.model.tag.UniqueTagList;

/**
 * Represents a Task in the task manager.
 * Guarantees: details are present and not null, field values are validated.
 */

public class Task implements ReadOnlyTask {

    private Name name;
    private Time startTime;
    private Time endTime;
    private Status status;
    private UniqueTagList tags;
    private Priority priority;


    /**
     * constructing a task without a specified end time.
     * @param
     */
    public Task(Name name, Time startTime, Priority priority, UniqueTagList tags, Status status) {
        this(name, startTime, null, priority, tags, status);

    }

    /**
     * Constructor with all parameters, allowing null inputs.
     * @param
     */

    public Task(Name name, Time startTime, Time endTime,
        Priority priority, UniqueTagList tags, Status status) {

        assert !CollectionUtil.isAnyNull(name, startTime, priority, tags, status);
        this.name = name;
        this.startTime = startTime;
        this.endTime = endTime;
        this.priority = priority;
        this.tags = new UniqueTagList(tags); // protect internal tags from changes in the arg list
        this.status = status;
    }


    /**
     * Creates a copy of the given ReadOnlyTask.
     */
    public Task(ReadOnlyTask source) {

        this(source.getName(), source.getStartTime(), source.getEndTime(),
             source.getPriority(), source.getTags(), source.getStatus());
    }

    public void setName(Name name) {
        assert name != null;
        this.name = name;
    }

    @Override
    public Name getName() {
        return name;
    }

    @Override
    public Priority getPriority() {
        return priority;
    }

    public void setPriority(Priority priority) {
        assert priority != null;
        this.priority = priority;
    }

    //@@author A0143873Y
    public void setTime(Time endTime) {
        assert endTime != null;
        this.endTime = endTime;
    }

    public Time getTime() {
        return endTime;
    }

    public void setStartTime(Time startTime) {
        assert startTime != null;
        this.startTime = startTime;
    }

    public Time getStartTime() {
        return startTime;
    }

    public void setEndTime(Time endTime) {
        assert endTime != null;
        this.endTime = endTime;
    }

    public Time getEndTime() {
        return endTime;
    }


    //@@author

    @Override
    public UniqueTagList getTags() {
        return new UniqueTagList(tags);
    }

    /**
     * Replaces this task's tags with the tags in the argument tag list.
     */
    public void setTags(UniqueTagList replacement) {
        tags.setTags(replacement);
    }

    public void setStatus(Status status) {
        assert status.status != this.status.status;
        this.status = status;
    }

    @Override
    public Status getStatus() {
        return status;
    }

    /**
     * Updates this task with the details of {@code replacement}.
     */
    public void resetData(ReadOnlyTask replacement) {
        assert replacement != null;

        this.setName(replacement.getName());
        this.setStartTime(replacement.getStartTime());
        this.setEndTime(replacement.getEndTime());
        this.setPriority(replacement.getPriority());
        //this.setAddress(replacement.getAddress());
        this.setTags(replacement.getTags());
    }

    @Override
    public boolean equals(Object other) {
        return other == this // short circuit if same object
                || (other instanceof ReadOnlyTask // instanceof handles nulls
                && this.isSameStateAs((ReadOnlyTask) other));
    }

    //@@author A0143873Y
    public boolean isFloating() {
        return (this.endTime != null && this.endTime != null); //eventually will startTime will replace endTime.
    }

    public boolean isDeadline() {
        return (this.endTime != null && this.endTime == null);
    }

    public boolean isEvent() {
        return (this.endTime != null && this.endTime != null);
    }
    //@@author

    @Override
    public int hashCode() {
        // use this method for custom fields hashing instead of implementing your own
        return Objects.hash(name, startTime, endTime, priority, tags, status);
    }

    @Override
    public String toString() {
        return getAsText();
    }

}

@@ -3757,32 +3757,192 @@
 uthor A0143873Y%0A
+    /**%0A     * Check whether this %7B@code Task%7D is todo.%0A     * @return %7B@code true%7D if and only if this %7B@code Task%7D has neither startTime nor endTime.%0A     */%0A
     public boole
@@ -3950,16 +3950,12 @@
 n is
-Floating
+Todo
 () %7B
@@ -3966,39 +3966,35 @@
      return 
-(this.end
+start
 Time 
-!
+=
 = null && th
@@ -3987,37 +3987,32 @@
  == null && 
-this.
 endTime 
 != null); //
@@ -4003,62 +4003,170 @@
 ime 
-!
+=
 = null
-); //eventually will startTime will replace end
+;%0A    %7D%0A%0A    /**%0A     * Check whether this %7B@code Task%7D is deadline.%0A     * @return %7B@code true%7D if and only if this %7B@code Task%7D has endTime but not start
 Time
@@ -4167,26 +4167,27 @@
 rtTime.%0A    
-%7D%0A
+ */
 %0A    public 
@@ -4228,62 +4228,213 @@
 urn 
-(this.endTime != null && this.endTime == null);
+startTime == null && endTime != null;%0A    %7D%0A%0A    /**%0A     * Check whether this %7B@code Task%7D is an event.%0A     * @return %7B@code true%7D if and only if this %7B@code Task%7D has both startTime and endTime.
 %0A    
-%7D%0A
+ */
 %0A   
@@ -4480,17 +4480,13 @@
 urn 
-(this.end
+start
 Time
@@ -4497,21 +4497,16 @@
 null && 
-this.
 endTime 
@@ -4512,17 +4512,16 @@
  != null
-)
 ;%0A    %7D%0A

Create boolean methods to show categories