/*
 *******************************************************************************
 * Copyright (C) 2005, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.util;

import java.util.Date;
import java.util.Locale;

/**
 * Base class for EthiopicCalendar and CopticCalendar.
 * @internal
 */
class CECalendar extends Calendar {
    // jdk1.4.2 serialver
    private static final long serialVersionUID = -999547623066414271L;

    private static final int LIMITS[][] = {
        // Minimum  Greatest    Least  Maximum
        //           Minimum  Maximum
        {0, 0, 1, 1                          }, // ERA
        {1, 1, 5828963, 5838270              }, // YEAR
        {0, 0, 13, 13                        }, // MONTH
        {1, 1, 52, 53                        }, // WEEK_OF_YEAR
        {0, 0, 1, 6                          }, // WEEK_OF_MONTH
        {1, 1, 5, 30                         }, // DAY_OF_MONTH
        {1, 1, 365, 366                      }, // DAY_OF_YEAR
        {/*                                */}, // DAY_OF_WEEK
        {-1, -1, 4, 6                        }, // DAY_OF_WEEK_IN_MONTH
        {/*                                */}, // AM_PM
        {/*                                */}, // HOUR
        {/*                                */}, // HOUR_OF_DAY
        {/*                                */}, // MINUTE
        {/*                                */}, // SECOND
        {/*                                */}, // MILLISECOND
        {/*                                */}, // ZONE_OFFSET
        {/*                                */}, // DST_OFFSET
        {-5838270, -5838270, 5828964, 5838271}, // YEAR_WOY
        {/*                                */}, // DOW_LOCAL
        {-5838269, -5838269, 5828963, 5838270}, // EXTENDED_YEAR
        {/*                                */}, // JULIAN_DAY
        {/*                                */}, // MILLISECONDS_IN_DAY
    };

    private static final int[][] ceMONTH_COUNT = {
        //len len2 st  st2
        {30, 30,   0,   0}, // Meskerem
        {30, 30,  30,  30}, // Tekemt 
        {30, 30,  60,  60}, // Hedar 
        {30, 30,  90,  90}, // Tahsas 
        {30, 30, 120, 120}, // Ter 
        {30, 30, 150, 150}, // Yekatit
        {30, 30, 180, 180}, // Megabit
        {30, 30, 210, 210}, // Miazia
        {30, 30, 240, 244}, // Genbot
        {30, 30, 270, 270}, // Sene 
        {30, 30, 300, 300}, // Hamle 
        {30, 30, 330, 330}, // Nehasse 
        { 5,  6, 360, 360}  // Pwagme
        // len  length of month
        // len2 length of month in a leap year
        // st   days in year before start of month
        // st2  days in year before month in leap year
    };
    
    // The Coptic and Ethiopic calendars differ only in their epochs.
    // We handle this by setting the jdOffset to the difference between
    // the Julian and Coptic or Ethiopic epoch.
    // This value is set in the class initialization phase of the two
    // subclasses, CopticCalendar and EthiopicCalendar
    protected int jdEpochOffset  = -1;
    

    protected int handleGetLimit(int field, int limitType) {
        return LIMITS[field][limitType];
    }
    
    //-------------------------------------------------------------------------
    // Constructors...
    //-------------------------------------------------------------------------

    /**
     * Constructs a default <code>CECalendar</code> using the current time
     * in the default time zone with the default locale.
     */
    protected CECalendar() {
        this(TimeZone.getDefault(), ULocale.getDefault());
    }

    /**
     * Constructs a <code>CECalendar</code> based on the current time
     * in the given time zone with the default locale.
     *
     * @param zone The time zone for the new calendar.
     */
    protected CECalendar(TimeZone zone) {
        this(zone, ULocale.getDefault());
    }

    /**
     * Constructs a <code>CECalendar</code> based on the current time
     * in the default time zone with the given locale.
     *
     * @param aLocale The locale for the new calendar.
     */
    protected CECalendar(Locale aLocale) {
        this(TimeZone.getDefault(), aLocale);
    }

    /**
     * Constructs a <code>CECalendar</code> based on the current time
     * in the default time zone with the given locale.
     *
     * @param locale The locale for the new calendar.
     */
    protected CECalendar(ULocale locale) {
        this(TimeZone.getDefault(), locale);
    }

    /**
     * Constructs a <code>CECalendar</code> based on the current time
     * in the given time zone with the given locale.
     *
     * @param zone The time zone for the new calendar.
     *
     * @param aLocale The locale for the new calendar.
     */
    protected CECalendar(TimeZone zone, Locale aLocale) {
        super(zone, aLocale);
        setTimeInMillis(System.currentTimeMillis());
    }

    /**
     * Constructs a <code>CECalendar</code> based on the current time
     * in the given time zone with the given locale.
     *
     * @param zone The time zone for the new calendar.
     *
     * @param locale The locale for the new calendar.
     */
    protected CECalendar(TimeZone zone, ULocale locale) {
        super(zone, locale);
        setTimeInMillis(System.currentTimeMillis());
    }

    /**
     * Constructs a <code>CECalendar</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} time field.
     *
     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
     *                  The value is 0-based. e.g., 0 for Tishri.
     *
     * @param date      The value used to set the calendar's {@link #DATE DATE} time field.
     */
    protected CECalendar(int year, int month, int date) {
        super(TimeZone.getDefault(), ULocale.getDefault());
        this.set(year, month, date);
    }

    /**
     * Constructs a <code>CECalendar</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.
     */
    protected CECalendar(Date date) {
        super(TimeZone.getDefault(), ULocale.getDefault());
        this.setTime(date);
    }

    /**
     * Constructs a <code>CECalendar</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.
     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
     *                  The value is 0-based. e.g., 0 for Tishri.
     * @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.
     */
    protected CECalendar(int year, int month, int date, int hour,
                         int minute, int second)
    {
        super(TimeZone.getDefault(), ULocale.getDefault());
        this.set(year, month, date, hour, minute, second);
    }
    
    
    //-------------------------------------------------------------------------
    // Calendar system Converstion methods...
    //-------------------------------------------------------------------------

    /**
     * @internal
     */
    protected int handleComputeMonthStart(int eyear,
                                          int emonth,
                                          boolean useMonth) {
        return ceToJD(eyear, emonth, 0, jdEpochOffset);
    }

    /**
     * @internal
     */
    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;
    }

    /**
     * @internal
     */
    protected void handleComputeFields(int julianDay) {
        Integer[] date = getDateFromJD(julianDay, jdEpochOffset);
        int _year  = date[0].intValue();
        int _month = date[1].intValue();
        int _day   = date[2].intValue();
        int ceyear = 0;

        // Do we want to use EthiopicCalendar.AA, .AM here?
        int era = GregorianCalendar.AD;
        if (_year < 0) { // dlf: this is what the test says to do
            era   = GregorianCalendar.BC;
            ceyear = 1 - _year;
        } else {
            ceyear = _year;
        }

        internalSet(MONTH, _month);
        internalSet(DAY_OF_MONTH, _day);
        internalSet(DAY_OF_YEAR, (30 * _month) + _day);
        internalSet(EXTENDED_YEAR, ceyear);
        internalSet(ERA, era);
        internalSet(YEAR, _year);
    }

    /**
     * @internal
     */
    public static int ceToJD(long year, int month, int date, int jdEpochOffset) {

        // Julian<->Ethiopic algorithms from:
        // "Calendars in Ethiopia", Berhanu Beyene, Manfred Kudlek, International Conference
        // of Ethiopian Studies XV, Hamburg, 2003

        return (int) (
            (jdEpochOffset+365)     // difference from Julian epoch to 1,1,1
            + 365 * (year - 1)      // number of days from years
            + quotient(year, 4)     // extra day of leap year
            + 30 * (month + 1)      // number of days from months
            + date                  // number of days for present month
            - 31                    // slack?
            );
    }

    /**
     * @internal
     * @deprecated This is a draft API and might change in a future release of ICU.
     */
    public static Integer[] getDateFromJD(int julianDay, int jdEpochOffset) {
        // 1461 is the number of days in 4 years
        long r4 = mod(julianDay - jdEpochOffset, 1461); // number of days within a 4 year period
        long  n = mod(r4, 365) + 365 * quotient(r4, 1460);  // days in present year

        long aprime = 4   // number of years in the leap year cycle
            * quotient(julianDay - jdEpochOffset, 1461)  // number of 4 year periods between epochs?
            + quotient(r4, 365)   // number of regular years?
            - quotient(r4, 1460)  // number of 4 year periods?
            - 1;

        int _year   = (int) (aprime + 1);
        int _month  = (int) (quotient(n, 30));
        int _day    = mod(n, 30) + 1;

        return new Integer[]{ new Integer(_year), new Integer(_month), new Integer(_day) };
    }
 
    /**
     * These utility functions can be replaced by equivalent 
     * functions from ICU if available.
     */
    static int mod(long i, int j) {
        return (int) (i - (long) j * quotient(i, j));
    }
    
    static int quotient(long i, int j) {
        return (int) Math.floor((double) i / j);
    }
}
