//@@author A0147984L
package seedu.address.model.task;

import seedu.address.model.tag.Tag;

/**
 * A read-only immutable interface for a Task in the TaskManager.
 * Implementations should guarantee: details are present and not null, field values are validated.
 */
public interface ReadOnlyTask {
    public enum FinishProperty {
        FINISHED, UNFINISHED
    }
    public enum EventProperty {
        EVENT, NON_EVENT
    }
    public enum RecurringProperty {
        RECURRING, NON_RECURRING
    }

    Name getName();
    TaskDate getDate();
    TaskTime getTime();
    Tag getTag();
    Description getDescription();
    Venue getVenue();
    Priority getPriority();
    boolean isFavorite();
    boolean isFinished();
    String getFavoriteText();
    String getFinishedText();
    boolean isEvent();
    boolean isRecurring();

    /**
     * Returns true if both have the same state. (interfaces cannot override equals)
     */
    default boolean isSameStateAs(ReadOnlyTask other) {
        if (this.isEvent() ^ other.isEvent()) {
            return false;
        } else if (!this.isEvent()) {
            return other == this // short circuit if same object
                    || (other != null // this is first to avoid NPE below
                    && checkEqual(this.getName(), other.getName())
                    && checkEqual(this.getDate(), other.getDate())
                    && checkEqual(this.getTime(), other.getTime())
                    && checkEqual(this.getTag(), other.getTag())
                    && ((other.getFinished() == null && this.getFinished() == null)
                            || (other.getFinished() != null && other.getFinished().equals(this.getFinished()))));
                    // state checks here onwards
        } else {
            return other == this // short circuit if same object
                    || (other != null // this is first to avoid NPE below
                    && checkEqual(this.getName(), other.getName())
                    && checkEqual(this.getDate(), other.getDate())
                    && checkEqual(this.getTime(), other.getTime())
                    && checkEqual(((ReadOnlyEvent) this).getStartDate(), ((ReadOnlyEvent) other).getStartDate())
                    && checkEqual(((ReadOnlyEvent) this).getStartTime(), ((ReadOnlyEvent) other).getStartTime())
                    && checkEqual(this.getTag(), other.getTag())
                    && ((other.getFinished() == null && this.getFinished() == null)
                            || (other.getFinished() != null && other.getFinished().equals(this.getFinished()))));
                    // state checks here onwards
        }
    }
//@@author A0147996E
    /**
     * For comparing two tasks in GUItests, to check if the list view matches desired list view.
     */
    default boolean isSameCardAs(ReadOnlyTask other) {
        return other == this // short circuit if same object
                || (other != null // this is first to avoid NPE below
                && checkEqual(this.getName(), other.getName())
                && checkEqual(this.getDate(), other.getDate())
                && checkEqual(this.getTime(), other.getTime())
                && checkEqual(this.getTag(), other.getTag())
                && ((other.getFinished() == null && this.getFinished() == null)
                        || (other.getFinished() != null && other.getFinished().equals(this.getFinished()))));
    }

//@@author A0143409J
    /*
     * Get the FinishProperty instead of boolean
     */
    FinishProperty getFinished();
    EventProperty getEventProperty();
    RecurringProperty getRecurringProperty();

    /*
     * Ensure there is no null pointer exception when comparing two TaskFields
     */
    default boolean checkEqual(TaskField mine, TaskField other) {
        if (mine == null) {
            return other == null;
        } else {
            return mine.equals(other);
        }
    }
//@@author
    /**
     * Formats the person as text, showing all contact details.
     */
    default String getAsText() {
        final StringBuilder builder = new StringBuilder();
        builder.append(getName());
        if (getDate() != null) {
            builder.append("  Due Date:");
            builder.append(getDate());
        }
        if (getTime() != null) {
            builder.append("  Time:");
            builder.append(getTime());
        }
        if (getDescription() != null) {
            builder.append("  Description:");
            builder.append(getDescription());
        }
        if (getTag() != null) {
            builder.append("  List:");
            builder.append(getTag());
        }
        if (getVenue() != null) {
            builder.append("  Venue:");
            builder.append(getVenue());
        }
        assert getPriority() != null;
        builder.append("  Priority:");
        builder.append(getPriority());
        if (isFavorite()) {
            builder.append(" favorite");
        }
        if (isFinished()) {
            builder.append(" finished");
        }
        return builder.toString();
    }
}

@@ -1007,21 +1007,25 @@
 (this.is
-Event
+Recurring
 () %5E oth
@@ -1029,21 +1029,25 @@
 other.is
-Event
+Recurring
 ()) %7B%0A  
@@ -1083,19 +1083,21 @@
    %7D
- else
+%0A       
  if (
-!
 this
@@ -1106,16 +1106,34 @@
 sEvent()
+ %5E other.isEvent()
 ) %7B%0A    
@@ -1138,32 +1138,73 @@
           return
+ false;%0A        %7D%0A        boolean state =
  other == this /
@@ -1242,36 +1242,32 @@
                 
-    
 %7C%7C (other != nul
@@ -1312,36 +1312,32 @@
                 
-    
 && checkEqual(th
@@ -1359,36 +1359,32 @@
 ther.getName())%0A
-    
                 
@@ -1438,36 +1438,32 @@
                 
-    
 && checkEqual(th
@@ -1501,36 +1501,32 @@
                 
-    
 && checkEqual(th
@@ -1546,36 +1546,32 @@
 other.getTag())%0A
-    
                 
@@ -1650,36 +1650,32 @@
                 
-    
 %7C%7C (other.getFin
@@ -1805,356 +1805,55 @@
     
-%7D else %7B%0A            return other == this // short circuit if same object%0A                    %7C%7C (other != null // 
+if (
 this
- is first to avoid NPE below%0A                    && checkEqual(this.getName(), other.getName())%0A                    && checkEqual(this.getDate(), other.getDate())%0A                    && checkEqual(this.getTime(), other.getTime())
+.isEvent()) %7B%0A            state = state
 %0A   
@@ -2066,32 +2066,33 @@
 .getStartTime())
+;
 %0A               
@@ -2100,136 +2100,192 @@
     
-&& checkEqual(this.getTag(), other.getTag())%0A                    && ((other.getFinished() == null &&
+// state checks here onwards%0A        %7D%0A        if (this.isRecurring()) %7B%0A            state = state%0A                    && ((((ReadOnlyRecurringTask)
  this
+)
 .get
-Finished() == null)
+RecurringPeriod()).equals(
 %0A   
@@ -2313,89 +2313,58 @@
     
-%7C%7C (other.getFinished() != null && other.getFinished().equals(
+((ReadOnlyRecurringTask) 
 this
+)
 .get
-Finished())
+RecurringPeriod(
 )));
@@ -2368,32 +2368,34 @@
 ));%0A        
+%7D%0A
         
     // state
@@ -2386,50 +2386,21 @@
     
-    // state checks here onwards%0A        %7D
+return state;
 %0A   

Refactor isSameState