package cnp.ew.util;
import java.util.Date;
/**
 * Adds additional functionality to the base Date class. One can
 * be created through all the usual Date constructors, or by
 * taking an existing Date, like so:
 * <pre>
      Date aDate = new Date("3/1/95");
 *    CpDate date = new CpDate(aDate);
 * </pre>
 *
 * @version        $Version$
 * @author         $Author: Ken $
 */
public class CpDate extends Date
{
    static final String[] longMonths = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    static final String[] shortMonths = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    static final String[] longDaysOfWeek = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    static final String[] shortDaysOfWeek = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

	static final int[] daysInMonths = { 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

    static final int daysBeforeCurrentMonth[] = {
        0,
        31,
        28 + 31,
        31 + 28 + 31,
        30 + 31 + 28 + 31,
        31 + 30 + 31 + 28 + 31,
        30 + 31 + 30 + 31 + 28 + 31,
        31 + 30 + 31 + 30 + 31 + 28 + 31,
        31 + 31 + 30 + 31 + 30 + 31 + 28 + 31,
        30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31,
        31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31,
        30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 28 + 31
    };

    /**
     * Creates a new CpDate, from the given date
     * @param aDate - the Date to build this from.
     */
    public CpDate(Date aDate)
    {
        super(aDate.getTime());
    }

    public CpDate(CpDate aDate)
    {
        super(aDate.getTime());
    }

    public CpDate()
    {
        this(new Date());
    }

    public Date getJavaDate()
    {
        return new Date(getTime());
    }

    /**
     * Answer this date's full month name.
     */
    public String getLongMonthName()
    {
        return longMonths[getMonth()];
    }

    /**
     * Answer this date's short (3 letter abbreviation) month name.
     */
    public String getShortMonthName()
    {
        return shortMonths[getMonth()];
    }

    /**
     * Answer the full name of this date's day of the week.
     */
    public String getLongDayOfWeekName()
    {
        return longDaysOfWeek[getDay()];
    }

    /**
     * Answer the short (3 letter abbreviation) name of this date's day of the week.
     */
    public String getShortDayOfWeekName()
    {
        return shortDaysOfWeek[getDay()];
    }

    /**
     * Answer the numeric calendar quarter for this date (1-4).
     */
    public int getQuarter()
    {
        int month = getMonth();
        if (month < 3) {
            return 1;
        }
        if (month < 6) {
            return 2;
        }
        if (month < 9) {
            return 3;
        }
        return 4;
    }

    /**
     * Answer the numeric day of the year for this date (1 to 366).
     */
    public int getDayOfYear()
    {
        int month, dayOfYear;

        month = getMonth();
        dayOfYear = daysBeforeCurrentMonth[month] + getDate();
        if ((month > 1) && (!isLeapYear())) {
            dayOfYear++;
        }
        return dayOfYear;
    }

    /**
     * Answer whether or not this date is in a leap year.
     */
    public boolean isLeapYear()
    {
        Date tempDate = new Date(getYear(), 1, 29);
		return tempDate.getMonth() != 1;
	}

	public int daysInCurrentMonth() {
		int daysInMonth;
		Date tempDate;

		daysInMonth = daysInMonths[getMonth()];
		if (daysInMonth > 0) {
			return daysInMonth;
		}

		// If it's February, check for leap year...
		if (!isLeapYear()) {
			return 29;
		} else {
			return 28;
		}
	}


    public void incrementHours()
    {
        int hours;

        if ((hours = getHours()) == 23) {
            setHours(0);
        } else {
            setHours(hours + 1);
        }
    }

    public void decrementHours()
    {
        int hours;

        if ((hours = getHours()) == 0) {
            setHours(23);
        } else {
            setHours(hours - 1);
        }
    }

    public void incrementMinutes()
    {
        int minutes;

        if ((minutes = getMinutes()) == 59) {
            setMinutes(0);
            incrementHours();
        } else {
            setMinutes(minutes + 1);
        }
    }

    public void decrementMinutes()
    {
        int minutes;

        if ((minutes = getMinutes()) == 0) {
            setMinutes(59);
            decrementHours();
        } else {
            setMinutes(minutes - 1);
        }
    }

    public void incrementSeconds()
    {
        int seconds;

        if ((seconds = getSeconds()) == 59) {
            setSeconds(0);
            incrementMinutes();
        } else {
            setSeconds(seconds + 1);
        }
    }

    public void decrementSeconds()
    {
        int seconds;

        if ((seconds = getSeconds()) == 0) {
            setSeconds(59);
            decrementMinutes();
        } else {
            setSeconds(seconds - 1);
        }
    }

    public void incrementDay()
    {
        int day;
        if ((day = getDate()) == daysInCurrentMonth()) {
            incrementMonth();
            setDate(1);
        } else {
            setDate(day + 1);
        }
    }

    public void decrementDay()
    {
        int day;
        if ((day = getDate()) == 1) {
            decrementMonth();
            setDate(daysInCurrentMonth());
        } else {
            setDate(day - 1);
        }
    }

    public void incrementMonth()
    {
        int month;

        if ((month = getMonth()) == 11) {
            setMonth(0);
            incrementYear();
        } else {
            setMonth(month + 1);
        }
        keepDayInBounds();
    }

    public void decrementMonth()
    {
        int month;
        if ((month = getMonth()) == 0) {
            setMonth(11);
            decrementYear();
        } else {
            setMonth(month - 1);
        }
        keepDayInBounds();
    }

    void keepDayInBounds() {
        int daysInMonth = daysInCurrentMonth();
        if (getDate() > daysInMonth) {
            setDate(daysInMonth);
        }
    }


    public void incrementYear()
    {
        setYear(getYear() + 1);
        keepDayInBounds();
    }

    public void decrementYear()
    {
        setYear(getYear() - 1);
        keepDayInBounds();
    }

    public int dayOfWeekIndexForStartOfMonth()
    {
        Date date = new Date(getYear(), getMonth(), 1);
        return date.getDay();
    }

    public void setMonth(int month)
    {
        int oldMonth = getMonth();
        super.setMonth(month);
        try {
            getTime();
        } catch (IllegalArgumentException e) {
            System.out.println(e);
            super.setMonth(oldMonth);
        }
    }

    public void setDate(int newDate)
    {
        int oldDate = getDate();
        super.setDate(newDate);
        try {
            getTime();
        } catch (IllegalArgumentException e) {
            System.out.println(e);
            super.setDate(oldDate);
        }
    }

    public void setYear(int newYear)
    {
        int oldYear = getYear();
        super.setYear(newYear);
        try {
            getTime();
        } catch (IllegalArgumentException e) {
            System.out.println(e);
            super.setYear(oldYear);
        }
    }
}


