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

#ifndef VALUEFORMATTER_H
#define VALUEFORMATTER_H

#if !UCONFIG_NO_FORMATTING

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



U_NAMESPACE_BEGIN

class UnicodeString;
class DigitList;
class FieldPositionHandler;
class DigitGrouping;
class PluralRules;
class FixedPrecision;
class DigitFormatter;
class DigitFormatterOptions;
class ScientificPrecision;
class SciFormatterOptions;
class FixedDecimal;
class VisibleDigitsWithExponent;


/**
 * A closure around rounding and formatting a value. As these instances are
 * designed to be short lived (they only exist while formatting a value), they
 * do not own their own attributes. Rather the caller maintains ownership of
 * all attributes. A caller first calls a prepareXXX method on an instance
 * to share its data before using that instance. Using an
 * instance without first calling a prepareXXX method results in an
 * assertion error and a program crash.
 */
class U_I18N_API ValueFormatter : public UObject {
public:
    ValueFormatter() : fType(kFormatTypeCount) {
    }

    virtual ~ValueFormatter();

    /**
     * This function is here only to support the protected round() method
     * in DecimalFormat. It serves no ther purpose than that.
     *
     * @param value this value is rounded in place.
     * @param status any error returned here.
     */
    DigitList &round(DigitList &value, UErrorCode &status) const;

    /**
     * Returns TRUE if the absolute value of value can be fast formatted
     * using ValueFormatter::formatInt32.
     */
    UBool isFastFormattable(int32_t value) const;

    /**
     * Converts value to a VisibleDigitsWithExponent.
     * Result may be fixed point or scientific.
     */
    VisibleDigitsWithExponent &toVisibleDigitsWithExponent(
            int64_t value,
            VisibleDigitsWithExponent &digits,
            UErrorCode &status) const;

    /**
     * Converts value to a VisibleDigitsWithExponent.
     * Result may be fixed point or scientific.
     */
    VisibleDigitsWithExponent &toVisibleDigitsWithExponent(
            DigitList &value,
            VisibleDigitsWithExponent &digits,
            UErrorCode &status) const;

    /**
     * formats positiveValue and appends to appendTo. Returns appendTo.
     * @param positiveValue If negative, no negative sign is formatted.
     * @param handler stores the field positions
     * @param appendTo formatted value appended here.
     */
    UnicodeString &format(
        const VisibleDigitsWithExponent &positiveValue,
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const;


    /**
     * formats positiveValue and appends to appendTo. Returns appendTo.
     * value must be positive. Calling formatInt32 to format a value when
     * isFastFormattable indicates that the value cannot be fast formatted
     * results in undefined behavior.
     */
    UnicodeString &formatInt32(
        int32_t positiveValue,
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const;

    /**
     * Returns the number of code points needed to format.
     * @param positiveValue if negative, the negative sign is not included
     *   in count.
     */
    int32_t countChar32(
            const VisibleDigitsWithExponent &positiveValue) const;
  
    /**
     * Prepares this instance for fixed decimal formatting.
     */
    void prepareFixedDecimalFormatting(
        const DigitFormatter &formatter,
        const DigitGrouping &grouping,
        const FixedPrecision &precision,
        const DigitFormatterOptions &options);

    /**
     * Prepares this instance for scientific formatting.
     */
    void prepareScientificFormatting(
        const DigitFormatter &formatter,
        const ScientificPrecision &precision,
        const SciFormatterOptions &options);

private:
    ValueFormatter(const ValueFormatter &);
    ValueFormatter &operator=(const ValueFormatter &);
    enum FormatType {
        kFixedDecimal,
        kScientificNotation,
        kFormatTypeCount
    };

    FormatType fType;

    // for fixed decimal and scientific formatting
    const DigitFormatter *fDigitFormatter;

    // for fixed decimal formatting
    const FixedPrecision *fFixedPrecision;
    const DigitFormatterOptions *fFixedOptions;
    const DigitGrouping *fGrouping;

    // for scientific formatting
    const ScientificPrecision *fScientificPrecision;
    const SciFormatterOptions *fScientificOptions;
};

U_NAMESPACE_END

#endif /* !UCONFIG_NO_FORMATTING */

#endif /* VALUEFORMATTER_H */
