// © 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"

/**
 * \def NUMSYS_NAME_CAPACITY
 * Size of a numbering system name.
 * @internal
 */
#define NUMSYS_NAME_CAPACITY 8


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

#if !UCONFIG_NO_FORMATTING


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

U_NAMESPACE_BEGIN

/**
 * 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.
     * @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
     * @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[NUMSYS_NAME_CAPACITY+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 // _NUMSYS
//eof
