package seedu.taskboss.model.task;

import java.util.Date;

import seedu.taskboss.commons.exceptions.IllegalValueException;
import seedu.taskboss.logic.parser.DateTimeParser;

public class DateTime {

    public static final String MESSAGE_DATE_CONSTRAINTS = "Task dates format should be in dd-mm-yyyy,"
            + " or word format like 5pm tomorrow, " + "and does not accept doubles.";

    public final String value;
    private boolean isDateInferred;
    private boolean isTimeInferred;
    private Date date;
    private DateTimeParser dtParser;

    public DateTime(String date) throws IllegalValueException {
        assert date != null;

        this.dtParser = new DateTimeParser();
        this.isDateInferred = false;
        this.isTimeInferred = false;
        this.date = null;
        String trimmedDate = date.trim();
        if (!isValidDateTime(trimmedDate)) {
            throw new IllegalValueException(MESSAGE_DATE_CONSTRAINTS);
        }

        if (!trimmedDate.equals("")) {
            parseDateTime(trimmedDate);
        }
        this.value = date.toString();
    }

    public DateTime(Date dateTime, boolean isDateInferred, boolean isTimeInferred) {
        this.date = dateTime;
        this.isDateInferred = isDateInferred;
        this.isTimeInferred = isTimeInferred;
        value = this.date.toString();
    }

    /**
     * Returns if a given string is a valid date input.
     *
     * @throws IllegalValueException
     */
    public boolean isValidDateTime(String date) {
        if (date.equals("")) {
            return true;
        } else {
            return dtParser.isParseable(date);
        }
    }

    private void parseDateTime(String date) throws IllegalValueException {
        DateTime dateTime = dtParser.parseDate(date);
        this.date = dateTime.getDate();
        this.setIsDateInferred(dateTime.isDateInferred);
        this.setIsTimeInferred(dateTime.isTimeInferred);
    }

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

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

    @Override
    public int hashCode() {
        return value.hashCode();
    }

    public boolean IsDateInferred() {
        return isDateInferred;
    }

    public boolean IsTimeInferred() {
        return isTimeInferred;
    }

    public void setIsDateInferred(boolean status) {
        this.isDateInferred = status;
    }

    public void setIsTimeInferred(boolean status) {
        this.isTimeInferred = status;
    }

    public Date getDate() {
        return date;
    }

}

@@ -29,16 +29,51 @@
 .task;%0A%0A
+import java.text.SimpleDateFormat;%0A
 import j
@@ -417,16 +417,54 @@
 ubles.%22;
+%0A    private String EMPTY_STRING = %22%22;
 %0A%0A    pu
@@ -468,22 +468,16 @@
  public 
-final 
 String v
@@ -1036,17 +1036,16 @@
     if (
-!
 trimmedD
@@ -1047,39 +1047,105 @@
 mmedDate.equals(
-%22%22
+EMPTY_STRING
 )) %7B%0A
+            this.value = EMPTY_STRING;%0A        %7D else %7B%0A
             pars
@@ -1180,47 +1180,39 @@
     
-%7D%0A
     
-    this.value = date.toString();
+formatDateTime();%0A        %7D
 %0A   
@@ -1657,18 +1657,28 @@
 .equals(
-%22%22
+EMPTY_STRING
 )) %7B%0A   
@@ -2062,32 +2062,571 @@
 ferred);%0A    %7D%0A%0A
+    /**%0A     * Format the current natty-parsed date into a string of our intended format%0A     * i.e May 19, 2017 8:30 PM%0A     */%0A    private void formatDateTime() %7B%0A        SimpleDateFormat sdfGeneral = new SimpleDateFormat(%22MMM dd, yyyy hh:mm aa%22);%0A        SimpleDateFormat sdfToday = new SimpleDateFormat(%22MMM dd, yyyy%22);%0A        // No time provided by user%0A        if (this.IsTimeInferred()) %7B%0A            this.value = sdfToday.format(this.date);%0A        %7D else %7B%0A            this.value = sdfGeneral.format(this.date);%0A        %7D%0A    %7D%0A%0A
     @Override%0A  

Convert datetime into desired format::DateTime