/*********************************************************************
 * Copyright (C) 2000-2004, International Business Machines Corporation and
 * others. All Rights Reserved.
 *********************************************************************
 */
package com.ibm.icu.util;
import com.ibm.icu.text.*;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.impl.CalendarAstronomer;
import com.ibm.icu.impl.CalendarCache;
import java.util.Locale;

/**
 * <code>ChineseCalendar</code> is a concrete subclass of {@link Calendar}
 * that implements a traditional Chinese calendar.  The traditional Chinese
 * calendar is a lunisolar calendar: Each month starts on a new moon, and
 * the months are numbered according to solar events, specifically, to
 * guarantee that month 11 always contains the winter solstice.  In order
 * to accomplish this, leap months are inserted in certain years.  Leap
 * months are numbered the same as the month they follow.  The decision of
 * which month is a leap month depends on the relative movements of the sun
 * and moon.
 *
 * <p>This class defines one addition field beyond those defined by
 * <code>Calendar</code>: The <code>IS_LEAP_MONTH</code> field takes the
 * value of 0 for normal months, or 1 for leap months.
 *
 * <p>All astronomical computations are performed with respect to a time
 * zone of GMT+8:00 and a longitude of 120 degrees east.  Although some
 * calendars implement a historically more accurate convention of using
 * Beijing's local longitude (116 degrees 25 minutes east) and time zone
 * (GMT+7:45:40) for dates before 1929, we do not implement this here.
 *
 * <p>Years are counted in two different ways in the Chinese calendar.  The
 * first method is by sequential numbering from the 61st year of the reign
 * of Huang Di, 2637 BCE, which is designated year 1 on the Chinese
 * calendar.  The second method uses 60-year cycles from the same starting
 * point, which is designated year 1 of cycle 1.  In this class, the
 * <code>EXTENDED_YEAR</code> field contains the sequential year count.
 * The <code>ERA</code> field contains the cycle number, and the
 * <code>YEAR</code> field contains the year of the cycle, a value between
 * 1 and 60.
 *
 * <p>There is some variation in what is considered the starting point of
 * the calendar, with some sources starting in the first year of the reign
 * of Huang Di, rather than the 61st.  This gives continuous year numbers
 * 60 years greater and cycle numbers one greater than what this class
 * implements.
 *
 * <p>Because <code>ChineseCalendar</code> defines an additional field and
 * redefines the way the <code>ERA</code> field is used, it requires a new
 * format class, <code>ChineseDateFormat</code>.  As always, use the
 * methods <code>DateFormat.getXxxInstance(Calendar cal,...)</code> to
 * obtain a formatter for this calendar.
 *
 * <p>References:<ul>
 * 
 * <li>Dershowitz and Reingold, <i>Calendrical Calculations</i>,
 * Cambridge University Press, 1997</li>
 * 
 * <li>Helmer Aslaksen's
 * <a href="http://www.math.nus.edu.sg/aslaksen/calendar/chinese.shtml">
 * Chinese Calendar page</a></li>
 *
 * <li>The <a href="http://www.tondering.dk/claus/calendar.html">
 * Calendar FAQ</a></li>
 *
 * </ul>
 *
 * <p>
 * Note This API has not been promoted to @stable and instead has been left
 * as @draft ICU 2.8.  It may yet change or be removed in a future release.
 *
 * @see com.ibm.icu.text.ChineseDateFormat
 * @author Alan Liu
 * @draft ICU 2.8
 * @deprecated This is a draft API and might change in a future release of ICU.
 */
public class ChineseCalendar extends Calendar {

    //------------------------------------------------------------------
    // Developer Notes
    // 
    // Time is represented as a scalar in two ways in this class.  One is
    // the usual UTC epoch millis, that is, milliseconds after January 1,
    // 1970 Gregorian, 0:00:00.000 UTC.  The other is in terms of 'local
    // days.'  This is the number of days after January 1, 1970 Gregorian,
    // local to Beijing, China (since all computations of the Chinese
    // calendar are done in Beijing).  That is, 0 represents January 1,
    // 1970 0:00 Asia/Shanghai.  Conversion of local days to and from
    // standard epoch milliseconds is accomplished by the daysToMillis()
    // and millisToDays() methods.
    // 
    // Several methods use caches to improve performance.  Caches are at
    // the object, not class level, under the assumption that typical
    // usage will be to have one instance of ChineseCalendar at a time.
 
    /**
     * We have one instance per object, and we don't synchronize it because
     * Calendar doesn't support multithreaded execution in the first place.
     */
    private transient CalendarAstronomer astro = new CalendarAstronomer();

    /**
     * Cache that maps Gregorian year to local days of winter solstice.
     * @see #winterSolstice
     */
    private transient CalendarCache winterSolsticeCache = new CalendarCache();

    /**
     * Cache that maps Gregorian year to local days of Chinese new year.
     * @see #newYear
     */
    private transient CalendarCache newYearCache = new CalendarCache();

    /**
     * True if the current year is a leap year.  Updated with each time to
     * fields resolution.
     * @see #computeChineseFields
     */
    private transient boolean isLeapYear;

    //------------------------------------------------------------------
    // Constructors
    //------------------------------------------------------------------

    /**
     * Construct a Chinese calendar with the default time zone and locale.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    public ChineseCalendar() {
        super();
    }

    /**
     * Construct a Chinese calendar with the given time zone and locale.
     * @param zone time zone for this calendar
     * @param locale locale for this calendar
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    public ChineseCalendar(TimeZone zone, Locale locale) {
        super(zone, locale);
    }

    /**
     * Construct a Chinese calendar with the given time zone and locale.
     * @param zone time zone for this calendar
     * @param locale ulocale for this calendar
     * @draft ICU 3.2
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    public ChineseCalendar(TimeZone zone, ULocale locale) {
        super(zone, locale);
    }

    //------------------------------------------------------------------
    // Public constants
    //------------------------------------------------------------------

    /**
     * Field indicating whether or not the current month is a leap month.
     * Should have a value of 0 for non-leap months, and 1 for leap months.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    public static int IS_LEAP_MONTH = BASE_FIELD_COUNT;

    /**
     * Count of fields in this class.
     */
    private static final int FIELD_COUNT = IS_LEAP_MONTH + 1;

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

    /**
     * Override Calendar to allocate our additional field.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    protected int[] handleCreateFields() {
        return new int[FIELD_COUNT];
    }

    /**
     * Array defining the limits of field values for this class.  Field
     * limits which are invariant with respect to calendar system and
     * defined by Calendar are left blank.
     *
     * Notes:
     *
     * ERA 5000000 / 60 = 83333.
     *
     * MONTH There are 12 or 13 lunar months in a year.  However, we always
     * number them 0..11, with an intercalated, identically numbered leap
     * month, when necessary.
     *
     * DAY_OF_YEAR In a non-leap year there are 353, 354, or 355 days.  In
     * a leap year there are 383, 384, or 385 days.
     *
     * WEEK_OF_YEAR The least maximum occurs if there are 353 days in the
     * year, and the first 6 are the last week of the previous year.  Then
     * we have 49 full weeks and 4 days in the last week: 6 + 49*7 + 4 =
     * 353.  So the least maximum is 50.  The maximum occurs if there are
     * 385 days in the year, and WOY 1 extends 6 days into the prior year.
     * Then there are 54 full weeks, and 6 days in the last week: 1 + 54*7
     * + 6 = 385.  The 6 days of the last week will fall into WOY 1 of the
     * next year.  Maximum is 55.
     *
     * WEEK_OF_MONTH In a 29 day month, if the first 7 days make up week 1
     * that leaves 3 full weeks and 1 day at the end.  The least maximum is
     * thus 5.  In a 30 days month, if the previous 6 days belong WOM 1 of
     * this month, we have 4 full weeks and 1 days at the end (which
     * technically will be WOM 1 of the next month, but will be reported by
     * time->fields and hence by getActualMaximum as WOM 6 of this month).
     * Maximum is 6.
     *
     * DAY_OF_WEEK_IN_MONTH In a 29 or 30 day month, there are 4 full weeks
     * plus 1 or 2 days at the end, so the maximum is always 5.
     */
    private static final int LIMITS[][] = {
        // Minimum  Greatest    Least  Maximum
        //           Minimum  Maximum
        {        1,        1,   83333,   83333 }, // ERA
        {        1,        1,      70,      70 }, // YEAR
        {        0,        0,      11,      11 }, // MONTH
        {        1,        1,      50,      55 }, // WEEK_OF_YEAR
        {        1,        1,       5,       6 }, // WEEK_OF_MONTH
        {        1,        1,      29,      30 }, // DAY_OF_MONTH
        {        1,        1,     353,     385 }, // 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
        { -5000001, -5000001, 5000001, 5000001 }, // YEAR_WOY
        {/*                                  */}, // DOW_LOCAL
        { -5000000, -5000000, 5000000, 5000000 }, // EXTENDED_YEAR
        {/*                                  */}, // JULIAN_DAY
        {/*                                  */}, // MILLISECONDS_IN_DAY
        {        0,        0,       1,       1 }, // IS_LEAP_MONTH
    };

    /**
     * Override Calendar to return the limit value for the given field.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    protected int handleGetLimit(int field, int limitType) {
        return LIMITS[field][limitType];
    }

    /**
     * Implement abstract Calendar method to return the extended year
     * defined by the current fields.  This will use either the ERA and
     * YEAR field as the cycle and year-of-cycle, or the EXTENDED_YEAR
     * field as the continuous year count, depending on which is newer.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    protected int handleGetExtendedYear() {
        int year;
        if (newestStamp(ERA, YEAR, UNSET) <= getStamp(EXTENDED_YEAR)) {
            year = internalGet(EXTENDED_YEAR, 1); // Default to year 1
        } else {
            int cycle = internalGet(ERA, 1) - 1; // 0-based cycle
            year = cycle * 60 + internalGet(YEAR, 1);
        }
        return year;
    }

    /**
     * Override Calendar method to return the number of days in the given
     * extended year and month.
     *
     * <p>Note: This method also reads the IS_LEAP_MONTH field to determine
     * whether or not the given month is a leap month.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    protected int handleGetMonthLength(int extendedYear, int month) {
        int thisStart = handleComputeMonthStart(extendedYear, month, true) -
            EPOCH_JULIAN_DAY + 1; // Julian day -> local days
        int nextStart = newMoonNear(thisStart + SYNODIC_GAP, true);
        return nextStart - thisStart;
    }

    /**
     * Framework method to create a calendar-specific DateFormat object
     * using the the given pattern.  This method is responsible for
     * creating the calendar- specific DateFormat and DateFormatSymbols
     * objects as needed.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    protected DateFormat handleGetDateFormat(String pattern, ULocale locale) {
        return new ChineseDateFormat(pattern, locale);
    }

    /**
     * Field resolution table that incorporates IS_LEAP_MONTH.
     */
    static final int[][][] CHINESE_DATE_PRECEDENCE = {
        {
            { DAY_OF_MONTH },
            { WEEK_OF_YEAR, DAY_OF_WEEK },
            { WEEK_OF_MONTH, DAY_OF_WEEK },
            { DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK },
            { WEEK_OF_YEAR, DOW_LOCAL },
            { WEEK_OF_MONTH, DOW_LOCAL },
            { DAY_OF_WEEK_IN_MONTH, DOW_LOCAL },
            { DAY_OF_YEAR },
            { RESOLVE_REMAP | DAY_OF_MONTH, IS_LEAP_MONTH },
        },
        {
            { WEEK_OF_YEAR },
            { WEEK_OF_MONTH },
            { DAY_OF_WEEK_IN_MONTH },
            { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK },
            { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DOW_LOCAL },
        },
    };

    /**
     * Override Calendar to add IS_LEAP_MONTH to the field resolution
     * table.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    protected int[][][] getFieldResolutionTable() {
        return CHINESE_DATE_PRECEDENCE;
    }

    /**
     * Adjust this calendar to be delta months before or after a given
     * start position, pinning the day of month if necessary.  The start
     * position is given as a local days number for the start of the month
     * and a day-of-month.  Used by add() and roll().
     * @param newMoon the local days of the first day of the month of the
     * start position (days after January 1, 1970 0:00 Asia/Shanghai)
     * @param dom the 1-based day-of-month of the start position
     * @param delta the number of months to move forward or backward from
     * the start position
     */
    private void offsetMonth(int newMoon, int dom, int delta) {
        // Move to the middle of the month before our target month.
        newMoon += (int) (CalendarAstronomer.SYNODIC_MONTH * (delta - 0.5));

        // Search forward to the target month's new moon
        newMoon = newMoonNear(newMoon, true);

        // Find the target dom
        int jd = newMoon + EPOCH_JULIAN_DAY - 1 + dom;

        // Pin the dom.  In this calendar all months are 29 or 30 days
        // so pinning just means handling dom 30.
        if (dom > 29) {
            set(JULIAN_DAY, jd-1);
            // TODO Fix this.  We really shouldn't ever have to
            // explicitly call complete().  This is either a bug in
            // this method, in ChineseCalendar, or in
            // Calendar.getActualMaximum().  I suspect the last.
            complete();
            if (getActualMaximum(DAY_OF_MONTH) >= dom) {
                set(JULIAN_DAY, jd);
            }
        } else {
            set(JULIAN_DAY, jd);
        }
    }

    /**
     * Override Calendar to handle leap months properly.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    public void add(int field, int amount) {
        switch (field) {
        case MONTH:
            if (amount != 0) {
                int dom = get(DAY_OF_MONTH);
                int day = get(JULIAN_DAY) - EPOCH_JULIAN_DAY; // Get local day
                int moon = day - dom + 1; // New moon 
                offsetMonth(moon, dom, amount);
            }
            break;
        default:
            super.add(field, amount);
            break;
        }
    }

    /**
     * Override Calendar to handle leap months properly.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    public void roll(int field, int amount) {
        switch (field) {
        case MONTH:
            if (amount != 0) {
                int dom = get(DAY_OF_MONTH);
                int day = get(JULIAN_DAY) - EPOCH_JULIAN_DAY; // Get local day
                int moon = day - dom + 1; // New moon (start of this month)

                // Note throughout the following:  Months 12 and 1 are never
                // followed by a leap month (D&R p. 185).

                // Compute the adjusted month number m.  This is zero-based
                // value from 0..11 in a non-leap year, and from 0..12 in a
                // leap year.
                int m = get(MONTH); // 0-based month
                if (isLeapYear) { // (member variable)
                    if (get(IS_LEAP_MONTH) == 1) {
                        ++m;
                    } else {
                        // Check for a prior leap month.  (In the
                        // following, month 0 is the first month of the
                        // year.)  Month 0 is never followed by a leap
                        // month, and we know month m is not a leap month.
                        // moon1 will be the start of month 0 if there is
                        // no leap month between month 0 and month m;
                        // otherwise it will be the start of month 1.
                        int moon1 = moon -
                            (int) (CalendarAstronomer.SYNODIC_MONTH * (m - 0.5));
                        moon1 = newMoonNear(moon1, true);
                        if (isLeapMonthBetween(moon1, moon)) {
                            ++m;
                        }
                    }
                }

                // Now do the standard roll computation on m, with the
                // allowed range of 0..n-1, where n is 12 or 13.
                int n = isLeapYear ? 13 : 12; // Months in this year
                int newM = (m + amount) % n;
                if (newM < 0) {
                    newM += n;
                }

                if (newM != m) {
                    offsetMonth(moon, dom, newM - m);
                }
            }
            break;
        default:
            super.roll(field, amount);
            break;
        }
    }

    //------------------------------------------------------------------
    // Support methods and constants
    //------------------------------------------------------------------
   
    /**
     * The start year of the Chinese calendar, the 61st year of the reign
     * of Huang Di.  Some sources use the first year of his reign,
     * resulting in EXTENDED_YEAR values 60 years greater and ERA (cycle)
     * values one greater.
     */
    private static final int CHINESE_EPOCH_YEAR = -2636; // Gregorian year

    /**
     * The offset from GMT in milliseconds at which we perform astronomical
     * computations.  Some sources use a different historically accurate
     * offset of GMT+7:45:40 for years before 1929; we do not do this.
     */
    private static final long CHINA_OFFSET = 8*ONE_HOUR;

    /**
     * Value to be added or subtracted from the local days of a new moon to
     * get close to the next or prior new moon, but not cross it.  Must be
     * >= 1 and < CalendarAstronomer.SYNODIC_MONTH.
     */
    private static final int SYNODIC_GAP = 25;

    /**
     * Convert local days to UTC epoch milliseconds.
     * @param days days after January 1, 1970 0:00 Asia/Shanghai
     * @return milliseconds after January 1, 1970 0:00 GMT
     */
    private static final long daysToMillis(int days) {
        return (days * ONE_DAY) - CHINA_OFFSET;
    }

    /**
     * Convert UTC epoch milliseconds to local days.
     * @param millis milliseconds after January 1, 1970 0:00 GMT
     * @return days after January 1, 1970 0:00 Asia/Shanghai
     */
    private static final int millisToDays(long millis) {
        return (int) floorDivide(millis + CHINA_OFFSET, ONE_DAY);
    }

    //------------------------------------------------------------------
    // Astronomical computations
    //------------------------------------------------------------------
    
    /**
     * Return the major solar term on or after December 15 of the given
     * Gregorian year, that is, the winter solstice of the given year.
     * Computations are relative to Asia/Shanghai time zone.
     * @param gyear a Gregorian year
     * @return days after January 1, 1970 0:00 Asia/Shanghai of the
     * winter solstice of the given year
     */
    private int winterSolstice(int gyear) {

        long cacheValue = winterSolsticeCache.get(gyear);

        if (cacheValue == CalendarCache.EMPTY) {
            // In books December 15 is used, but it fails for some years
            // using our algorithms, e.g.: 1298 1391 1492 1553 1560.  That
            // is, winterSolstice(1298) starts search at Dec 14 08:00:00
            // PST 1298 with a final result of Dec 14 10:31:59 PST 1299.
            long ms = daysToMillis(computeGregorianMonthStart(gyear, DECEMBER) +
                                   1 - EPOCH_JULIAN_DAY);
            astro.setTime(ms);
            
            // Winter solstice is 270 degrees solar longitude aka Dongzhi
            long solarLong = astro.getSunTime(CalendarAstronomer.WINTER_SOLSTICE,
                                              true);
            cacheValue = millisToDays(solarLong);
            winterSolsticeCache.put(gyear, cacheValue);
        }
        return (int) cacheValue;
    }

    /**
     * Return the closest new moon to the given date, searching either
     * forward or backward in time.
     * @param days days after January 1, 1970 0:00 Asia/Shanghai
     * @param after if true, search for a new moon on or after the given
     * date; otherwise, search for a new moon before it
     * @return days after January 1, 1970 0:00 Asia/Shanghai of the nearest
     * new moon after or before <code>days</code>
     */
    private int newMoonNear(int days, boolean after) {
        
        astro.setTime(daysToMillis(days));
        long newMoon = astro.getMoonTime(CalendarAstronomer.NEW_MOON, after);
        
        return millisToDays(newMoon);
    }

    /**
     * Return the nearest integer number of synodic months between
     * two dates.
     * @param day1 days after January 1, 1970 0:00 Asia/Shanghai
     * @param day2 days after January 1, 1970 0:00 Asia/Shanghai
     * @return the nearest integer number of months between day1 and day2
     */
    private int synodicMonthsBetween(int day1, int day2) {
        return (int) Math.round((day2 - day1) / CalendarAstronomer.SYNODIC_MONTH);
    }

    /**
     * Return the major solar term on or before a given date.  This
     * will be an integer from 1..12, with 1 corresponding to 330 degrees,
     * 2 to 0 degrees, 3 to 30 degrees,..., and 12 to 300 degrees.
     * @param days days after January 1, 1970 0:00 Asia/Shanghai
     */
    private int majorSolarTerm(int days) {
        
        astro.setTime(daysToMillis(days));

        // Compute (floor(solarLongitude / (pi/6)) + 2) % 12
        int term = ((int) Math.floor(6 * astro.getSunLongitude() / Math.PI) + 2) % 12;
        if (term < 1) {
            term += 12;
        }
        return term;
    }

    /**
     * Return true if the given month lacks a major solar term.
     * @param newMoon days after January 1, 1970 0:00 Asia/Shanghai of a new
     * moon
     */
    private boolean hasNoMajorSolarTerm(int newMoon) {
        
        int mst = majorSolarTerm(newMoon);
        int nmn = newMoonNear(newMoon + SYNODIC_GAP, true);
        int mstt = majorSolarTerm(nmn);
        return mst == mstt;
        /*
        return majorSolarTerm(newMoon) ==
            majorSolarTerm(newMoonNear(newMoon + SYNODIC_GAP, true));
        */
    }

    //------------------------------------------------------------------
    // Time to fields
    //------------------------------------------------------------------
    
    /**
     * Return true if there is a leap month on or after month newMoon1 and
     * at or before month newMoon2.
     * @param newMoon1 days after January 1, 1970 0:00 Asia/Shanghai of a
     * new moon
     * @param newMoon2 days after January 1, 1970 0:00 Asia/Shanghai of a
     * new moon
     */
    private boolean isLeapMonthBetween(int newMoon1, int newMoon2) {

        // This is only needed to debug the timeOfAngle divergence bug.
        // Remove this later. Liu 11/9/00
        // DEBUG
        if (synodicMonthsBetween(newMoon1, newMoon2) >= 50) {
            throw new IllegalArgumentException("isLeapMonthBetween(" + newMoon1 +
                                               ", " + newMoon2 +
                                               "): Invalid parameters");
        }

        return (newMoon2 >= newMoon1) &&
            (isLeapMonthBetween(newMoon1, newMoonNear(newMoon2 - SYNODIC_GAP, false)) ||
             hasNoMajorSolarTerm(newMoon2));
    }

    /**
     * Override Calendar to compute several fields specific to the Chinese
     * 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.  The getGregorianXxx() methods return Gregorian
     * calendar equivalents for the given Julian day.
     *
     * <p>Compute the ChineseCalendar-specific field IS_LEAP_MONTH.
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    protected void handleComputeFields(int julianDay) {

        computeChineseFields(julianDay - EPOCH_JULIAN_DAY, // local days
                             getGregorianYear(), getGregorianMonth(),
                             true); // set all fields
    }

    /**
     * Compute fields for the Chinese calendar system.  This method can
     * either set all relevant fields, as required by
     * <code>handleComputeFields()</code>, or it can just set the MONTH and
     * IS_LEAP_MONTH fields, as required by
     * <code>handleComputeMonthStart()</code>.
     *
     * <p>As a side effect, this method sets {@link #isLeapYear}.
     * @param days days after January 1, 1970 0:00 Asia/Shanghai of the
     * date to compute fields for
     * @param gyear the Gregorian year of the given date
     * @param gmonth the Gregorian month of the given date
     * @param setAllFields if true, set the EXTENDED_YEAR, ERA, YEAR,
     * DAY_OF_MONTH, and DAY_OF_YEAR fields.  In either case set the MONTH
     * and IS_LEAP_MONTH fields.
     */
    private void computeChineseFields(int days, int gyear, int gmonth,
                                      boolean setAllFields) {

        // Find the winter solstices before and after the target date.
        // These define the boundaries of this Chinese year, specifically,
        // the position of month 11, which always contains the solstice.
        // We want solsticeBefore <= date < solsticeAfter.
        int solsticeBefore;
        int solsticeAfter = winterSolstice(gyear);
        if (days < solsticeAfter) {
            solsticeBefore = winterSolstice(gyear - 1);
        } else {
            solsticeBefore = solsticeAfter;
            solsticeAfter = winterSolstice(gyear + 1);
        }

        // Find the start of the month after month 11.  This will be either
        // the prior month 12 or leap month 11 (very rare).  Also find the
        // start of the following month 11.
        int firstMoon = newMoonNear(solsticeBefore + 1, true);
        int lastMoon = newMoonNear(solsticeAfter + 1, false);
        int thisMoon = newMoonNear(days + 1, false); // Start of this month
        // Note: isLeapYear is a member variable
        isLeapYear = synodicMonthsBetween(firstMoon, lastMoon) == 12;

        int month = synodicMonthsBetween(firstMoon, thisMoon);
        if (isLeapYear && isLeapMonthBetween(firstMoon, thisMoon)) {
            month--;
        }
        if (month < 1) {
            month += 12;
        }

        boolean isLeapMonth = isLeapYear &&
            hasNoMajorSolarTerm(thisMoon) &&
            !isLeapMonthBetween(firstMoon, newMoonNear(thisMoon - SYNODIC_GAP, false));

        internalSet(MONTH, month-1); // Convert from 1-based to 0-based
        internalSet(IS_LEAP_MONTH, isLeapMonth?1:0);

        if (setAllFields) {

            int year = gyear - CHINESE_EPOCH_YEAR;
            if (month < 11 ||
                gmonth >= JULY) {
                year++;
            }
            int dayOfMonth = days - thisMoon + 1;

            internalSet(EXTENDED_YEAR, year);

            // 0->0,60  1->1,1  60->1,60  61->2,1  etc.
            int[] yearOfCycle = new int[1];
            int cycle = floorDivide(year-1, 60, yearOfCycle);
            internalSet(ERA, cycle+1);
            internalSet(YEAR, yearOfCycle[0]+1);

            internalSet(DAY_OF_MONTH, dayOfMonth);

            // Days will be before the first new year we compute if this
            // date is in month 11, leap 11, 12.  There is never a leap 12.
            // New year computations are cached so this should be cheap in
            // the long run.
            int newYear = newYear(gyear);
            if (days < newYear) {
                newYear = newYear(gyear-1);
            }
            internalSet(DAY_OF_YEAR, days - newYear + 1);
        }
    }

    //------------------------------------------------------------------
    // Fields to time
    //------------------------------------------------------------------
    
    /**
     * Return the Chinese new year of the given Gregorian year.
     * @param gyear a Gregorian year
     * @return days after January 1, 1970 0:00 Asia/Shanghai of the
     * Chinese new year of the given year (this will be a new moon)
     */
    private int newYear(int gyear) {

        long cacheValue = newYearCache.get(gyear);

        if (cacheValue == CalendarCache.EMPTY) {

            int solsticeBefore= winterSolstice(gyear - 1);
            int solsticeAfter = winterSolstice(gyear);
            int newMoon1 = newMoonNear(solsticeBefore + 1, true);
            int newMoon2 = newMoonNear(newMoon1 + SYNODIC_GAP, true);
            int newMoon11 = newMoonNear(solsticeAfter + 1, false);
            
            if (synodicMonthsBetween(newMoon1, newMoon11) == 12 &&
                (hasNoMajorSolarTerm(newMoon1) || hasNoMajorSolarTerm(newMoon2))) {
                cacheValue = newMoonNear(newMoon2 + SYNODIC_GAP, true);
            } else {
                cacheValue = newMoon2;
            }

            newYearCache.put(gyear, cacheValue);
        }
        return (int) cacheValue;
    }

    /**
     * Return the Julian day number of day before the first day of the
     * given month in the given extended year.
     * 
     * <p>Note: This method reads the IS_LEAP_MONTH field to determine
     * whether the given month is a leap month.
     * @param eyear the extended year
     * @param month the zero-based month.  The month is also determined
     * by reading the IS_LEAP_MONTH field.
     * @return the Julian day number of the day before the first
     * day of the given month and year
     * @draft ICU 2.8
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    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 gyear = eyear + CHINESE_EPOCH_YEAR - 1; // Gregorian year
        int newYear = newYear(gyear);
        int newMoon = newMoonNear(newYear + month * 29, true);
        
        int julianDay = newMoon + EPOCH_JULIAN_DAY;

        // Save fields for later restoration
        int saveMonth = internalGet(MONTH);
        int saveIsLeapMonth = internalGet(IS_LEAP_MONTH);

        // Ignore IS_LEAP_MONTH field if useMonth is false
        int isLeapMonth = useMonth ? saveIsLeapMonth : 0;

        computeGregorianFields(julianDay);
        
        // This will modify the MONTH and IS_LEAP_MONTH fields (only)
        computeChineseFields(newMoon, getGregorianYear(),
                             getGregorianMonth(), false);        

        if (month != internalGet(MONTH) ||
            isLeapMonth != internalGet(IS_LEAP_MONTH)) {
            newMoon = newMoonNear(newMoon + SYNODIC_GAP, true);
            julianDay = newMoon + EPOCH_JULIAN_DAY;
        }

        internalSet(MONTH, saveMonth);
        internalSet(IS_LEAP_MONTH, saveIsLeapMonth);

        return julianDay - 1;
    }

    /**
     * Return the current Calendar type.
     * @return type of calendar (gregorian, etc.)
     * @internal ICU 3.0
     */
    public String getType() {
        return "chinese";
    }

    /*
    private static CalendarFactory factory;
    public static CalendarFactory factory() {
        if (factory == null) {
            factory = new CalendarFactory() {
                public Calendar create(TimeZone tz, ULocale loc) {
                    return new ChineseCalendar(tz, loc);
                }

                public String factoryName() {
                    return "Chinese";
                }
            };
        }
        return factory;
    }
    */
}
