// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 2003 - 2013, International Business Machines Corporation and  *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/

#ifndef ETHPCCAL_H
#define ETHPCCAL_H

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/calendar.h"
#include "cecal.h"

U_NAMESPACE_BEGIN

/**
 * Implement the Ethiopic calendar system.
 * @internal
 */
class EthiopicCalendar : public CECalendar {

public:
    /**
     * Calendar type - use Amete Alem era for all the time or not
     * @internal 
     */
    enum EEraType {
        AMETE_MIHRET_ERA,
        AMETE_ALEM_ERA
    };

    /**
     * Useful constants for EthiopicCalendar.
     * @internal
     */
    enum EMonths {
        /** 
         * Constant for &#x1218;&#x1235;&#x12a8;&#x1228;&#x121d;, the 1st month of the Ethiopic year.
         */
        MESKEREM,

        /** 
         * Constant for &#x1325;&#x1245;&#x121d;&#x1275;, the 2nd month of the Ethiopic year.
         */
        TEKEMT,

        /** 
         * Constant for &#x1285;&#x12f3;&#x122d;, the 3rd month of the Ethiopic year. 
         */
        HEDAR,

        /** 
         * Constant for &#x1273;&#x1285;&#x1223;&#x1225;, the 4th month of the Ethiopic year. 
         */
        TAHSAS,

        /** 
         * Constant for &#x1325;&#x122d;, the 5th month of the Ethiopic year. 
         */
        TER,

        /** 
         * Constant for &#x12e8;&#x12ab;&#x1272;&#x1275;, the 6th month of the Ethiopic year. 
         */
        YEKATIT,

        /** 
         * Constant for &#x1218;&#x130b;&#x1262;&#x1275;, the 7th month of the Ethiopic year. 
         */
        MEGABIT,

        /** 
         * Constant for &#x121a;&#x12eb;&#x12dd;&#x12eb;, the 8th month of the Ethiopic year. 
         */
        MIAZIA,

        /** 
         * Constant for &#x130d;&#x1295;&#x1266;&#x1275;, the 9th month of the Ethiopic year. 
         */
        GENBOT,

        /** 
         * Constant for &#x1230;&#x1294;, the 10th month of the Ethiopic year. 
         */
        SENE,

        /** 
         * Constant for &#x1210;&#x121d;&#x120c;, the 11th month of the Ethiopic year. 
         */
        HAMLE,

        /** 
         * Constant for &#x1290;&#x1210;&#x1234;, the 12th month of the Ethiopic year. 
         */
        NEHASSA,

        /** 
         * Constant for &#x1333;&#x1309;&#x121c;&#x1295;, the 13th month of the Ethiopic year. 
         */
        PAGUMEN
    };

    enum EEras {
        AMETE_ALEM,     // Before the epoch
        AMETE_MIHRET    // After the epoch
    };

    /**
     * Constructs a EthiopicCalendar based on the current time in the default time zone
     * with the given locale.
     *
     * @param aLocale  The given locale.
     * @param success  Indicates the status of EthiopicCalendar object construction.
     *                 Returns U_ZERO_ERROR if constructed successfully.
     * @param type     Whether this Ethiopic calendar use Amete Mihrret (default) or
     *                 only use Amete Alem for all the time.
     * @internal
     */
    EthiopicCalendar(const Locale& aLocale, UErrorCode& success, EEraType type = AMETE_MIHRET_ERA);

    /**
     * Copy Constructor
     * @internal
     */
    EthiopicCalendar(const EthiopicCalendar& other);

    /**
     * Destructor.
     * @internal
     */
    virtual ~EthiopicCalendar();

    /**
     * Create and return a polymorphic copy of this calendar.
     * @return    return a polymorphic copy of this calendar.
     * @internal
     */
    virtual EthiopicCalendar* clone() const;

    /**
     * return the calendar type, "ethiopic"
     * @return calendar type
     * @internal
     */
    virtual const char * getType() const;

    /**
     * Set Alem or Mihret era.
     * @param onOff Set Amete Alem era if true, otherwise set Amete Mihret era.
     * @internal
     */
    void setAmeteAlemEra (UBool onOff);

    /**
     * Return true if this calendar is set to the Amete Alem era.
     * @return true if set to the Amete Alem era.
     * @internal
     */
    UBool isAmeteAlemEra() const;

protected:
    //-------------------------------------------------------------------------
    // Calendar framework
    //-------------------------------------------------------------------------

    /**
     * Return the extended year defined by the current fields.
     * @internal
     */
    virtual int32_t handleGetExtendedYear();

    /**
     * Compute fields from the JD
     * @internal
     */
    virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);

    /**
     * Calculate the limit for a specified type of limit and field
     * @internal
     */
    virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;

    /**
     * Returns the date of the start of the default century
     * @return start of century - in milliseconds since epoch, 1970
     * @internal
     */
    virtual UDate defaultCenturyStart() const;

    /**
     * Returns the year in which the default century begins
     * @internal
     */
    virtual int32_t defaultCenturyStartYear() const;

    /**
     * Return the date offset from Julian
     * @internal
     */
    virtual int32_t getJDEpochOffset() const;

private:
    /**
     * When eraType is AMETE_ALEM_ERA, then this calendar use only AMETE_ALEM
     * for the era. Otherwise (default), this calendar uses both AMETE_ALEM
     * and AMETE_MIHRET.
     *
     * EXTENDED_YEAR        AMETE_ALEM_ERA     AMETE_MIHRET_ERA
     *             0       Amete Alem 5500      Amete Alem 5500
     *             1        Amete Mihret 1      Amete Alem 5501
     */
    EEraType eraType;

public:
    /**
     * Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
     * override. This method is to implement a simple version of RTTI, since not all C++
     * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
     * this method.
     *
     * @return   The class ID for this object. All objects of a given class have the
     *           same class ID. Objects of other classes have different class IDs.
     * @internal
     */
    virtual UClassID getDynamicClassID(void) const;

    /**
     * Return the class ID for this class. This is useful only for comparing to a return
     * value from getDynamicClassID(). For example:
     *
     *      Base* polymorphic_pointer = createPolymorphicObject();
     *      if (polymorphic_pointer->getDynamicClassID() ==
     *          Derived::getStaticClassID()) ...
     *
     * @return   The class ID for all objects of this class.
     * @internal
     */
    U_I18N_API static UClassID U_EXPORT2 getStaticClassID(void);  

#if 0
// We do not want to introduce this API in ICU4C.
// It was accidentally introduced in ICU4J as a public API.

public:
    //-------------------------------------------------------------------------
    // Calendar system Conversion methods...
    //-------------------------------------------------------------------------

    /**
     * Convert an Ethiopic year, month, and day to a Julian day.
     *
     * @param year the extended year
     * @param month the month
     * @param day the day
     * @return Julian day
     * @internal
     */
    int32_t ethiopicToJD(int32_t year, int32_t month, int32_t day);
#endif
};

U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
#endif /* ETHPCCAL_H */
//eof
