package seedu.ezdo.model.todo;

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

import com.joestelmach.natty.DateGroup;
import com.joestelmach.natty.Parser;

/**
 * Represents the date associated with tasks.
 */
public abstract class TaskDate {

    public String value;

    public static final String TASKDATE_VALIDATION_REGEX = "^$|(0[1-9]|[12][0-9]|3[01])[/](0[1-9]|1[012])[/](19|20)[0-9]{2} (2[0-3]|[0-1][0-9])[:][0-5][0-9]";
    public static final String USER_DATE_INPUT_FORMAT = "dd/MM/yyyy";
    public static final String USER_DATE_OUTPUT_FORMAT = "dd/MM/yyyy H:mm";
    public static final String NATTY_DATE_FORMAT = "EEE MMM dd hh:mm:ss zzz yyyy";

    public final SimpleDateFormat userInputDateFormat = new SimpleDateFormat(USER_DATE_INPUT_FORMAT);
    public final SimpleDateFormat userOutputDateFormat = new SimpleDateFormat(USER_DATE_OUTPUT_FORMAT);
    public final SimpleDateFormat nattyDateFormat = new SimpleDateFormat(NATTY_DATE_FORMAT);
    
    public TaskDate(String taskDate) {
        try {
	    // Format input string to suit Natty dependency
	    String formattedInitialTaskDate = changeToNattyDateFormat(taskDate);
	    this.value = nattyManipulation(formattedInitialTaskDate);
        } catch (ParseException pe) {
            this.value = nattyManipulation(taskDate);
        }
    }

    /**
     * Uses Natty dependency (natural language date parser) to manipulate date
     * input in String.
     */
    private String nattyManipulation(String taskDate) {
 
	try {
            // Initialises Natty parser
            Parser parser = new Parser();

            // Parses input String into a list of DateGroups
            List<DateGroup> dateGroupList = parser.parse(taskDate);

            // Retrieves parsed date
            Date parsedDate = dateGroupList.get(0).getDates().get(0);

            // Format parsed date to suit the UI
            String formattedFinalTaskDate = userOutputDateFormat.format(parsedDate);
            
            return formattedFinalTaskDate;
            
	} catch (IndexOutOfBoundsException e) {
	    return taskDate;
	}

    }

    /**
     * Changes the initial date format of a string input for Natty.
     */
    private String changeToNattyDateFormat(String input) throws ParseException {

	String output = new String();
	Date userDateObject = userInputDateFormat.parse(input);
	output = nattyDateFormat.format(userDateObject);

	return output;
    }

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

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

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

    /**
     * Returns true if a given string is a valid task date.
     */
    public static boolean isValidTaskDate(String test) {
	return test.matches(TASKDATE_VALIDATION_REGEX);
    }
}

@@ -1020,20 +1020,16 @@
 ORMAT);%0A
-    
 %0A    pub
@@ -1074,17 +1074,24 @@
   try %7B%0A
-%09
+        
     // F
@@ -1134,17 +1134,24 @@
 endency%0A
-%09
+        
     Stri
@@ -1215,17 +1215,24 @@
 kDate);%0A
-%09
+        
     this
@@ -1569,19 +1569,25 @@
 Date) %7B%0A
- %0A%09
+%0A        
 try %7B%0A  
@@ -2039,28 +2039,16 @@
 dDate);%0A
-            
 %0A       
@@ -2083,28 +2083,25 @@
 skDate;%0A
-    
+%0A
         
 %0A%09%7D catc
@@ -2092,18 +2092,16 @@
         
-%0A%09
 %7D catch 
@@ -2132,17 +2132,24 @@
 on e) %7B%0A
-%09
+        
     retu
@@ -2161,17 +2161,24 @@
 skDate;%0A
-%09
+        
 %7D%0A%0A    %7D
@@ -2345,17 +2345,24 @@
 tion %7B%0A%0A
-%09
+        
 String o
@@ -2383,17 +2383,24 @@
 ring();%0A
-%09
+        
 Date use
@@ -2447,17 +2447,24 @@
 input);%0A
-%09
+        
 output =
@@ -2505,17 +2505,24 @@
 ject);%0A%0A
-%09
+        
 return o
@@ -2576,25 +2576,32 @@
 oString() %7B%0A
-%09
+        
 return value
@@ -2661,25 +2661,32 @@
 ct other) %7B%0A
-%09
+        
 return other
@@ -2726,18 +2726,32 @@
  object%0A
-%09%09
+                
 %7C%7C (othe
@@ -2800,19 +2800,40 @@
 s nulls%0A
-%09%09%09
+                        
 && this.
@@ -2886,17 +2886,80 @@
 ate%0A
-%09%09%09%09%09%09%09%09%09
+                                                                        
  // 
@@ -3009,25 +3009,32 @@
 ashCode() %7B%0A
-%09
+        
 return value
@@ -3190,9 +3190,16 @@
 ) %7B%0A
-%09
+        
 retu

Correct formatting errors in TaskDate.java