// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 2010-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
*
* File NUMSYS.H
*
* Modification History:*
*   Date        Name        Description
*
********************************************************************************
*/

#ifndef NUMSYS
#define NUMSYS

#include "unicode/utypes.h"

#if U_SHOW_CPLUSPLUS_API

/**
 * \file
 * \brief C++ API: NumberingSystem object
 */

#if !UCONFIG_NO_FORMATTING

#include "unicode/format.h"
#include "unicode/uobject.h"

U_NAMESPACE_BEGIN

// can't be #ifndef U_HIDE_INTERNAL_API; needed for char[] field size
/**
 * Size of a numbering system name.
 * @internal
 */
constexpr const size_t kInternalNumSysNameCapacity = 8;

/**
 * Defines numbering systems. A numbering system describes the scheme by which 
 * numbers are to be presented to the end user.  In its simplest form, a numbering
 * system describes the set of digit characters that are to be used to display
 * numbers, such as Western digits, Thai digits, Arabic-Indic digits, etc., in a
 * positional numbering system with a specified radix (typically 10).
 * More complicated numbering systems are algorithmic in nature, and require use
 * of an RBNF formatter ( rule based number formatter ), in order to calculate
 * the characters to be displayed for a given number.  Examples of algorithmic
 * numbering systems include Roman numerals, Chinese numerals, and Hebrew numerals.
 * Formatting rules for many commonly used numbering systems are included in
 * the ICU package, based on the numbering system rules defined in CLDR.
 * Alternate numbering systems can be specified to a locale by using the
 * numbers locale keyword.
 */

class U_I18N_API NumberingSystem : public UObject {
public:

    /**
     * Default Constructor.
     *
     * @stable ICU 4.2
     */
    NumberingSystem();

    /**
     * Copy constructor.
     * @stable ICU 4.2
     */
    NumberingSystem(const NumberingSystem& other);

    /**
     * Destructor.
     * @stable ICU 4.2
     */
    virtual ~NumberingSystem();

    /**
     * Create the default numbering system associated with the specified locale.
     * @param inLocale The given locale.
     * @param status ICU status
     * @stable ICU 4.2
     */
    static NumberingSystem* U_EXPORT2 createInstance(const Locale & inLocale, UErrorCode& status);

    /**
     * Create the default numbering system associated with the default locale.
     * @stable ICU 4.2
     */
    static NumberingSystem* U_EXPORT2 createInstance(UErrorCode& status);

    /**
     * Create a numbering system using the specified radix, type, and description. 
     * @param radix         The radix (base) for this numbering system.
     * @param isAlgorithmic TRUE if the numbering system is algorithmic rather than numeric.
     * @param description   The string representing the set of digits used in a numeric system, or the name of the RBNF
     *                      ruleset to be used in an algorithmic system.
     * @param status ICU status
     * @stable ICU 4.2
     */
    static NumberingSystem* U_EXPORT2 createInstance(int32_t radix, UBool isAlgorithmic, const UnicodeString& description, UErrorCode& status );

    /**
     * Return a StringEnumeration over all the names of numbering systems known to ICU.
     * The numbering system names will be in alphabetical (invariant) order.
     *
     * The returned StringEnumeration is owned by the caller, who must delete it when
     * finished with it.
     *
     * @stable ICU 4.2
     */
     static StringEnumeration * U_EXPORT2 getAvailableNames(UErrorCode& status);

    /**
     * Create a numbering system from one of the predefined numbering systems specified
     * by CLDR and known to ICU, such as "latn", "arabext", or "hanidec"; the full list
     * is returned by unumsys_openAvailableNames. Note that some of the names listed at
     * http://unicode.org/repos/cldr/tags/latest/common/bcp47/number.xml - e.g.
     * default, native, traditional, finance - do not identify specific numbering systems,
     * but rather key values that may only be used as part of a locale, which in turn
     * defines how they are mapped to a specific numbering system such as "latn" or "hant".
     *
     * @param name   The name of the numbering system.
     * @param status ICU status; set to U_UNSUPPORTED_ERROR if numbering system not found.
     * @return The NumberingSystem instance, or nullptr if not found.
     * @stable ICU 4.2
     */
    static NumberingSystem* U_EXPORT2 createInstanceByName(const char* name, UErrorCode& status);


    /**
     * Returns the radix of this numbering system. Simple positional numbering systems
     * typically have radix 10, but might have a radix of e.g. 16 for hexadecimal. The
     * radix is less well-defined for non-positional algorithmic systems.
     * @stable ICU 4.2
     */
    int32_t getRadix() const;

    /**
     * Returns the name of this numbering system if it was created using one of the predefined names
     * known to ICU.  Otherwise, returns NULL.
     * The predefined names are identical to the numbering system names as defined by
     * the BCP47 definition in Unicode CLDR.
     * See also, http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/number.xml
     * @stable ICU 4.6
     */
    const char * getName() const;

    /**
     * Returns the description string of this numbering system. For simple
     * positional systems this is the ordered string of digits (with length matching
     * the radix), e.g. "\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D"
     * for "hanidec"; it would be "0123456789ABCDEF" for hexadecimal. For
     * algorithmic systems this is the name of the RBNF ruleset used for formatting,
     * e.g. "zh/SpelloutRules/%spellout-cardinal" for "hans" or "%greek-upper" for
     * "grek".
     * @stable ICU 4.2
     */
    virtual UnicodeString getDescription() const;



    /**
     * Returns TRUE if the given numbering system is algorithmic
     *
     * @return         TRUE if the numbering system is algorithmic.
     *                 Otherwise, return FALSE.
     * @stable ICU 4.2
     */
    UBool isAlgorithmic() const;

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @stable ICU 4.2
     *
    */
    static UClassID U_EXPORT2 getStaticClassID(void);

    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @stable ICU 4.2
     */
    virtual UClassID getDynamicClassID() const;


private:
    UnicodeString   desc;
    int32_t         radix;
    UBool           algorithmic;
    char            name[kInternalNumSysNameCapacity+1];

    void setRadix(int32_t radix);

    void setAlgorithmic(UBool algorithmic);

    void setDesc(const UnicodeString &desc);

    void setName(const char* name);

    static UBool isValidDigitString(const UnicodeString &str);

    UBool hasContiguousDecimalDigits() const;
};

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

#endif /* U_SHOW_CPLUSPLUS_API */

#endif // _NUMSYS
//eof
