// © 2018 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_MAPPER_H__
#define __NUMBER_MAPPER_H__

#include <atomic>
#include "number_types.h"
#include "unicode/currpinf.h"
#include "standardplural.h"
#include "number_patternstring.h"
#include "number_currencysymbols.h"
#include "numparse_impl.h"

U_NAMESPACE_BEGIN
namespace number {
namespace impl {


class PropertiesAffixPatternProvider : public AffixPatternProvider, public UMemory {
  public:
    bool isBogus() const {
        return fBogus;
    }

    void setToBogus() {
        fBogus = true;
    }

    void setTo(const DecimalFormatProperties& properties, UErrorCode& status);

    PropertiesAffixPatternProvider() = default; // puts instance in valid but undefined state

    PropertiesAffixPatternProvider(const DecimalFormatProperties& properties, UErrorCode& status) {
        setTo(properties, status);
    }

    // AffixPatternProvider Methods:

    char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE;

    int32_t length(int32_t flags) const U_OVERRIDE;

    UnicodeString getString(int32_t flags) const U_OVERRIDE;

    bool hasCurrencySign() const U_OVERRIDE;

    bool positiveHasPlusSign() const U_OVERRIDE;

    bool hasNegativeSubpattern() const U_OVERRIDE;

    bool negativeHasMinusSign() const U_OVERRIDE;

    bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE;

    bool hasBody() const U_OVERRIDE;

  private:
    UnicodeString posPrefix;
    UnicodeString posSuffix;
    UnicodeString negPrefix;
    UnicodeString negSuffix;

    const UnicodeString& getStringInternal(int32_t flags) const;

    bool fBogus{true};
};


class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMemory {
  public:
    bool isBogus() const {
        return fBogus;
    }

    void setToBogus() {
        fBogus = true;
    }

    void setTo(const CurrencyPluralInfo& cpi, const DecimalFormatProperties& properties,
               UErrorCode& status);

    // AffixPatternProvider Methods:

    char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE;

    int32_t length(int32_t flags) const U_OVERRIDE;

    UnicodeString getString(int32_t flags) const U_OVERRIDE;

    bool hasCurrencySign() const U_OVERRIDE;

    bool positiveHasPlusSign() const U_OVERRIDE;

    bool hasNegativeSubpattern() const U_OVERRIDE;

    bool negativeHasMinusSign() const U_OVERRIDE;

    bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE;

    bool hasBody() const U_OVERRIDE;

  private:
    PropertiesAffixPatternProvider affixesByPlural[StandardPlural::COUNT];

    bool fBogus{true};
};


/**
 * A struct for ownership of a few objects needed for formatting.
 */
struct DecimalFormatWarehouse {
    PropertiesAffixPatternProvider propertiesAPP;
    CurrencyPluralInfoAffixProvider currencyPluralInfoAPP;
    CurrencySymbols currencySymbols;
};


/**
* Internal fields for DecimalFormat.
* TODO: Make some of these fields by value instead of by LocalPointer?
*/
struct DecimalFormatFields : public UMemory {
    /** The property bag corresponding to user-specified settings and settings from the pattern string. */
    LocalPointer<DecimalFormatProperties> properties;

    /** The symbols for the current locale. */
    LocalPointer<const DecimalFormatSymbols> symbols;

    /**
    * The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link
    * #format} method uses the formatter directly without needing to synchronize.
    */
    LocalPointer<const LocalizedNumberFormatter> formatter;

    /** The lazy-computed parser for .parse() */
    std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {};

    /** The lazy-computed parser for .parseCurrency() */
    std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicCurrencyParser = {};

    /** Small object ownership warehouse for the formatter and parser */
    DecimalFormatWarehouse warehouse;

    /** The effective properties as exported from the formatter object. Used by some getters. */
    LocalPointer<DecimalFormatProperties> exportedProperties;

    // Data for fastpath
    bool canUseFastFormat = false;
    struct FastFormatData {
        char16_t cpZero;
        char16_t cpGroupingSeparator;
        char16_t cpMinusSign;
        int8_t minInt;
        int8_t maxInt;
    } fastData;
};


/**
 * Utilities for converting between a DecimalFormatProperties and a MacroProps.
 */
class NumberPropertyMapper {
  public:
    /** Convenience method to create a NumberFormatter directly from Properties. */
    static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
                                             const DecimalFormatSymbols& symbols,
                                             DecimalFormatWarehouse& warehouse, UErrorCode& status);

    /** Convenience method to create a NumberFormatter directly from Properties. */
    static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
                                             const DecimalFormatSymbols& symbols,
                                             DecimalFormatWarehouse& warehouse,
                                             DecimalFormatProperties& exportedProperties,
                                             UErrorCode& status);

    /**
     * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties}
     * object. In other words, maps Properties to MacroProps. This function is used by the
     * JDK-compatibility API to call into the ICU 60 fluent number formatting pipeline.
     *
     * @param properties
     *            The property bag to be mapped.
     * @param symbols
     *            The symbols associated with the property bag.
     * @param exportedProperties
     *            A property bag in which to store validated properties. Used by some DecimalFormat
     *            getters.
     * @return A new MacroProps containing all of the information in the Properties.
     */
    static MacroProps oldToNew(const DecimalFormatProperties& properties,
                               const DecimalFormatSymbols& symbols, DecimalFormatWarehouse& warehouse,
                               DecimalFormatProperties* exportedProperties, UErrorCode& status);
};


} // namespace impl
} // namespace numparse
U_NAMESPACE_END

#endif //__NUMBER_MAPPER_H__
#endif /* #if !UCONFIG_NO_FORMATTING */
