// Copyright (C) 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.
*******************************************************************************
* digitformatter.h
*
* created on: 2015jan06
* created by: Travis Keep
*/

#ifndef __DIGITFORMATTER_H__
#define __DIGITFORMATTER_H__

#include "unicode/uobject.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/utypes.h"
#include "unicode/unistr.h"
#include "digitaffix.h"

U_NAMESPACE_BEGIN

class DecimalFormatSymbols;
class DigitList;
class DigitGrouping;
class DigitInterval;
class UnicodeString;
class FieldPositionHandler;
class IntDigitCountRange;
class VisibleDigits;
class VisibleDigitsWithExponent;

/**
 * Various options for formatting in fixed point.
 */
class U_I18N_API DigitFormatterOptions : public UMemory {
    public:
    DigitFormatterOptions() : fAlwaysShowDecimal(FALSE) { }

    /**
     * Returns TRUE if this object equals rhs.
     */
    UBool equals(const DigitFormatterOptions &rhs) const {
        return (
            fAlwaysShowDecimal == rhs.fAlwaysShowDecimal);
    }

    /**
     * Returns TRUE if these options allow for fast formatting of
     * integers.
     */
    UBool isFastFormattable() const {
        return (fAlwaysShowDecimal == FALSE);
    }

    /**
     * If TRUE, show the decimal separator even when there are no fraction
     * digits. default is FALSE.
     */
    UBool fAlwaysShowDecimal;
};

/**
 * Various options for formatting an integer.
 */
class U_I18N_API DigitFormatterIntOptions : public UMemory {
    public:
    DigitFormatterIntOptions() : fAlwaysShowSign(FALSE) { }

    /**
     * Returns TRUE if this object equals rhs.
     */
    UBool equals(const DigitFormatterIntOptions &rhs) const {
        return (fAlwaysShowSign == rhs.fAlwaysShowSign);
    }

    /**
     * If TRUE, always prefix the integer with its sign even if the number is
     * positive. Default is FALSE.
     */
    UBool fAlwaysShowSign;
};

/**
 * Options for formatting in scientific notation.
 */
class U_I18N_API SciFormatterOptions : public UMemory {
    public:

    /**
     * Returns TRUE if this object equals rhs.
     */
    UBool equals(const SciFormatterOptions &rhs) const {
        return (fMantissa.equals(rhs.fMantissa) &&
                fExponent.equals(rhs.fExponent));
    }

    /**
     * Options for formatting the mantissa.
     */
    DigitFormatterOptions fMantissa;

    /**
     * Options for formatting the exponent.
     */
    DigitFormatterIntOptions fExponent;
};


/**
 * Does fixed point formatting.
 *
 * This class only does fixed point formatting. It does no rounding before
 * formatting.
 */
class U_I18N_API DigitFormatter : public UMemory {
public:

/**
 * Decimal separator is period (.), Plus sign is plus (+),
 * minus sign is minus (-), grouping separator is comma (,), digits are 0-9.
 */
DigitFormatter();

/**
 * Let symbols determine the digits, decimal separator,
 * plus and mius sign, grouping separator, and possibly other settings.
 */
DigitFormatter(const DecimalFormatSymbols &symbols);

/**
 * Change what this instance uses for digits, decimal separator,
 * plus and mius sign, grouping separator, and possibly other settings
 * according to symbols.
 */
void setDecimalFormatSymbols(const DecimalFormatSymbols &symbols);

/**
 * Change what this instance uses for digits, decimal separator,
 * plus and mius sign, grouping separator, and possibly other settings
 * according to symbols in the context of monetary amounts.
 */
void setDecimalFormatSymbolsForMonetary(const DecimalFormatSymbols &symbols);

/**
 * Fixed point formatting.
 *
 * @param positiveDigits the value to format
 *  Negative sign can be present, but it won't show.
 * @param grouping controls how digit grouping is done
 * @param options formatting options
 * @param handler records field positions
 * @param appendTo formatted value appended here.
 * @return appendTo
 */
UnicodeString &format(
        const VisibleDigits &positiveDigits,
        const DigitGrouping &grouping,
        const DigitFormatterOptions &options,
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const;

/**
 * formats in scientifc notation.
 * @param positiveDigits the value to format.
 *  Negative sign can be present, but it won't show.
 * @param options formatting options
 * @param handler records field positions.
 * @param appendTo formatted value appended here.
 */
UnicodeString &format(
        const VisibleDigitsWithExponent &positiveDigits,
        const SciFormatterOptions &options,
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const;

/**
 * Fixed point formatting of integers.
 * Always performed with no grouping and no decimal point.
 *
 * @param positiveValue the value to format must be positive.
 * @param range specifies minimum and maximum number of digits.
 * @param handler records field positions
 * @param appendTo formatted value appended here.
 * @return appendTo
 */
UnicodeString &formatPositiveInt32(
        int32_t positiveValue,
        const IntDigitCountRange &range,
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const;

/**
 * Counts how many code points are needed for fixed formatting.
 *   If digits is negative, the negative sign is not included in the count.
 */
int32_t countChar32(
        const VisibleDigits &digits,
        const DigitGrouping &grouping,
        const DigitFormatterOptions &options) const;

/**
 * Counts how many code points are needed for scientific formatting.
 *   If digits is negative, the negative sign is not included in the count.
 */
int32_t countChar32(
        const VisibleDigitsWithExponent &digits,
        const SciFormatterOptions &options) const;

/**
 * Returns TRUE if this object equals rhs.
 */
UBool equals(const DigitFormatter &rhs) const;

private:
UChar32 fLocalizedDigits[10];
UnicodeString fGroupingSeparator;
UnicodeString fDecimal;
UnicodeString fNegativeSign;
UnicodeString fPositiveSign;
DigitAffix fInfinity;
DigitAffix fNan;
UBool fIsStandardDigits;
UnicodeString fExponent;
UBool isStandardDigits() const;

UnicodeString &formatDigits(
        const uint8_t *digits,
        int32_t count,
        const IntDigitCountRange &range,
        int32_t intField,
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const;

void setOtherDecimalFormatSymbols(const DecimalFormatSymbols &symbols);

int32_t countChar32(
        const VisibleDigits &exponent,
        const DigitInterval &mantissaInterval,
        const SciFormatterOptions &options) const;

UnicodeString &formatNaN(
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const {
    return fNan.format(handler, appendTo);
}

int32_t countChar32ForNaN() const {
    return fNan.toString().countChar32();
}

UnicodeString &formatInfinity(
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const {
    return fInfinity.format(handler, appendTo);
}

int32_t countChar32ForInfinity() const {
    return fInfinity.toString().countChar32();
}

UnicodeString &formatExponent(
        const VisibleDigits &digits,
        const DigitFormatterIntOptions &options,
        int32_t signField,
        int32_t intField,
        FieldPositionHandler &handler,
        UnicodeString &appendTo) const;

int32_t countChar32(
        const DigitGrouping &grouping,
        const DigitInterval &interval,
        const DigitFormatterOptions &options) const;

int32_t countChar32ForExponent(
        const VisibleDigits &exponent,
        const DigitFormatterIntOptions &options) const;

};


U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
#endif  // __DIGITFORMATTER_H__
