// © 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;
import java.util.Locale;

import com.ibm.icu.util.ULocale.Category;

/**
 * <code>PersianCalendar</code> is a subclass of <code>Calendar</code> that
 * that implements the Persian calendar.  It is used as the main civil
 * calendar in Iran and Afghanistan, and by Iranians and Afghans worldwide.
 * <p>
 * The Persian calendar is solar, and is similar to the Gregorian calendar
 * in various ways, except its leap year rule, which is determined
 * astronomically.  The Persian year starts around the March equinox.
 * <p>
 * The modern Persian calendar (used in Iran since 1925 CE and in
 * Afghanistan since 1957 CE), has the lengths of the months fixed.  The
 * first six months are 31 days each, the next five months are 30 days each,
 * and the final month is 29 days in non-leap years and 30 days in leap
 * ones.  Historically, the lengths of the month differed in different
 * years, but they were finally fixed at the times mentioned above.  Partial
 * information is available about the historical lengths.
 * <p>
 * The official rule for determination of the beginning of the Persian year
 * is locale dependent, but at the same time, it has not specified a locale. 
 * Iranians around the world traditionally follow the calendar authorities
 * of Iran, which haven't officially specified the locale.  Some
 * calendarists use some point in Tehran as the locale, while others have
 * tried the more neutral 52.5 degrees east meridian.  It is not clear which
 * locale should be used for the Persian calendar of Afghanistan, but it is
 * expected that for about one year in every twenty-four years, the Afghan
 * calendar may become different from the Iranian one.
 * <p> 
 * The exact locale to be used for the Iranian calendar starts to make a
 * difference at around 2090 CE.  The specific arithmetic method implemented
 * here, commonly known as the 33-year cycle rule, matches the astronomical
 * calendar at least for the whole period that the calendar has been both
 * well-defined and official, from 1925 to around 2090 CE.  The other
 * commonly known algorithm, the 2820-year cycle, has been incorrectly
 * designed to follow the tropical year instead of the spring equinoctial
 * year, and fails to match the astronomical one as early as 2025 CE.
 * <p>
 * This class should not be subclassed.</p>
 * <p>
 * PersianCalendar usually should be instantiated using
 * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a
 * <code>ULocale</code> with the tag <code>"@calendar=persian"</code>.</p>
 *
 * @see com.ibm.icu.util.GregorianCalendar
 * @see com.ibm.icu.util.Calendar
 *
 * @author Roozbeh Pournader
 *
 * @internal
 * @deprecated This API is ICU internal only.
 */
@Deprecated
public class PersianCalendar extends Calendar {
    private static final long serialVersionUID = -6727306982975111643L;

    //-------------------------------------------------------------------------
    // Constants...
    //-------------------------------------------------------------------------
    
    private static final int[][] MONTH_COUNT = {
        //len len2   st
        {  31,  31,   0 }, // Farvardin
        {  31,  31,  31 }, // Ordibehesht
        {  31,  31,  62 }, // Khordad
        {  31,  31,  93 }, // Tir
        {  31,  31, 124 }, // Mordad
        {  31,  31, 155 }, // Shahrivar
        {  30,  30, 186 }, // Mehr
        {  30,  30, 216 }, // Aban
        {  30,  30, 246 }, // Azar
        {  30,  30, 276 }, // Dey
        {  30,  30, 306 }, // Bahman
        {  29,  30, 336 }  // Esfand
        // len  length of month
        // len2 length of month in a leap year
        // st   days in year before start of month
    };
    
    private static final int PERSIAN_EPOCH = 1948320;

    //-------------------------------------------------------------------------
    // Constructors...
    //-------------------------------------------------------------------------

    /**
     * Constructs a default <code>PersianCalendar</code> using the current time
     * in the default time zone with the default <code>FORMAT</code> locale.
     * @see Category#FORMAT
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar()
    {
        this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
    }

    /**
     * Constructs a <code>PersianCalendar</code> based on the current time
     * in the given time zone with the default <code>FORMAT</code> locale.
     * @param zone the given time zone.
     * @see Category#FORMAT
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar(TimeZone zone)
    {
        this(zone, ULocale.getDefault(Category.FORMAT));
    }

    /**
     * Constructs a <code>PersianCalendar</code> based on the current time
     * in the default time zone with the given locale.
     *
     * @param aLocale the given locale.
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar(Locale aLocale)
    {
        this(TimeZone.forLocaleOrDefault(aLocale), aLocale);
    }

    /**
     * Constructs a <code>PersianCalendar</code> based on the current time
     * in the default time zone with the given locale.
     *
     * @param locale the given ulocale.
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar(ULocale locale)
    {
        this(TimeZone.forULocaleOrDefault(locale), locale);
    }

    /**
     * Constructs a <code>PersianCalendar</code> based on the current time
     * in the given time zone with the given locale.
     *
     * @param zone the given time zone.
     * @param aLocale the given locale.
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar(TimeZone zone, Locale aLocale)
    {
        super(zone, aLocale);
        setTimeInMillis(System.currentTimeMillis());
    }

    /**
     * Constructs a <code>PersianCalendar</code> based on the current time
     * in the given time zone with the given locale.
     *
     * @param zone the given time zone.
     * @param locale the given ulocale.
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar(TimeZone zone, ULocale locale)
    {
        super(zone, locale);
        setTimeInMillis(System.currentTimeMillis());
    }

    /**
     * Constructs a <code>PersianCalendar</code> with the given date set
     * in the default time zone with the default <code>FORMAT</code> locale.
     *
     * @param date      The date to which the new calendar is set.
     * @see Category#FORMAT
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar(Date date) {
        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
        this.setTime(date);
    }

    /**
     * Constructs a <code>PersianCalendar</code> with the given date set
     * in the default time zone with the default <code>FORMAT</code> locale.
     *
     * @param year the value used to set the {@link #YEAR YEAR} time field in the calendar.
     * @param month the value used to set the {@link #MONTH MONTH} time field in the calendar.
     *              Note that the month value is 0-based. e.g., 0 for Farvardin.
     * @param date the value used to set the {@link #DATE DATE} time field in the calendar.
     * @see Category#FORMAT
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar(int year, int month, int date)
    {
        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
        this.set(Calendar.YEAR, year);
        this.set(Calendar.MONTH, month);
        this.set(Calendar.DATE, date);
    }

    /**
     * Constructs a <code>PersianCalendar</code> with the given date
     * and time set for the default time zone with the default <code>FORMAT</code> locale.
     *
     * @param year  the value used to set the {@link #YEAR YEAR} time field in the calendar.
     * @param month the value used to set the {@link #MONTH MONTH} time field in the calendar.
     *              Note that the month value is 0-based. e.g., 0 for Farvardin.
     * @param date  the value used to set the {@link #DATE DATE} time field in the calendar.
     * @param hour  the value used to set the {@link #HOUR_OF_DAY HOUR_OF_DAY} time field
     *              in the calendar.
     * @param minute the value used to set the {@link #MINUTE MINUTE} time field
     *              in the calendar.
     * @param second the value used to set the {@link #SECOND SECOND} time field
     *              in the calendar.
     * @see Category#FORMAT
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public PersianCalendar(int year, int month, int date, int hour,
                           int minute, int second)
    {
        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
        this.set(Calendar.YEAR, year);
        this.set(Calendar.MONTH, month);
        this.set(Calendar.DATE, date);
        this.set(Calendar.HOUR_OF_DAY, hour);
        this.set(Calendar.MINUTE, minute);
        this.set(Calendar.SECOND, second);
    }

    //-------------------------------------------------------------------------
    // Minimum / Maximum access functions
    //-------------------------------------------------------------------------

    private static final int LIMITS[][] = {
        // Minimum  Greatest     Least   Maximum
        //           Minimum   Maximum
        {        0,        0,        0,        0}, // ERA
        { -5000000, -5000000,  5000000,  5000000}, // YEAR
        {        0,        0,       11,       11}, // MONTH
        {        1,        1,       52,       53}, // WEEK_OF_YEAR
        {/*                                   */}, // WEEK_OF_MONTH
        {        1,        1,       29,       31}, // DAY_OF_MONTH
        {        1,        1,      365,      366}, // DAY_OF_YEAR
        {/*                                   */}, // DAY_OF_WEEK
        {       -1,       -1,        5,        5}, // DAY_OF_WEEK_IN_MONTH
        {/*                                   */}, // AM_PM
        {/*                                   */}, // HOUR
        {/*                                   */}, // HOUR_OF_DAY
        {/*                                   */}, // MINUTE
        {/*                                   */}, // SECOND
        {/*                                   */}, // MILLISECOND
        {/*                                   */}, // ZONE_OFFSET
        {/*                                   */}, // DST_OFFSET
        { -5000000, -5000000,  5000000,  5000000}, // YEAR_WOY
        {/*                                   */}, // DOW_LOCAL
        { -5000000, -5000000,  5000000,  5000000}, // EXTENDED_YEAR
        {/*                                   */}, // JULIAN_DAY
        {/*                                   */}, // MILLISECONDS_IN_DAY
    };

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected int handleGetLimit(int field, int limitType) {
        return LIMITS[field][limitType];
    }

    //-------------------------------------------------------------------------
    // Assorted calculation utilities
    //

    /**
     * Determine whether a year is a leap year in the Persian calendar
     */
    private final static boolean isLeapYear(int year)
    {
        int[] remainder = new int[1];
        floorDivide(25 * year + 11, 33, remainder);
        return remainder[0] < 8;
        
    }

    //----------------------------------------------------------------------
    // Calendar framework
    //----------------------------------------------------------------------

    /**
     * Return the length (in days) of the given month.
     *
     * @param extendedYear  The Persian year
     * @param month The Persian month, 0-based
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected int handleGetMonthLength(int extendedYear, int month) {
        // If the month is out of range, adjust it into range, and
        // modify the extended year value accordingly.
        if (month < 0 || month > 11) {
            int[] rem = new int[1];
            extendedYear += floorDivide(month, 12, rem);
            month = rem[0];
        }

        return MONTH_COUNT[month][isLeapYear(extendedYear)?1:0];
    }

    /**
     * Return the number of days in the given Persian year
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected int handleGetYearLength(int extendedYear) {
        return isLeapYear(extendedYear) ? 366 : 365;
    }
    
    //-------------------------------------------------------------------------
    // Functions for converting from field values to milliseconds....
    //-------------------------------------------------------------------------

    /**
     * Return JD of start of given month/year
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected int handleComputeMonthStart(int eyear, int month, boolean useMonth) {
        // If the month is out of range, adjust it into range, and
        // modify the extended year value accordingly.
        if (month < 0 || month > 11) {
            int[] rem = new int[1];
            eyear += floorDivide(month, 12, rem);
            month = rem[0];
        }

        int julianDay = PERSIAN_EPOCH - 1 + 365 * (eyear - 1) + floorDivide(8 * eyear + 21, 33);
        if (month != 0) {
            julianDay += MONTH_COUNT[month][2];
        }
        return julianDay;
    }    

    //-------------------------------------------------------------------------
    // Functions for converting from milliseconds to field values
    //-------------------------------------------------------------------------

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected int handleGetExtendedYear() {
        int year;
        if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR) {
            year = internalGet(EXTENDED_YEAR, 1); // Default to year 1
        } else {
            year = internalGet(YEAR, 1); // Default to year 1
        }
        return year;
    }

    /**
     * Override Calendar to compute several fields specific to the Persian
     * calendar system.  These are:
     *
     * <ul><li>ERA
     * <li>YEAR
     * <li>MONTH
     * <li>DAY_OF_MONTH
     * <li>DAY_OF_YEAR
     * <li>EXTENDED_YEAR</ul>
     * 
     * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
     * method is called.
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected void handleComputeFields(int julianDay) {
        int year, month, dayOfMonth, dayOfYear;

        long daysSinceEpoch = julianDay - PERSIAN_EPOCH;
        year = 1 + (int) floorDivide(33 * daysSinceEpoch + 3, 12053);

        long farvardin1 = 365L * (year - 1L) + floorDivide(8L * year + 21, 33L);
        dayOfYear = (int)(daysSinceEpoch - farvardin1); // 0-based
        if (dayOfYear < 216) { // Compute 0-based month
            month = dayOfYear / 31;
        } else {
            month = (dayOfYear - 6) / 30;
        }
        dayOfMonth = dayOfYear - MONTH_COUNT[month][2] + 1;
        ++dayOfYear; // Make it 1-based now
        
        internalSet(ERA, 0);
        internalSet(YEAR, year);
        internalSet(EXTENDED_YEAR, year);
        internalSet(MONTH, month);
        internalSet(DAY_OF_MONTH, dayOfMonth);
        internalSet(DAY_OF_YEAR, dayOfYear);       
    }    

    /**
     * {@inheritDoc}
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public String getType() {
        return "persian";
    }
}
