package seedu.taskman.model.event;

import seedu.taskman.model.tag.UniqueTagList;

import java.util.Objects;
import java.util.Optional;

/**
 * Wrapper for both ReadOnlyEvent and ReadOnlyTask
 */
public class Activity implements ReadOnlyEvent{

    public enum ActivityType {EVENT, TASK};

    private ReadOnlyEvent activity;
    private ActivityType type;

    public Activity(ReadOnlyEvent event){
        activity = event;
        type = ActivityType.EVENT;
    }

    public Activity(ReadOnlyTask task){
        activity = task;
        type = ActivityType.TASK;
    }

    public Activity(Activity source){
        switch (source.getType()){
            case TASK:
                this.activity = new Task(source.getTask());
                break;
            case EVENT:
            default:
                this.activity = new Event(source.getEvent());
        }
        type = source.getType();
    }

    public ActivityType getType(){
        return type;
    }

    public ReadOnlyTask getTask(){
        assert type == ActivityType.TASK;
        return (ReadOnlyTask) activity;
    }

    public ReadOnlyEvent getEvent(){
        return activity;
    }

    public Optional<Status> getStatus() {
        switch(type){
            case TASK:
                return Optional.ofNullable(((ReadOnlyTask)activity).getStatus());
            case EVENT:
            default:
                return null;
        }
    }

    public Optional<Deadline> getDeadline() {
        switch(type){
            case TASK:
                return ((ReadOnlyTask)activity).getDeadline();
            case EVENT:
            default:
                return Optional.empty();
        }
    }

    @Override
    public Title getTitle() {
        return activity.getTitle();
    }

    @Override
    public Optional<Frequency> getFrequency() {
        return activity.getFrequency();
    }

    @Override
    public Optional<Schedule> getSchedule() {
        return activity.getSchedule();
    }

    @Override
    public UniqueTagList getTags() {
        return activity.getTags();
    }

    public boolean isSameStateAs(Activity other){
        if(type != other.type) return false;

        switch(type){
            case TASK:
                return getTask().isSameStateAs(other.getTask());
            case EVENT:
            default:
                return activity.isSameStateAs(other.activity);
        }
    }

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

    @Override
    public int hashCode() {
        // use this method for custom fields hashing instead of implementing your own
        return Objects.hash(
                getTitle(),
                getDeadline(),
                getStatus(),
                getFrequency(),
                getSchedule(),
                getTags()
        );
    }

    @Override
    public String getAsText() {
        return activity.getAsText();
    }

}

@@ -708,24 +708,38 @@
 ask(
-source.getTask()
+(ReadOnlyTask) source.activity
 );%0A 
@@ -983,32 +983,41 @@
   %7D%0A%0A    public 
+Optional%3C
 ReadOnlyTask get
@@ -1012,16 +1012,17 @@
 OnlyTask
+%3E
  getTask
@@ -1037,21 +1037,17 @@
     
-assert 
+if(
 type 
-=
+!
 = Ac
@@ -1065,25 +1065,85 @@
 TASK
-;%0A        return 
+)%7B%0A            return Optional.empty();%0A        %7D%0A        return Optional.of(
 (Rea
@@ -1153,32 +1153,33 @@
 lyTask) activity
+)
 ;%0A    %7D%0A%0A    pub
@@ -2320,47 +2320,75 @@
 urn 
-getTask().isSameStateAs(other.getTask()
+((ReadOnlyTask)activity).isSameStateAs((ReadOnlyTask)other.activity
 );%0A 

Replace return type of getTask