/*
 * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.util.calendar;

import java.util.Locale;
import java.util.TimeZone;

/**
 * The <code>BaseCalendar</code> provides basic calendar calculation
 * functions to support the Julian, Gregorian, and Gregorian-based
 * calendar systems.
 *
 * @author Masayoshi Okutsu
 * @since 1.5
 */

public abstract class BaseCalendar extends AbstractCalendar {

    public static final int JANUARY = 1;
    public static final int FEBRUARY = 2;
    public static final int MARCH = 3;
    public static final int APRIL = 4;
    public static final int MAY = 5;
    public static final int JUNE = 6;
    public static final int JULY = 7;
    public static final int AUGUST = 8;
    public static final int SEPTEMBER = 9;
    public static final int OCTOBER = 10;
    public static final int NOVEMBER = 11;
    public static final int DECEMBER = 12;

    // day of week constants
    public static final int SUNDAY = 1;
    public static final int MONDAY = 2;
    public static final int TUESDAY = 3;
    public static final int WEDNESDAY = 4;
    public static final int THURSDAY = 5;
    public static final int FRIDAY = 6;
    public static final int SATURDAY = 7;

    // The base Gregorian year of FIXED_DATES[]
    private static final int BASE_YEAR = 1970;

    // Pre-calculated fixed dates of January 1 from BASE_YEAR
    // (Gregorian). This table covers all the years that can be
    // supported by the POSIX time_t (32-bit) after the Epoch. Note
    // that the data type is int[].
    private static final int[] FIXED_DATES = {
        719163, // 1970
        719528, // 1971
        719893, // 1972
        720259, // 1973
        720624, // 1974
        720989, // 1975
        721354, // 1976
        721720, // 1977
        722085, // 1978
        722450, // 1979
        722815, // 1980
        723181, // 1981
        723546, // 1982
        723911, // 1983
        724276, // 1984
        724642, // 1985
        725007, // 1986
        725372, // 1987
        725737, // 1988
        726103, // 1989
        726468, // 1990
        726833, // 1991
        727198, // 1992
        727564, // 1993
        727929, // 1994
        728294, // 1995
        728659, // 1996
        729025, // 1997
        729390, // 1998
        729755, // 1999
        730120, // 2000
        730486, // 2001
        730851, // 2002
        731216, // 2003
        731581, // 2004
        731947, // 2005
        732312, // 2006
        732677, // 2007
        733042, // 2008
        733408, // 2009
        733773, // 2010
        734138, // 2011
        734503, // 2012
        734869, // 2013
        735234, // 2014
        735599, // 2015
        735964, // 2016
        736330, // 2017
        736695, // 2018
        737060, // 2019
        737425, // 2020
        737791, // 2021
        738156, // 2022
        738521, // 2023
        738886, // 2024
        739252, // 2025
        739617, // 2026
        739982, // 2027
        740347, // 2028
        740713, // 2029
        741078, // 2030
        741443, // 2031
        741808, // 2032
        742174, // 2033
        742539, // 2034
        742904, // 2035
        743269, // 2036
        743635, // 2037
        744000, // 2038
        744365, // 2039
    };

    public abstract static class Date extends CalendarDate {
        protected Date() {
            super();
        }
        protected Date(TimeZone zone) {
            super(zone);
        }

        public Date setNormalizedDate(int normalizedYear, int month, int dayOfMonth) {
            setNormalizedYear(normalizedYear);
            setMonth(month).setDayOfMonth(dayOfMonth);
            return this;
        }

        public abstract int getNormalizedYear();

        public abstract void setNormalizedYear(int normalizedYear);

        // Cache for the fixed date of January 1 and year length of the
        // cachedYear. A simple benchmark showed 7% performance
        // improvement with >90% cache hit. The initial values are for Gregorian.
        int cachedYear = 2004;
        long cachedFixedDateJan1 = 731581L;
        long cachedFixedDateNextJan1 = cachedFixedDateJan1 + 366;

        protected final boolean hit(int year) {
            return year == cachedYear;
        }

        protected final boolean hit(long fixedDate) {
            return (fixedDate >= cachedFixedDateJan1 &&
                    fixedDate < cachedFixedDateNextJan1);
        }
        protected int getCachedYear() {
            return cachedYear;
        }

        protected long getCachedJan1() {
            return cachedFixedDateJan1;
        }

        protected void setCache(int year, long jan1, int len) {
            cachedYear = year;
            cachedFixedDateJan1 = jan1;
            cachedFixedDateNextJan1 = jan1 + len;
        }
    }

    public boolean validate(CalendarDate date) {
        Date bdate = (Date) date;
        if (bdate.isNormalized()) {
            return true;
        }
        int month = bdate.getMonth();
        if (month < JANUARY || month > DECEMBER) {
            return false;
        }
        int d = bdate.getDayOfMonth();
        if (d <= 0 || d > getMonthLength(bdate.getNormalizedYear(), month)) {
            return false;
        }
        int dow = bdate.getDayOfWeek();
        if (dow != bdate.FIELD_UNDEFINED && dow != getDayOfWeek(bdate)) {
            return false;
        }

        if (!validateTime(date)) {
            return false;
        }

        bdate.setNormalized(true);
        return true;
    }

    public boolean normalize(CalendarDate date) {
        if (date.isNormalized()) {
            return true;
        }

        Date bdate = (Date) date;
        TimeZone zi = bdate.getZone();

        // If the date has a time zone, then we need to recalculate
        // the calendar fields. Let getTime() do it.
        if (zi != null) {
            getTime(date);
            return true;
        }

        int days = normalizeTime(bdate);
        normalizeMonth(bdate);
        long d = (long)bdate.getDayOfMonth() + days;
        int m = bdate.getMonth();
        int y = bdate.getNormalizedYear();
        int ml = getMonthLength(y, m);

        if (!(d > 0 && d <= ml)) {
            if (d <= 0 && d > -28) {
                ml = getMonthLength(y, --m);
                d += ml;
                bdate.setDayOfMonth((int) d);
                if (m == 0) {
                    m = DECEMBER;
                    bdate.setNormalizedYear(y - 1);
                }
                bdate.setMonth(m);
            } else if (d > ml && d < (ml + 28)) {
                d -= ml;
                ++m;
                bdate.setDayOfMonth((int)d);
                if (m > DECEMBER) {
                    bdate.setNormalizedYear(y + 1);
                    m = JANUARY;
                }
                bdate.setMonth(m);
            } else {
                long fixedDate = d + getFixedDate(y, m, 1, bdate) - 1L;
                getCalendarDateFromFixedDate(bdate, fixedDate);
            }
        } else {
            bdate.setDayOfWeek(getDayOfWeek(bdate));
        }
        date.setLeapYear(isLeapYear(bdate.getNormalizedYear()));
        date.setZoneOffset(0);
        date.setDaylightSaving(0);
        bdate.setNormalized(true);
        return true;
    }

    void normalizeMonth(CalendarDate date) {
        Date bdate = (Date) date;
        int year = bdate.getNormalizedYear();
        long month = bdate.getMonth();
        if (month <= 0) {
            long xm = 1L - month;
            year -= (int)((xm / 12) + 1);
            month = 13 - (xm % 12);
            bdate.setNormalizedYear(year);
            bdate.setMonth((int) month);
        } else if (month > DECEMBER) {
            year += (int)((month - 1) / 12);
            month = ((month - 1)) % 12 + 1;
            bdate.setNormalizedYear(year);
            bdate.setMonth((int) month);
        }
    }

    /**
     * Returns 366 if the specified date is in a leap year, or 365
     * otherwise This method does not perform the normalization with
     * the specified <code>CalendarDate</code>. The
     * <code>CalendarDate</code> must be normalized to get a correct
     * value.
     *
     * @param a <code>CalendarDate</code>
     * @return a year length in days
     * @throws ClassCastException if the specified date is not a
     * {@link BaseCalendar.Date}
     */
    public int getYearLength(CalendarDate date) {
        return isLeapYear(((Date)date).getNormalizedYear()) ? 366 : 365;
    }

    public int getYearLengthInMonths(CalendarDate date) {
        return 12;
    }

    static final int[] DAYS_IN_MONTH
        //  12   1   2   3   4   5   6   7   8   9  10  11  12
        = { 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    static final int[] ACCUMULATED_DAYS_IN_MONTH
        //  12/1 1/1 2/1 3/1 4/1 5/1 6/1 7/1 8/1 9/1 10/1 11/1 12/1
        = {  -30,  0, 31, 59, 90,120,151,181,212,243, 273, 304, 334};

    static final int[] ACCUMULATED_DAYS_IN_MONTH_LEAP
        //  12/1 1/1 2/1   3/1   4/1   5/1   6/1   7/1   8/1   9/1   10/1   11/1   12/1
        = {  -30,  0, 31, 59+1, 90+1,120+1,151+1,181+1,212+1,243+1, 273+1, 304+1, 334+1};

    public int getMonthLength(CalendarDate date) {
        Date gdate = (Date) date;
        int month = gdate.getMonth();
        if (month < JANUARY || month > DECEMBER) {
            throw new IllegalArgumentException("Illegal month value: " + month);
        }
        return getMonthLength(gdate.getNormalizedYear(), month);
    }

    // accepts 0 (December in the previous year) to 12.
    private final int getMonthLength(int year, int month) {
        int days = DAYS_IN_MONTH[month];
        if (month == FEBRUARY && isLeapYear(year)) {
            days++;
        }
        return days;
    }

    public long getDayOfYear(CalendarDate date) {
        return getDayOfYear(((Date)date).getNormalizedYear(),
                            date.getMonth(),
                            date.getDayOfMonth());
    }

    final long getDayOfYear(int year, int month, int dayOfMonth) {
        return (long) dayOfMonth
            + (isLeapYear(year) ?
               ACCUMULATED_DAYS_IN_MONTH_LEAP[month] : ACCUMULATED_DAYS_IN_MONTH[month]);
    }

    // protected
    public long getFixedDate(CalendarDate date) {
        if (!date.isNormalized()) {
            normalizeMonth(date);
        }
        return getFixedDate(((Date)date).getNormalizedYear(),
                            date.getMonth(),
                            date.getDayOfMonth(),
                            (BaseCalendar.Date) date);
    }

    // public for java.util.GregorianCalendar
    public long getFixedDate(int year, int month, int dayOfMonth, BaseCalendar.Date cache) {
        boolean isJan1 = month == JANUARY && dayOfMonth == 1;

        // Look up the one year cache
        if (cache != null && cache.hit(year)) {
            if (isJan1) {
                return cache.getCachedJan1();
            }
            return cache.getCachedJan1() + getDayOfYear(year, month, dayOfMonth) - 1;
        }

        // Look up the pre-calculated fixed date table
        int n = year - BASE_YEAR;
        if (n >= 0 && n < FIXED_DATES.length) {
            long jan1 = FIXED_DATES[n];
            if (cache != null) {
                cache.setCache(year, jan1, isLeapYear(year) ? 366 : 365);
            }
            return isJan1 ? jan1 : jan1 + getDayOfYear(year, month, dayOfMonth) - 1;
        }

        long prevyear = (long)year - 1;
        long days = dayOfMonth;

        if (prevyear >= 0) {
            days += (365 * prevyear)
                   + (prevyear / 4)
                   - (prevyear / 100)
                   + (prevyear / 400)
                   + ((367 * month - 362) / 12);
        } else {
            days += (365 * prevyear)
                   + CalendarUtils.floorDivide(prevyear, 4)
                   - CalendarUtils.floorDivide(prevyear, 100)
                   + CalendarUtils.floorDivide(prevyear, 400)
                   + CalendarUtils.floorDivide((367 * month - 362), 12);
        }

        if (month > FEBRUARY) {
            days -=  isLeapYear(year) ? 1 : 2;
        }

        // If it's January 1, update the cache.
        if (cache != null && isJan1) {
            cache.setCache(year, days, isLeapYear(year) ? 366 : 365);
        }

        return days;
    }

    /**
     * Calculates calendar fields and store them in the specified
     * <code>CalendarDate</code>.
     */
    // should be 'protected'
    public void getCalendarDateFromFixedDate(CalendarDate date,
                                             long fixedDate) {
        Date gdate = (Date) date;
        int year;
        long jan1;
        boolean isLeap;
        if (gdate.hit(fixedDate)) {
            year = gdate.getCachedYear();
            jan1 = gdate.getCachedJan1();
            isLeap = isLeapYear(year);
        } else {
            // Looking up FIXED_DATES[] here didn't improve performance
            // much. So we calculate year and jan1. getFixedDate()
            // will look up FIXED_DATES[] actually.
            year = getGregorianYearFromFixedDate(fixedDate);
            jan1 = getFixedDate(year, JANUARY, 1, null);
            isLeap = isLeapYear(year);
            // Update the cache data
            gdate.setCache (year, jan1, isLeap ? 366 : 365);
        }

        int priorDays = (int)(fixedDate - jan1);
        long mar1 = jan1 + 31 + 28;
        if (isLeap) {
            ++mar1;
        }
        if (fixedDate >= mar1) {
            priorDays += isLeap ? 1 : 2;
        }
        int month = 12 * priorDays + 373;
        if (month > 0) {
            month /= 367;
        } else {
            month = CalendarUtils.floorDivide(month, 367);
        }
        long month1 = jan1 + ACCUMULATED_DAYS_IN_MONTH[month];
        if (isLeap && month >= MARCH) {
            ++month1;
        }
        int dayOfMonth = (int)(fixedDate - month1) + 1;
        int dayOfWeek = getDayOfWeekFromFixedDate(fixedDate);
        assert dayOfWeek > 0 : "negative day of week " + dayOfWeek;
        gdate.setNormalizedYear(year);
        gdate.setMonth(month);
        gdate.setDayOfMonth(dayOfMonth);
        gdate.setDayOfWeek(dayOfWeek);
        gdate.setLeapYear(isLeap);
        gdate.setNormalized(true);
    }

    /**
     * Returns the day of week of the given Gregorian date.
     */
    public int getDayOfWeek(CalendarDate date) {
        long fixedDate = getFixedDate(date);
        return getDayOfWeekFromFixedDate(fixedDate);
    }

    public static final int getDayOfWeekFromFixedDate(long fixedDate) {
        // The fixed day 1 (January 1, 1 Gregorian) is Monday.
        if (fixedDate >= 0) {
            return (int)(fixedDate % 7) + SUNDAY;
        }
        return (int)CalendarUtils.mod(fixedDate, 7) + SUNDAY;
    }

    public int getYearFromFixedDate(long fixedDate) {
        return getGregorianYearFromFixedDate(fixedDate);
    }

    /**
     * Returns the Gregorian year number of the given fixed date.
     */
    final int getGregorianYearFromFixedDate(long fixedDate) {
        long d0;
        int  d1, d2, d3, d4;
        int  n400, n100, n4, n1;
        int  year;

        if (fixedDate > 0) {
            d0 = fixedDate - 1;
            n400 = (int)(d0 / 146097);
            d1 = (int)(d0 % 146097);
            n100 = d1 / 36524;
            d2 = d1 % 36524;
            n4 = d2 / 1461;
            d3 = d2 % 1461;
            n1 = d3 / 365;
            d4 = (d3 % 365) + 1;
        } else {
            d0 = fixedDate - 1;
            n400 = (int)CalendarUtils.floorDivide(d0, 146097L);
            d1 = (int)CalendarUtils.mod(d0, 146097L);
            n100 = CalendarUtils.floorDivide(d1, 36524);
            d2 = CalendarUtils.mod(d1, 36524);
            n4 = CalendarUtils.floorDivide(d2, 1461);
            d3 = CalendarUtils.mod(d2, 1461);
            n1 = CalendarUtils.floorDivide(d3, 365);
            d4 = CalendarUtils.mod(d3, 365) + 1;
        }
        year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
        if (!(n100 == 4 || n1 == 4)) {
            ++year;
        }
        return year;
    }

    /**
     * @return true if the specified year is a Gregorian leap year, or
     * false otherwise.
     * @see BaseCalendar#isGregorianLeapYear
     */
    protected boolean isLeapYear(CalendarDate date) {
        return isLeapYear(((Date)date).getNormalizedYear());
    }

    boolean isLeapYear(int normalizedYear) {
        return CalendarUtils.isGregorianLeapYear(normalizedYear);
    }
}
