/*
 * Simple Date Class
 */

public class Date implements Comparable<Date> {
    private static final int[] DAYS = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    private final int month;   // month (between 1 and 12)
    private final int day;     // day   (between 1 and DAYS[month]
    private final int year;    // year
    
    /**
     * Initializes a new date from the month, day, and year.
     * @param month the month (between 1 and 12)
     * @param day the day (between 1 and 28-31, depending on the month)
     * @param year the year
     * @throws IllegalArgumentException if the date is invalid
     */
    public Date(int month, int day, int year) {
        if (!isValid(month, day, year)) {throw new IllegalArgumentException("Invalid date");}
        this.month = month;
        this.day   = day;
        this.year  = year;
    }
     /**
     * Initializes a new date from the month, day, and year.
     * @param date a string date in MM/DD/YYYY format. for example: "12/25/2014"
     * @throws IllegalArgumentException if the date is invalid
     */
    public Date(String date) {
        String s[] = date.split("/");
        int month = Integer.parseInt(s[0]);
        int day = Integer.parseInt(s[1]);
        int year = Integer.parseInt(s[2]);
        if (!isValid(month, day, year)) {throw new IllegalArgumentException("Invalid date");}
        this.month = month;
        this.day   = day;
        this.year  = year;
    }
    /**
     * @return month return the month
     */
    public int getMonth(){
        return month;
    }
    
    /**
     * @return year return the year
     */
    public int getYear(){
        return year;
    }
    /**
     * @return day return the day
     */
    public int getDay(){
        return day;
    }
    
    // is the given date valid?
    private static boolean isValid(int m, int d, int y) {
        if (m < 1 || m > 12)      {return false;}
        if (d < 1 || d > DAYS[m]) {return false;}
        if (m == 2 && d == 29 && !isLeapYear(y)) {return false;}
        return true;
    }
    
    /**
     * Is year y a leap year?
     * @return true if y is a leap year; false otherwise
     */
    private static boolean isLeapYear(int y) {
        if (y % 400 == 0) {return true;}
        if (y % 100 == 0) {return false;}
        return y % 4 == 0;
    }
    
    /**
     * Compare this date to that date.
     * @return { a negative integer, zero, or a positive integer }, depending
     *    on whether this date is { before, equal to, after } that date
     */
    @Override
    public int compareTo(Date that) {
        if (this.year  < that.year)  {return -1;}
        if (this.year  > that.year)  {return +1;}
        if (this.month < that.month) {return -1;}
        if (this.month > that.month) {return +1;}
        if (this.day   < that.day)   {return -1;}
        if (this.day   > that.day)   {return +1;}
        return 0;
    }
    
    /**
     * Return a string representation of this date.
     * @return the string representation in the foramt MM/DD/YYYY
     */
    @Override
    public String toString() {
        return month + "/" + day + "/" + year;
    }
    
}
