// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 1996-2014, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

package com.ibm.icu.util;

import java.util.Date;

/**
 * <b>Note:</b> The Holiday framework is a technology preview.
 * Despite its age, is still draft API, and clients should treat it as such.
 *
 * A Holiday subclass which represents holidays that occur
 * a fixed number of days before or after Easter.  Supports both the
 * Western and Orthodox methods for calculating Easter.
 * @draft ICU 2.8 (retainAll)
 * @provisional This API might change or be removed in a future release.
 */
public class EasterHoliday extends Holiday
{
    /**
     * Construct a holiday that falls on Easter Sunday every year
     *
     * @param name The name of the holiday
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    public EasterHoliday(String name)
    {
        super(name, new EasterRule(0, false));
    }

    /**
     * Construct a holiday that falls a specified number of days before
     * or after Easter Sunday each year.
     *
     * @param daysAfter The number of days before (-) or after (+) Easter
     * @param name      The name of the holiday
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    public EasterHoliday(int daysAfter, String name)
    {
        super(name, new EasterRule(daysAfter, false));
    }

    /**
     * Construct a holiday that falls a specified number of days before
     * or after Easter Sunday each year, using either the Western
     * or Orthodox calendar.
     *
     * @param daysAfter The number of days before (-) or after (+) Easter
     * @param orthodox  Use the Orthodox calendar?
     * @param name      The name of the holiday
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    public EasterHoliday(int daysAfter, boolean orthodox, String name)
    {
        super(name, new EasterRule(daysAfter, orthodox));
    }

    /**
     * Shrove Tuesday, aka Mardi Gras, 48 days before Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday SHROVE_TUESDAY  = new EasterHoliday(-48,    "Shrove Tuesday");

    /**
     * Ash Wednesday, start of Lent, 47 days before Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday ASH_WEDNESDAY   = new EasterHoliday(-47,    "Ash Wednesday");

    /**
     * Palm Sunday, 7 days before Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday PALM_SUNDAY     = new EasterHoliday( -7,    "Palm Sunday");

    /**
     * Maundy Thursday, 3 days before Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday MAUNDY_THURSDAY = new EasterHoliday( -3,    "Maundy Thursday");

    /**
     * Good Friday, 2 days before Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday GOOD_FRIDAY     = new EasterHoliday( -2,    "Good Friday");

    /**
     * Easter Sunday
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday EASTER_SUNDAY   = new EasterHoliday(  0,    "Easter Sunday");

    /**
     * Easter Monday, 1 day after Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday EASTER_MONDAY   = new EasterHoliday(  1,    "Easter Monday");

    /**
     * Ascension, 39 days after Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday ASCENSION       = new EasterHoliday( 39,    "Ascension");

    /**
     * Pentecost (aka Whit Sunday), 49 days after Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday PENTECOST       = new EasterHoliday( 49,    "Pentecost");

    /**
     * Whit Sunday (aka Pentecost), 49 days after Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday WHIT_SUNDAY     = new EasterHoliday( 49,    "Whit Sunday");

    /**
     * Whit Monday, 50 days after Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday WHIT_MONDAY     = new EasterHoliday( 50,    "Whit Monday");

    /**
     * Corpus Christi, 60 days after Easter
     * @draft ICU 2.8
     * @provisional This API might change or be removed in a future release.
     */
    static public final EasterHoliday CORPUS_CHRISTI  = new EasterHoliday( 60,    "Corpus Christi");
}

class EasterRule implements DateRule {
    public EasterRule(int daysAfterEaster, boolean isOrthodox) {
        this.daysAfterEaster = daysAfterEaster;
        if (isOrthodox) {
            calendar.setGregorianChange(new Date(Long.MAX_VALUE));
        }
    }

    /**
     * Return the first occurrence of this rule on or after the given date
     */
    @Override
    public Date firstAfter(Date start)
    {
        return doFirstBetween(start, null);
    }

    /**
     * Return the first occurrence of this rule on or after
     * the given start date and before the given end date.
     */
    @Override
    public Date firstBetween(Date start, Date end)
    {
        return doFirstBetween(start, end);
    }

    /**
     * Return true if the given Date is on the same day as Easter
     */
    @Override
    public boolean isOn(Date date)
    {
        synchronized(calendar) {
            calendar.setTime(date);
            int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);

            calendar.setTime(computeInYear(calendar.getTime(), calendar));

            return calendar.get(Calendar.DAY_OF_YEAR) == dayOfYear;
        }
    }

    /**
     * Return true if Easter occurs between the two dates given
     */
    @Override
    public boolean isBetween(Date start, Date end)
    {
        return firstBetween(start, end) != null; // TODO: optimize?
    }

    private Date doFirstBetween(Date start, Date end)
    {
        //System.out.println("doFirstBetween: start   = " + start.toString());
        //System.out.println("doFirstBetween: end     = " + end.toString());

        synchronized(calendar) {
            // Figure out when this holiday lands in the given year
            Date result = computeInYear(start, calendar);

         //System.out.println("                result  = " + result.toString());

            // We might have gotten a date that's in the same year as "start", but
            // earlier in the year.  If so, go to next year
            if (result.before(start))
            {
                calendar.setTime(start);
                calendar.get(Calendar.YEAR);    // JDK 1.1.2 bug workaround
                calendar.add(Calendar.YEAR, 1);

                //System.out.println("                Result before start, going to next year: "
                //                        + calendar.getTime().toString());

                result = computeInYear(calendar.getTime(), calendar);
                //System.out.println("                result  = " + result.toString());
            }

            if (end != null && !result.before(end)) {
                //System.out.println("Result after end, returning null");
                return null;
            }
            return result;
        }
    }

    /**
     * Compute the month and date on which this holiday falls in the year
     * containing the date "date".  First figure out which date Easter
     * lands on in this year, and then add the offset for this holiday to get
     * the right date.
     * <p>
     * The algorithm here is taken from the
     * <a href="http://www.faqs.org/faqs/calendars/faq/">Calendar FAQ</a>.
     */
    private Date computeInYear(Date date, GregorianCalendar cal)
    {
        if (cal == null) cal = calendar;

        synchronized(cal) {
            cal.setTime(date);

            int year = cal.get(Calendar.YEAR);
            int g = year % 19;  // "Golden Number" of year - 1
            int i = 0;          // # of days from 3/21 to the Paschal full moon
            int j = 0;          // Weekday (0-based) of Paschal full moon

            if (cal.getTime().after( cal.getGregorianChange()))
            {
                // We're past the Gregorian switchover, so use the Gregorian rules.
                int c = year / 100;
                int h = (c - c/4 - (8*c+13)/25 + 19*g + 15) % 30;
                i = h - (h/28)*(1 - (h/28)*(29/(h+1))*((21-g)/11));
                j = (year + year/4 + i + 2 - c + c/4) % 7;
            }
            else
            {
                // Use the old Julian rules.
                i = (19*g + 15) % 30;
                j = (year + year/4 + i) % 7;
            }
            int l = i - j;
            int m = 3 + (l+40)/44;              // 1-based month in which Easter falls
            int d = l + 28 - 31*(m/4);          // Date of Easter within that month

            cal.clear();
            cal.set(Calendar.ERA, GregorianCalendar.AD);
            cal.set(Calendar.YEAR, year);
            cal.set(Calendar.MONTH, m-1);       // 0-based
            cal.set(Calendar.DATE, d);
            cal.getTime();                      // JDK 1.1.2 bug workaround
            cal.add(Calendar.DATE, daysAfterEaster);

            return cal.getTime();
        }
    }

    private int               daysAfterEaster;
    private GregorianCalendar calendar = new GregorianCalendar();
}
