package seedu.address.model.task;

import java.text.SimpleDateFormat;
import java.util.Date;

import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.model.parser.DeadlineParser;

/**
 * Represents a Task's deadline in the TaskManager.
 * Guarantees: immutable; is valid as declared in {@link #isValidDeadline(String)}
 */
public class Deadline {

    public enum DeadlineType {
        DATEONLY, DATETIME
    };

    public static final String MESSAGE_DEADLINE_CONSTRAINTS =
        "Task deadline should strictly follow this format DD/MM/YYYY";

    /**
     * Output format used to display deadline with both date and time.
     * Day, Month Date Year at Hour:Minute
     * Example: Tuesday, April 1 2013 at 23:59
     */
    public static final String READABLE_DATETIME_OUTPUT_FORMAT = "EEE, MMM dd yyyy, hh:mm aaa";

    /**
     * Output format used to display deadline with only date.
     * Day, Month Date Year
     * Example: Tuesday, April 1 2013
     */
    public static final String READABLE_DATEONLY_OUTPUT_FORMAT = "EEE, MMM dd yyyy";

    private final Date date;
    private final DeadlineType type;

    /**
     * Constructor for Deadline.
     */
    public Deadline(String dateString) throws IllegalValueException {
        assert dateString != null;
        // Trim and remove continuous whitespace
        String trimmedDateString = dateString.trim().replace(" +", " ");

        // Try date-only format
        if (DeadlineParser.isParsableDate(dateString)) {
            date = DeadlineParser.parseDateString(dateString);
            type = DeadlineType.DATEONLY;

        // Try time-only format
        } else if (DeadlineParser.isParsableTime(dateString)) {
            // The default date value to be assigned is today
            date = combineDateTime(new Date(), DeadlineParser.parseTimeString(dateString));
            type = DeadlineType.DATETIME;

        // Try complete date-time formats
        } else if (DeadlineParser.isParsableDateTime(dateString)) {
            date = DeadlineParser.parseDateTimeString(dateString);
            type = DeadlineType.DATETIME;

        } else {
            throw new IllegalValueException(MESSAGE_DEADLINE_CONSTRAINTS);
        }

    }

    /**
     * Validates given date.
     *
     * @throws IllegalValueException if given date string is invalid.
     */
    public static boolean isValidDeadline(String dateString) {
        return DeadlineParser.isParsable(dateString);
    }

    /**
     * Combine date and time from 2 different sources.
     */
    public static Date combineDateTime(Date date, Date time) {
        return new Date(date.getYear(), date.getMonth(), date.getDate(),
                        time.getHours(), time.getMinutes());
    }

    @Override
    public String toString() {
        switch (type) {
        case DATETIME:
            return new SimpleDateFormat(READABLE_DATETIME_OUTPUT_FORMAT).format(date);

        case DATEONLY:
            return new SimpleDateFormat(READABLE_DATEONLY_OUTPUT_FORMAT).format(date);

        default:
            return date.toString();
        }
    }

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

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

}

@@ -32,66 +32,8 @@
 k;%0A%0A
-import java.text.SimpleDateFormat;%0Aimport java.util.Date;%0A
 %0Aimp
@@ -123,29 +123,76 @@
 del.
-parser.DeadlineParser
+task.date.DateFactory;%0Aimport seedu.address.model.task.date.TaskDate
 ;%0A%0A/
@@ -362,74 +362,8 @@
  %7B%0A%0A
-    public enum DeadlineType %7B%0A        DATEONLY, DATETIME%0A    %7D;%0A%0A
     
@@ -496,1280 +496,311 @@
 %22;%0A%0A
-    /**%0A     * Output format used to display deadline with both date and time.%0A     * Day, Month Date Year at Hour:Minute%0A     * Example: Tuesday, April 1 2013 at 23:59%0A     */%0A    public static final String READABLE_DATETIME_OUTPUT_FORMAT = %22EEE, MMM dd yyyy, hh:mm aaa%22;%0A%0A    /**%0A     * Output format used to display deadline with only date.%0A     * Day, Month Date Year%0A     * Example: Tuesday, April 1 2013%0A     */%0A    public static final String READABLE_DATEONLY_OUTPUT_FORMAT = %22EEE, MMM dd yyyy%22;%0A%0A    private final Date date;%0A    private final DeadlineType type;%0A%0A    /**%0A     * Constructor for Deadline.%0A     */%0A    public Deadline(String dateString) throws IllegalValueException %7B%0A        assert dateString != null;%0A        // Trim and remove continuous whitespace%0A        String trimmedDateString = dateString.trim().replace(%22 +%22, %22 %22);%0A%0A        // Try date-only format%0A        if (DeadlineParser.isParsableDate(dateString)) %7B%0A            date = DeadlineParser.parseDateString(dateString);%0A            type = DeadlineType.DATEONLY;%0A%0A        // Try time-only format%0A        %7D else if (DeadlineParser.isParsableTime(dateString)) %7B%0A            // The default date value to be assigned is today%0A            date = combineDateTime(new Date(), DeadlineParser.parseTime
+%0A    private final TaskDate date;%0A%0A    /**%0A     * Constructor for Deadline.%0A     */%0A    public Deadline(String dateString) throws IllegalValueException %7B%0A        assert dateString != null;%0A%0A        DateFactory dateFactory = new DateFactory();%0A        try %7B%0A            date = dateFactory.getTaskDateFrom
 Stri
@@ -813,17 +813,16 @@
 eString)
-)
 ;%0A      
@@ -827,277 +827,41 @@
     
-    type = DeadlineType.DATETIME;%0A%0A        // Try complete date-time formats%0A        %7D else if (DeadlineParser.isParsableDateTime(dateString)) %7B%0A            date = DeadlineParser.parseDateTimeString(dateString);%0A            type = DeadlineType.DATETIME;%0A%0A        %7D else
+%7D catch (IllegalValueException e)
  %7B%0A 
@@ -948,138 +948,15 @@
   %7D%0A
-%0A
     %7D%0A%0A
-    /**%0A     * Validates given date.%0A     *%0A     * @throws IllegalValueException if given date string is invalid.%0A     */%0A
     
@@ -1026,648 +1026,299 @@
     
-return DeadlineParser.isParsable(dateString
+DateFactory dateFactory = new DateFactory(
 );%0A    
-%7D%0A%0A
     
-/**%0A     * Combine date and time from 2 different sources.
+try %7B
 %0A     
-*/%0A
     
-public static Date combineDateTime(Date date, Date time) %7B%0A        return new Date(date.getYear(), date.getMonth(), date.getDate(),%0A                        time.getHours(), time.getMinutes())
+   TaskDate date = dateFactory.getTaskDateFromString(dateString);%0A            return true
 ;%0A    
-%7D%0A%0A
     
-@Override%0A    public String toString() %7B%0A        switch (type) %7B%0A        case DATETIME:%0A            return new SimpleDateFormat(READABLE_DATETIME_OUTPUT_FORMAT).format(date);%0A%0A        case DATEONLY:
+%7D catch (IllegalValueException e) %7B%0A            return false;%0A        %7D
 %0A    
+%7D%0A%0A
     
-    return new SimpleDateFormat(READABLE_DATEONLY_OUTPUT_FORMAT).format(date);%0A%0A        default:%0A    
+@Override%0A    public String toString() %7B%0A
     
@@ -1345,26 +1345,16 @@
 ring();%0A
-        %7D%0A
     %7D%0A%0A 

Update Deadline