// © 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 currencySymbols
     *            The currency symbols 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()}.
     */
    void setSymbols(const DecimalFormatSymbols* symbols, const CurrencySymbols* currencySymbols,
                    UNumberUnitWidth unitWidth, const PluralRules* rules);

    /**
     * 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(UNumberFormatFields 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;
    const 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 */
