// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2009-2015, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
#ifndef CURRPINF_H
#define CURRPINF_H

#include "unicode/utypes.h"

/**
 * \file
 * \brief C++ API: Currency Plural Information used by Decimal Format
 */

#if !UCONFIG_NO_FORMATTING

#include "unicode/unistr.h"

U_NAMESPACE_BEGIN

class Locale;
class PluralRules;
class Hashtable;

/**
 * This class represents the information needed by 
 * DecimalFormat to format currency plural, 
 * such as "3.00 US dollars" or "1.00 US dollar". 
 * DecimalFormat creates for itself an instance of
 * CurrencyPluralInfo from its locale data.  
 * If you need to change any of these symbols, you can get the
 * CurrencyPluralInfo object from your 
 * DecimalFormat and modify it.
 *
 * Following are the information needed for currency plural format and parse:
 * locale information,
 * plural rule of the locale,
 * currency plural pattern of the locale.
 *
 * @stable ICU 4.2
 */
class  U_I18N_API CurrencyPluralInfo : public UObject {
public:

    /**
     * Create a CurrencyPluralInfo object for the default locale.
     * @param status output param set to success/failure code on exit
     * @stable ICU 4.2
     */
    CurrencyPluralInfo(UErrorCode& status);

    /**
     * Create a CurrencyPluralInfo object for the given locale.
     * @param locale the locale
     * @param status output param set to success/failure code on exit
     * @stable ICU 4.2
     */
    CurrencyPluralInfo(const Locale& locale, UErrorCode& status); 

    /**
     * Copy constructor
     *
     * @stable ICU 4.2
     */
    CurrencyPluralInfo(const CurrencyPluralInfo& info);


    /**
     * Assignment operator
     *
     * @stable ICU 4.2
     */
    CurrencyPluralInfo& operator=(const CurrencyPluralInfo& info);


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


    /**
     * Equal operator.
     *
     * @stable ICU 4.2
     */
    UBool operator==(const CurrencyPluralInfo& info) const;


    /**
     * Not equal operator
     *
     * @stable ICU 4.2
     */
    UBool operator!=(const CurrencyPluralInfo& info) const;


    /**
     * Clone
     *
     * @stable ICU 4.2
     */
    CurrencyPluralInfo* clone() const;


    /**
     * Gets plural rules of this locale, used for currency plural format
     *
     * @return plural rule
     * @stable ICU 4.2
     */
    const PluralRules* getPluralRules() const;

    /**
     * Given a plural count, gets currency plural pattern of this locale, 
     * used for currency plural format
     *
     * @param  pluralCount currency plural count
     * @param  result      output param to receive the pattern
     * @return a currency plural pattern based on plural count
     * @stable ICU 4.2
     */
    UnicodeString& getCurrencyPluralPattern(const UnicodeString& pluralCount,
                                            UnicodeString& result) const; 

    /**
     * Get locale 
     *
     * @return locale
     * @stable ICU 4.2
     */
    const Locale& getLocale() const;

    /**
     * Set plural rules.
     * The plural rule is set when CurrencyPluralInfo
     * instance is created.
     * You can call this method to reset plural rules only if you want
     * to modify the default plural rule of the locale.
     *
     * @param ruleDescription new plural rule description
     * @param status output param set to success/failure code on exit
     * @stable ICU 4.2
     */
    void setPluralRules(const UnicodeString& ruleDescription,
                        UErrorCode& status);

    /**
     * Set currency plural pattern.
     * The currency plural pattern is set when CurrencyPluralInfo
     * instance is created.
     * You can call this method to reset currency plural pattern only if 
     * you want to modify the default currency plural pattern of the locale.
     *
     * @param pluralCount the plural count for which the currency pattern will 
     *                    be overridden.
     * @param pattern     the new currency plural pattern
     * @param status      output param set to success/failure code on exit
     * @stable ICU 4.2
     */
    void setCurrencyPluralPattern(const UnicodeString& pluralCount, 
                                  const UnicodeString& pattern,
                                  UErrorCode& status);

    /**
     * Set locale
     *
     * @param loc     the new locale to set
     * @param status  output param set to success/failure code on exit
     * @stable ICU 4.2
     */
    void setLocale(const Locale& loc, UErrorCode& status);

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

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

private:
    friend class DecimalFormat;
    friend class DecimalFormatImpl;

    void initialize(const Locale& loc, UErrorCode& status);
   
    void setupCurrencyPluralPattern(const Locale& loc, UErrorCode& status);

    /*
     * delete hash table
     *
     * @param hTable  hash table to be deleted
     */
    void deleteHash(Hashtable* hTable);


    /*
     * initialize hash table
     *
     * @param status   output param set to success/failure code on exit
     * @return         hash table initialized
     */
    Hashtable* initHash(UErrorCode& status);



    /**
     * copy hash table
     *
     * @param source   the source to copy from
     * @param target   the target to copy to
     * @param status   error code
     */
    void copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status);

    //-------------------- private data member ---------------------
    // map from plural count to currency plural pattern, for example
    // a plural pattern defined in "CurrencyUnitPatterns" is
    // "one{{0} {1}}", in which "one" is a plural count
    // and "{0} {1}" is a currency plural pattern".
    // The currency plural pattern saved in this mapping is the pattern
    // defined in "CurrencyUnitPattern" by replacing
    // {0} with the number format pattern,
    // and {1} with 3 currency sign.
    Hashtable* fPluralCountToCurrencyUnitPattern;

    /*
     * The plural rule is used to format currency plural name,
     * for example: "3.00 US Dollars".
     * If there are 3 currency signs in the currency patttern,
     * the 3 currency signs will be replaced by currency plural name.
     */
    PluralRules* fPluralRules;

    // locale
    Locale* fLocale;
};


inline UBool
CurrencyPluralInfo::operator!=(const CurrencyPluralInfo& info) const {              return !operator==(info);                                                   }  

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

#endif // _CURRPINFO
//eof
