/*
 *******************************************************************************
 * Copyright (C) 1996-2010,2012, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.util;
import java.util.Date;
import java.util.Locale;

/**
 * <code>JapaneseCalendar</code> is a subclass of <code>GregorianCalendar</code>
 * that numbers years and eras based on the reigns of the Japanese emperors.
 * The Japanese calendar is identical to the Gregorian calendar in all respects
 * except for the year and era.  The ascension of each  emperor to the throne
 * begins a new era, and the years of that era are numbered starting with the
 * year of ascension as year 1.
 * <p>
 * Note that in the year of an imperial ascension, there are two possible sets
 * of year and era values: that for the old era and for the new.  For example, a
 * new era began on January 7, 1989 AD.  Strictly speaking, the first six days
 * of that year were in the Showa era, e.g. "January 6, 64 Showa", while the rest
 * of the year was in the Heisei era, e.g. "January 7, 1 Heisei".  This class
 * handles this distinction correctly when computing dates.  However, in lenient
 * mode either form of date is acceptable as input. 
 * <p>
 * In modern times, eras have started on January 8, 1868 AD, Gregorian (Meiji),
 * July 30, 1912 (Taisho), December 25, 1926 (Showa), and January 7, 1989 (Heisei).  Constants
 * for these eras, suitable for use in the <code>ERA</code> field, are provided
 * in this class.  Note that the <em>number</em> used for each era is more or
 * less arbitrary.  Currently, the era starting in 1053 AD is era #0; however this
 * may change in the future as we add more historical data.  Use the predefined
 * constants rather than using actual, absolute numbers.
 * <p>
 * This class should not be subclassed.</p>
 * <p>
 * JapaneseCalendar usually should be instantiated using 
 * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a <code>ULocale</code>
 * with the tag <code>"@calendar=japanese"</code>.</p>
 *
 * @see com.ibm.icu.util.GregorianCalendar
 * @see com.ibm.icu.util.Calendar
 *
 * @author Laura Werner
 * @author Alan Liu
 * @stable ICU 2.8
 */
public class JapaneseCalendar extends GregorianCalendar {
    // jdk1.4.2 serialver
    private static final long serialVersionUID = -2977189902603704691L;

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

    /**
     * Constructs a default <code>JapaneseCalendar</code> using the current time
     * in the default time zone with the default locale.
     * @stable ICU 2.8
     */
    public JapaneseCalendar() {
        super();
    }

    /**
     * Constructs a <code>JapaneseCalendar</code> based on the current time
     * in the given time zone with the default locale.
     * @param zone the given time zone.
     * @stable ICU 2.8
     */
    public JapaneseCalendar(TimeZone zone) {
        super(zone);
    }

    /**
     * Constructs a <code>JapaneseCalendar</code> based on the current time
     * in the default time zone with the given locale.
     * @param aLocale the given locale.
     * @stable ICU 2.8
     */
    public JapaneseCalendar(Locale aLocale) {
        super(aLocale);
    }

    /**
     * Constructs a <code>JapaneseCalendar</code> based on the current time
     * in the default time zone with the given locale.
     * @param locale the given ulocale.
     * @stable ICU 3.2
     */
    public JapaneseCalendar(ULocale locale) {
        super(locale);
    }

    /**
     * Constructs a <code>JapaneseCalendar</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.
     * @stable ICU 2.8
     */
    public JapaneseCalendar(TimeZone zone, Locale aLocale) {
        super(zone, aLocale);
    }

    /**
     * Constructs a <code>JapaneseCalendar</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.
     * @stable ICU 3.2
     */
    public JapaneseCalendar(TimeZone zone, ULocale locale) {
        super(zone, locale);
    }

    /**
     * Constructs a <code>JapaneseCalendar</code> with the given date set
     * in the default time zone with the default locale.
     *
     * @param date      The date to which the new calendar is set.
     * @stable ICU 2.8
     */
    public JapaneseCalendar(Date date) {
        this();
        setTime(date);
    }

    /**
     * Constructs a <code>JapaneseCalendar</code> with the given date set
     * in the default time zone with the default locale.
     *
     * @param era       The imperial era used to set the calendar's {@link #ERA ERA} field.
     *                  Eras are numbered starting with the Tenki era, which
     *                  began in 1053 AD Gregorian, as era zero.  Recent
     *                  eras can be specified using the constants
     *                  {@link #MEIJI} (which started in 1868 AD),
     *                  {@link #TAISHO} (1912 AD),
     *                  {@link #SHOWA} (1926 AD), and
     *                  {@link #HEISEI} (1989 AD).
     *
     * @param year      The value used to set the calendar's {@link #YEAR YEAR} field,
     *                  in terms of the era.
     *
     * @param month     The value used to set the calendar's {@link #MONTH MONTH} field.
     *                  The value is 0-based. e.g., 0 for January.
     *
     * @param date      The value used to set the calendar's DATE field.
     * @stable ICU 2.8
     */
    public JapaneseCalendar(int era, int year, int month, int date) {
        super(year, month, date);
        set(ERA, era);
    }

    /**
     * Constructs a <code>JapaneseCalendar</code> with the given date set
     * in the default time zone with the default locale.
     *
     * @param year      The value used to set the calendar's {@link #YEAR YEAR} field,
     *                  in the era Heisei, the most current at the time this
     *                  class was last updated.
     *
     * @param month     The value used to set the calendar's {@link #MONTH MONTH} field.
     *                  The value is 0-based. e.g., 0 for January.
     *
     * @param date      The value used to set the calendar's {@link #DATE DATE} field.
     * @stable ICU 2.8
     */
    public JapaneseCalendar(int year, int month, int date) {
        super(year, month, date);
        set(ERA, CURRENT_ERA);
    }

    /**
     * Constructs a <code>JapaneseCalendar</code> with the given date
     * and time set for the default time zone with the default locale.
     *
     * @param year      The value used to set the calendar's {@link #YEAR YEAR} time field,
     *                  in the era Heisei, the most current at the time of this
     *                  writing.
     *
     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
     *                  The value is 0-based. e.g., 0 for January.
     *
     * @param date      The value used to set the calendar's {@link #DATE DATE} time field.
     *
     * @param hour      The value used to set the calendar's {@link #HOUR_OF_DAY HOUR_OF_DAY} time field.
     *
     * @param minute    The value used to set the calendar's {@link #MINUTE MINUTE} time field.
     *
     * @param second    The value used to set the calendar's {@link #SECOND SECOND} time field.
     * @stable ICU 2.8
     */
    public JapaneseCalendar(int year, int month, int date, int hour,
                             int minute, int second)
    {
        super(year, month, date, hour, minute, second);
        set(ERA, CURRENT_ERA);
    }

    //-------------------------------------------------------------------------

    // Use 1970 as the default value of EXTENDED_YEAR
    private static final int GREGORIAN_EPOCH = 1970;

    /**
     * @stable ICU 2.8
     */
    protected int handleGetExtendedYear() {
        // EXTENDED_YEAR in JapaneseCalendar is a Gregorian year
        // The default value of EXTENDED_YEAR is 1970 (Showa 45)
        int year;
        if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR &&
            newerField(EXTENDED_YEAR, ERA) == EXTENDED_YEAR) {
            year = internalGet(EXTENDED_YEAR, GREGORIAN_EPOCH);
        } else {
            // extended year is a gregorian year, where 1 = 1AD,  0 = 1BC, -1 = 2BC, etc 
            year = internalGet(YEAR, 1)                       // pin to minimum of year 1 (first year)
                    + ERAS[internalGet(ERA, CURRENT_ERA) * 3] // add gregorian starting year
                    - 1;                                      // Subtract one because year starts at 1
        }
        return year;
    }
    
    /**
     * Called by handleComputeJulianDay.  Returns the default month (0-based) for the year,
     * taking year and era into account.  Defaults to 0 (JANUARY) for Gregorian.
     * @param extendedYear the extendedYear, as returned by handleGetExtendedYear
     * @return the default month
     * @provisional ICU 3.6
     * @draft ICU 3.6 (retain)
     * @see #MONTH
     */
    protected int getDefaultMonthInYear(int extendedYear)
    {
      int era = internalGet(ERA, CURRENT_ERA);
      //computeFields(status); // No need to compute fields here - expect the caller already did so.

      // Find out if we are at the edge of an era
      if(extendedYear == ERAS[era*3]) {
        return ERAS[(era*3)+1] // month..
            -1; // return 0-based month
      } else {
        return super.getDefaultMonthInYear(extendedYear);
      }
    }

    /**
     * Called by handleComputeJulianDay.  Returns the default day (1-based) for the month,
     * taking currently-set year and era into account.  Defaults to 1 for Gregorian.
     * @param extendedYear the extendedYear, as returned by handleGetExtendedYear
     * @param month the month, as returned by getDefaultMonthInYear
     * @return the default day of the month
     * @draft ICU 3.6 (retain)
     * @provisional ICU 3.6
     * @see #DAY_OF_MONTH
     */
    protected int getDefaultDayInMonth(int extendedYear, int month) {
      int era = internalGet(ERA, CURRENT_ERA);
          
      if(extendedYear == ERAS[era*3]) { // if it is year 1..
        if(month == ((ERAS[(era*3)+1])-1)) { // if it is the emperor's first month.. 
          return ERAS[(era*3)+2]; // return the D_O_M of acession
        }
      }

      return super.getDefaultDayInMonth(extendedYear, month);
    }

    /**
     * @stable ICU 2.8
     */
    protected void handleComputeFields(int julianDay) {
        super.handleComputeFields(julianDay);
        int year = internalGet(EXTENDED_YEAR);

        int low = 0;

        // Short circuit for recent years.  Most modern computations will
        // occur in the current era and won't require the binary search.
        // Note that if the year is == the current era year, then we use
        // the binary search to handle the month/dom comparison.
        if (year > ERAS[ERAS.length - 3]) {
            low = CURRENT_ERA;
        } else {
            // Binary search
            int high = ERAS.length / 3;
        
            while (low < high - 1) {
                int i = (low + high) / 2;
                int diff = year - ERAS[i*3];

                // If years are the same, then compare the months, and if those
                // are the same, compare days of month.  In the ERAS array
                // months are 1-based for easier maintenance.
                if (diff == 0) {
                    diff = internalGet(MONTH) - (ERAS[i*3 + 1] - 1);
                    if (diff == 0) {
                        diff = internalGet(DAY_OF_MONTH) - ERAS[i*3 + 2];
                    }
                }
                if (diff >= 0) {
                    low = i;
                } else {
                    high = i;
                }
            }
        }

        // Now we've found the last era that starts before this date, so
        // adjust the year to count from the start of that era.  Note that
        // all dates before the first era will fall into the first era by
        // the algorithm.
        internalSet(ERA, low);
        internalSet(YEAR, year - ERAS[low*3] + 1);
    }

    private static final int[] ERAS = {
    //  Gregorian date of each emperor's ascension
    //  Years are AD, months are 1-based.
    //  Year  Month Day
         645,    6, 19,     // Taika
         650,    2, 15,     // Hakuchi
         672,    1,  1,     // Hakuho
         686,    7, 20,     // Shucho
         701,    3, 21,     // Taiho
         704,    5, 10,     // Keiun
         708,    1, 11,     // Wado
         715,    9,  2,     // Reiki
         717,   11, 17,     // Yoro
         724,    2,  4,     // Jinki
         729,    8,  5,     // Tempyo
         749,    4, 14,     // Tempyo-kampo
         749,    7,  2,     // Tempyo-shoho
         757,    8, 18,     // Tempyo-hoji
         765,    1,  7,     // Tempho-jingo
         767,    8, 16,     // Jingo-keiun
         770,   10,  1,     // Hoki
         781,    1,  1,     // Ten-o
         782,    8, 19,     // Enryaku
         806,    5, 18,     // Daido
         810,    9, 19,     // Konin
         824,    1,  5,     // Tencho
         834,    1,  3,     // Showa
         848,    6, 13,     // Kajo
         851,    4, 28,     // Ninju
         854,   11, 30,     // Saiko
         857,    2, 21,     // Tennan
         859,    4, 15,     // Jogan
         877,    4, 16,     // Genkei
         885,    2, 21,     // Ninna
         889,    4, 27,     // Kampyo
         898,    4, 26,     // Shotai
         901,    7, 15,     // Engi
         923,    4, 11,     // Encho
         931,    4, 26,     // Shohei
         938,    5, 22,     // Tengyo
         947,    4, 22,     // Tenryaku
         957,   10, 27,     // Tentoku
         961,    2, 16,     // Owa
         964,    7, 10,     // Koho
         968,    8, 13,     // Anna
         970,    3, 25,     // Tenroku
         973,   12, 20,     // Ten-en
         976,    7, 13,     // Jogen
         978,   11, 29,     // Tengen
         983,    4, 15,     // Eikan
         985,    4, 27,     // Kanna
         987,    4,  5,     // Ei-en
         989,    8,  8,     // Eiso
         990,   11,  7,     // Shoryaku
         995,    2, 22,     // Chotoku
         999,    1, 13,     // Choho
        1004,    7, 20,     // Kanko
        1012,   12, 25,     // Chowa
        1017,    4, 23,     // Kannin
        1021,    2,  2,     // Jian
        1024,    7, 13,     // Manju
        1028,    7, 25,     // Chogen
        1037,    4, 21,     // Choryaku
        1040,   11, 10,     // Chokyu
        1044,   11, 24,     // Kantoku
        1046,    4, 14,     // Eisho
        1053,    1, 11,     // Tengi
        1058,    8, 29,     // Kohei
        1065,    8,  2,     // Jiryaku
        1069,    4, 13,     // Enkyu
        1074,    8, 23,     // Shoho
        1077,   11, 17,     // Shoryaku
        1081,    2, 10,     // Eiho
        1084,    2,  7,     // Otoku
        1087,    4,  7,     // Kanji
        1094,   12, 15,     // Kaho
        1096,   12, 17,     // Eicho
        1097,   11, 21,     // Shotoku
        1099,    8, 28,     // Kowa
        1104,    2, 10,     // Choji
        1106,    4,  9,     // Kasho
        1108,    8,  3,     // Tennin
        1110,    7, 13,     // Ten-ei
        1113,    7, 13,     // Eikyu
        1118,    4,  3,     // Gen-ei
        1120,    4, 10,     // Hoan
        1124,    4,  3,     // Tenji
        1126,    1, 22,     // Daiji
        1131,    1, 29,     // Tensho
        1132,    8, 11,     // Chosho
        1135,    4, 27,     // Hoen
        1141,    7, 10,     // Eiji
        1142,    4, 28,     // Koji
        1144,    2, 23,     // Tenyo
        1145,    7, 22,     // Kyuan
        1151,    1, 26,     // Ninpei
        1154,   10, 28,     // Kyuju
        1156,    4, 27,     // Hogen
        1159,    4, 20,     // Heiji
        1160,    1, 10,     // Eiryaku
        1161,    9,  4,     // Oho
        1163,    3, 29,     // Chokan
        1165,    6,  5,     // Eiman
        1166,    8, 27,     // Nin-an
        1169,    4,  8,     // Kao
        1171,    4, 21,     // Shoan
        1175,    7, 28,     // Angen
        1177,    8,  4,     // Jisho
        1181,    7, 14,     // Yowa
        1182,    5, 27,     // Juei
        1184,    4, 16,     // Genryuku
        1185,    8, 14,     // Bunji
        1190,    4, 11,     // Kenkyu
        1199,    4, 27,     // Shoji
        1201,    2, 13,     // Kennin
        1204,    2, 20,     // Genkyu
        1206,    4, 27,     // Ken-ei
        1207,   10, 25,     // Shogen
        1211,    3,  9,     // Kenryaku
        1213,   12,  6,     // Kenpo
        1219,    4, 12,     // Shokyu
        1222,    4, 13,     // Joo
        1224,   11, 20,     // Gennin
        1225,    4, 20,     // Karoku
        1227,   12, 10,     // Antei
        1229,    3,  5,     // Kanki
        1232,    4,  2,     // Joei
        1233,    4, 15,     // Tempuku
        1234,   11,  5,     // Bunryaku
        1235,    9, 19,     // Katei
        1238,   11, 23,     // Ryakunin
        1239,    2,  7,     // En-o
        1240,    7, 16,     // Ninji
        1243,    2, 26,     // Kangen
        1247,    2, 28,     // Hoji
        1249,    3, 18,     // Kencho
        1256,   10,  5,     // Kogen
        1257,    3, 14,     // Shoka
        1259,    3, 26,     // Shogen
        1260,    4, 13,     // Bun-o
        1261,    2, 20,     // Kocho
        1264,    2, 28,     // Bun-ei
        1275,    4, 25,     // Kenji
        1278,    2, 29,     // Koan
        1288,    4, 28,     // Shoo
        1293,    8, 55,     // Einin
        1299,    4, 25,     // Shoan
        1302,   11, 21,     // Kengen
        1303,    8,  5,     // Kagen
        1306,   12, 14,     // Tokuji
        1308,   10,  9,     // Enkei
        1311,    4, 28,     // Ocho
        1312,    3, 20,     // Showa
        1317,    2,  3,     // Bunpo
        1319,    4, 28,     // Geno
        1321,    2, 23,     // Genkyo
        1324,   12,  9,     // Shochu
        1326,    4, 26,     // Kareki
        1329,    8, 29,     // Gentoku
        1331,    8,  9,     // Genko
        1334,    1, 29,     // Kemmu
        1336,    2, 29,     // Engen
        1340,    4, 28,     // Kokoku
        1346,   12,  8,     // Shohei
        1370,    7, 24,     // Kentoku
        1372,    4,  1,     // Bunch\u0169
        1375,    5, 27,     // Tenju
        1379,    3, 22,     // Koryaku
        1381,    2, 10,     // Kowa
        1384,    4, 28,     // Gench\u0169
        1384,    2, 27,     // Meitoku
        1387,    8, 23,     // Kakei
        1389,    2,  9,     // Koo
        1390,    3, 26,     // Meitoku
        1394,    7,  5,     // Oei
        1428,    4, 27,     // Shocho
        1429,    9,  5,     // Eikyo
        1441,    2, 17,     // Kakitsu
        1444,    2,  5,     // Bun-an
        1449,    7, 28,     // Hotoku
        1452,    7, 25,     // Kyotoku
        1455,    7, 25,     // Kosho
        1457,    9, 28,     // Choroku
        1460,   12, 21,     // Kansho
        1466,    2, 28,     // Bunsho
        1467,    3,  3,     // Onin
        1469,    4, 28,     // Bunmei
        1487,    7, 29,     // Chokyo
        1489,    8, 21,     // Entoku
        1492,    7, 19,     // Meio
        1501,    2, 29,     // Bunki
        1504,    2, 30,     // Eisho
        1521,    8, 23,     // Taiei
        1528,    8, 20,     // Kyoroku
        1532,    7, 29,     // Tenmon
        1555,   10, 23,     // Koji
        1558,    2, 28,     // Eiroku
        1570,    4, 23,     // Genki
        1573,    7, 28,     // Tensho
        1592,   12,  8,     // Bunroku
        1596,   10, 27,     // Keicho
        1615,    7, 13,     // Genwa
        1624,    2, 30,     // Kan-ei
        1644,   12, 16,     // Shoho
        1648,    2, 15,     // Keian
        1652,    9, 18,     // Shoo
        1655,    4, 13,     // Meiryaku
        1658,    7, 23,     // Manji
        1661,    4, 25,     // Kanbun
        1673,    9, 21,     // Enpo
        1681,    9, 29,     // Tenwa
        1684,    2, 21,     // Jokyo
        1688,    9, 30,     // Genroku
        1704,    3, 13,     // Hoei
        1711,    4, 25,     // Shotoku
        1716,    6, 22,     // Kyoho
        1736,    4, 28,     // Genbun
        1741,    2, 27,     // Kanpo
        1744,    2, 21,     // Enkyo
        1748,    7, 12,     // Kan-en
        1751,   10, 27,     // Horyaku
        1764,    6,  2,     // Meiwa
        1772,   11, 16,     // An-ei
        1781,    4,  2,     // Tenmei
        1789,    1, 25,     // Kansei
        1801,    2,  5,     // Kyowa
        1804,    2, 11,     // Bunka
        1818,    4, 22,     // Bunsei
        1830,   12, 10,     // Tenpo
        1844,   12,  2,     // Koka
        1848,    2, 28,     // Kaei
        1854,   11, 27,     // Ansei
        1860,    3, 18,     // Man-en
        1861,    2, 19,     // Bunkyu
        1864,    2, 20,     // Genji
        1865,    4,  7,     // Keio
        1868,    9,  8,     // Meiji
        1912,    7, 30,     // Taisho
        1926,   12, 25,     // Showa
        1989,    1,  8,     // Heisei
    };

    //-------------------------------------------------------------------------
    // Public constants for some of the recent eras that folks might use...
    //-------------------------------------------------------------------------

    // Constant for the current era.  This must be regularly updated.
    /**
     * @stable ICU 2.8
     */
    static public final int CURRENT_ERA = (ERAS.length / 3) - 1;
    
    /** 
     * Constant for the era starting on Sept. 8, 1868 AD.
     * @stable  ICU 2.8 
     */
    static public final int MEIJI = CURRENT_ERA - 3;

    /** 
     * Constant for the era starting on July 30, 1912 AD. 
     * @stable ICU 2.8 
     */
    static public final int TAISHO = CURRENT_ERA - 2;
    
    /** 
     * Constant for the era starting on Dec. 25, 1926 AD. 
     * @stable ICU 2.8 
     */
    static public final int SHOWA = CURRENT_ERA - 1;

    /** 
     * Constant for the era starting on Jan. 7, 1989 AD. 
     * @stable ICU 2.8 
     */
    static public final int HEISEI = CURRENT_ERA;

    /**
     * Override GregorianCalendar.  We should really handle YEAR_WOY and
     * EXTENDED_YEAR here too to implement the 1..5000000 range, but it's
     * not critical.
     * @stable ICU 2.8
     */
    @SuppressWarnings("fallthrough")
    protected int handleGetLimit(int field, int limitType) {
        switch (field) {
        case ERA:
            if (limitType == MINIMUM || limitType == GREATEST_MINIMUM) {
                return 0;
            }
            return CURRENT_ERA;
        case YEAR:
        {
            switch (limitType) {
            case MINIMUM:
            case GREATEST_MINIMUM:
                return 1;
            case LEAST_MAXIMUM:
                return 1;
            case MAXIMUM:
                return super.handleGetLimit(field, MAXIMUM) - ERAS[CURRENT_ERA*3];
            }
            //Fall through to the default if not handled above
        }
        default:
            return super.handleGetLimit(field, limitType);
        }
    }

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    public String getType() {
        return "japanese";
    }

    /**
     * {@inheritDoc}
     * @stable ICU 4.0
     */
    public int getActualMaximum(int field) {
        if (field == YEAR) {
            int era = get(Calendar.ERA);
            if (era == CURRENT_ERA) {
                // TODO: Investigate what value should be used here - revisit after 4.0.
                return handleGetLimit(YEAR, MAXIMUM);
            } else {
                int nextEraYear = ERAS[(era+1)*3];
                int nextEraMonth = ERAS[(era+1)*3 + 1];
                int nextEraDate = ERAS[(era+1)*3 + 2];

                int maxYear = nextEraYear - ERAS[era*3] + 1; // 1-base
                if (nextEraMonth == 1 && nextEraDate == 1) {
                    // Substract 1, because the next era starts at Jan 1
                    maxYear--;
                }
                return maxYear;
            }
        }
        return super.getActualMaximum(field);
    }
}
