/*
 *******************************************************************************
 * 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.getDefault(), 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.getDefault(), 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 = 365 * (year - 1) + floorDivide(8 * year + 21, 33);
        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";
    }
}
