// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING
#ifndef __NUMBER_PATTERNMODIFIER_H__
#define __NUMBER_PATTERNMODIFIER_H__

#include "standardplural.h"
#include "unicode/numberformatter.h"
#include "number_patternstring.h"
#include "number_types.h"
#include "number_modifiers.h"
#include "number_utils.h"
#include "number_currencysymbols.h"

U_NAMESPACE_BEGIN

// Export an explicit template instantiation of the LocalPointer that is used as a
// data member of AdoptingModifierStore.
// (When building DLLs for Windows this is required.)
#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
#if defined(_MSC_VER)
// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
#pragma warning(push)
#pragma warning(disable : 4661)
#endif
template class U_I18N_API LocalPointerBase<number::impl::AdoptingModifierStore>;
template class U_I18N_API LocalPointer<number::impl::AdoptingModifierStore>;
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif

namespace number {
namespace impl {

// Forward declaration
class MutablePatternModifier;

// Exported as U_I18N_API because it is needed for the unit test PatternModifierTest
class U_I18N_API ImmutablePatternModifier : public MicroPropsGenerator, public UMemory {
  public:
    ~ImmutablePatternModifier() U_OVERRIDE = default;

    void processQuantity(DecimalQuantity&, MicroProps& micros, UErrorCode& status) const U_OVERRIDE;

    void applyToMicros(MicroProps& micros, const DecimalQuantity& quantity, UErrorCode& status) const;

    const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const;

    // Non-const method:
    void addToChain(const MicroPropsGenerator* parent);

  private:
    ImmutablePatternModifier(AdoptingModifierStore* pm, const PluralRules* rules);

    const LocalPointer<AdoptingModifierStore> pm;
    const PluralRules* rules;
    const MicroPropsGenerator* parent;

    friend class MutablePatternModifier;
};

/**
 * This class is a {@link Modifier} that wraps a decimal format pattern. It applies the pattern's affixes in
 * {@link Modifier#apply}.
 *
 * <p>
 * In addition to being a Modifier, this class contains the business logic for substituting the correct locale symbols
 * into the affixes of the decimal format pattern.
 *
 * <p>
 * In order to use this class, create a new instance and call the following four setters: {@link #setPatternInfo},
 * {@link #setPatternAttributes}, {@link #setSymbols}, and {@link #setNumberProperties}. After calling these four
 * setters, the instance will be ready for use as a Modifier.
 *
 * <p>
 * This is a MUTABLE, NON-THREAD-SAFE class designed for performance. Do NOT save references to this or attempt to use
 * it from multiple threads! Instead, you can obtain a safe, immutable decimal format pattern modifier by calling
 * {@link MutablePatternModifier#createImmutable}, in effect treating this instance as a builder for the immutable
 * variant.
 */
class U_I18N_API MutablePatternModifier
        : public MicroPropsGenerator,
          public Modifier,
          public SymbolProvider,
          public UMemory {
  public:

    ~MutablePatternModifier() U_OVERRIDE = default;

    /**
     * @param isStrong
     *            Whether the modifier should be considered strong. For more information, see
     *            {@link Modifier#isStrong()}. Most of the time, decimal format pattern modifiers should be considered
     *            as non-strong.
     */
    explicit MutablePatternModifier(bool isStrong);

    /**
     * Sets a reference to the parsed decimal format pattern, usually obtained from
     * {@link PatternStringParser#parseToPatternInfo(String)}, but any implementation of {@link AffixPatternProvider} is
     * accepted.
     *
     * @param field
     *            Which field to use for literal characters in the pattern.
     */
    void setPatternInfo(const AffixPatternProvider *patternInfo, Field field);

    /**
     * Sets attributes that imply changes to the literal interpretation of the pattern string affixes.
     *
     * @param signDisplay
     *            Whether to force a plus sign on positive numbers.
     * @param perMille
     *            Whether to substitute the percent sign in the pattern with a permille sign.
     */
    void setPatternAttributes(UNumberSignDisplay signDisplay, bool perMille);

    /**
     * Sets locale-specific details that affect the symbols substituted into the pattern string affixes.
     *
     * @param symbols
     *            The desired instance of DecimalFormatSymbols.
     * @param currency
     *            The currency to be used when substituting currency values into the affixes.
     * @param unitWidth
     *            The width used to render currencies.
     * @param rules
     *            Required if the triple currency sign, "¤¤¤", appears in the pattern, which can be determined from the
     *            convenience method {@link #needsPlurals()}.
     * @param status
     *            Set if an error occurs while loading currency data.
     */
    void setSymbols(const DecimalFormatSymbols* symbols, const CurrencyUnit& currency,
                    UNumberUnitWidth unitWidth, const PluralRules* rules, UErrorCode& status);

    /**
     * Sets attributes of the current number being processed.
     *
     * @param signum
     *            -1 if negative; +1 if positive; or 0 if zero.
     * @param plural
     *            The plural form of the number, required only if the pattern contains the triple
     *            currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}).
     */
    void setNumberProperties(Signum signum, StandardPlural::Form plural);

    /**
     * Returns true if the pattern represented by this MurkyModifier requires a plural keyword in order to localize.
     * This is currently true only if there is a currency long name placeholder in the pattern ("¤¤¤").
     */
    bool needsPlurals() const;

    /**
     * Creates a new quantity-dependent Modifier that behaves the same as the current instance, but which is immutable
     * and can be saved for future use. The number properties in the current instance are mutated; all other properties
     * are left untouched.
     *
     * <p>
     * The resulting modifier cannot be used in a QuantityChain.
     *
     * <p>
     * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
     *
     * @return An immutable that supports both positive and negative numbers.
     */
    ImmutablePatternModifier *createImmutable(UErrorCode &status);

    MicroPropsGenerator &addToChain(const MicroPropsGenerator *parent);

    void processQuantity(DecimalQuantity &, MicroProps &micros, UErrorCode &status) const U_OVERRIDE;

    int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
                  UErrorCode &status) const U_OVERRIDE;

    int32_t getPrefixLength() const U_OVERRIDE;

    int32_t getCodePointCount() const U_OVERRIDE;

    bool isStrong() const U_OVERRIDE;

    bool containsField(Field field) const U_OVERRIDE;

    void getParameters(Parameters& output) const U_OVERRIDE;

    bool semanticallyEquivalent(const Modifier& other) const U_OVERRIDE;

    /**
     * Returns the string that substitutes a given symbol type in a pattern.
     */
    UnicodeString getSymbol(AffixPatternType type) const U_OVERRIDE;

    UnicodeString toUnicodeString() const;

  private:
    // Modifier details (initialized in constructor)
    const bool fStrong;

    // Pattern details (initialized in setPatternInfo and setPatternAttributes)
    const AffixPatternProvider *fPatternInfo;
    Field fField;
    UNumberSignDisplay fSignDisplay;
    bool fPerMilleReplacesPercent;

    // Symbol details (initialized in setSymbols)
    const DecimalFormatSymbols *fSymbols;
    UNumberUnitWidth fUnitWidth;
    CurrencySymbols fCurrencySymbols;
    const PluralRules *fRules;

    // Number details (initialized in setNumberProperties)
    Signum fSignum;
    StandardPlural::Form fPlural;

    // QuantityChain details (initialized in addToChain)
    const MicroPropsGenerator *fParent;

    // Transient fields for rendering
    UnicodeString currentAffix;

    /**
     * Uses the current properties to create a single {@link ConstantMultiFieldModifier} with currency spacing support
     * if required.
     *
     * <p>
     * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
     *
     * @param a
     *            A working FormattedStringBuilder object; passed from the outside to prevent the need to create many new
     *            instances if this method is called in a loop.
     * @param b
     *            Another working FormattedStringBuilder object.
     * @return The constant modifier object.
     */
    ConstantMultiFieldModifier *createConstantModifier(UErrorCode &status);

    int32_t insertPrefix(FormattedStringBuilder &sb, int position, UErrorCode &status);

    int32_t insertSuffix(FormattedStringBuilder &sb, int position, UErrorCode &status);

    void prepareAffix(bool isPrefix);
};


}  // namespace impl
}  // namespace number
U_NAMESPACE_END

#endif //__NUMBER_PATTERNMODIFIER_H__

#endif /* #if !UCONFIG_NO_FORMATTING */
