// © 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_ROUNDINGUTILS_H__
#define __NUMBER_ROUNDINGUTILS_H__

#include "number_types.h"

U_NAMESPACE_BEGIN
namespace number {
namespace impl {
namespace roundingutils {

enum Section {
    SECTION_LOWER_EDGE = -1,
    SECTION_UPPER_EDGE = -2,
    SECTION_LOWER = 1,
    SECTION_MIDPOINT = 2,
    SECTION_UPPER = 3
};

/**
 * Converts a rounding mode and metadata about the quantity being rounded to a boolean determining
 * whether the value should be rounded toward infinity or toward zero.
 *
 * <p>The parameters are of type int because benchmarks on an x86-64 processor against OpenJDK
 * showed that ints were demonstrably faster than enums in switch statements.
 *
 * @param isEven Whether the digit immediately before the rounding magnitude is even.
 * @param isNegative Whether the quantity is negative.
 * @param section Whether the part of the quantity to the right of the rounding magnitude is
 *     exactly halfway between two digits, whether it is in the lower part (closer to zero), or
 *     whether it is in the upper part (closer to infinity). See {@link #SECTION_LOWER}, {@link
 *     #SECTION_MIDPOINT}, and {@link #SECTION_UPPER}.
 * @param roundingMode The integer version of the {@link RoundingMode}, which you can get via
 *     {@link RoundingMode#ordinal}.
 * @param status Error code, set to U_FORMAT_INEXACT_ERROR if the rounding mode is kRoundUnnecessary.
 * @return true if the number should be rounded toward zero; false if it should be rounded toward
 *     infinity.
 */
inline bool
getRoundingDirection(bool isEven, bool isNegative, Section section, RoundingMode roundingMode,
                     UErrorCode &status) {
    switch (roundingMode) {
        case RoundingMode::UNUM_ROUND_UP:
            // round away from zero
            return false;

        case RoundingMode::UNUM_ROUND_DOWN:
            // round toward zero
            return true;

        case RoundingMode::UNUM_ROUND_CEILING:
            // round toward positive infinity
            return isNegative;

        case RoundingMode::UNUM_ROUND_FLOOR:
            // round toward negative infinity
            return !isNegative;

        case RoundingMode::UNUM_ROUND_HALFUP:
            switch (section) {
                case SECTION_MIDPOINT:
                    return false;
                case SECTION_LOWER:
                    return true;
                case SECTION_UPPER:
                    return false;
                default:
                    break;
            }
            break;

        case RoundingMode::UNUM_ROUND_HALFDOWN:
            switch (section) {
                case SECTION_MIDPOINT:
                    return true;
                case SECTION_LOWER:
                    return true;
                case SECTION_UPPER:
                    return false;
                default:
                    break;
            }
            break;

        case RoundingMode::UNUM_ROUND_HALFEVEN:
            switch (section) {
                case SECTION_MIDPOINT:
                    return isEven;
                case SECTION_LOWER:
                    return true;
                case SECTION_UPPER:
                    return false;
                default:
                    break;
            }
            break;

        default:
            break;
    }

    status = U_FORMAT_INEXACT_ERROR;
    return false;
}

/**
 * Gets whether the given rounding mode's rounding boundary is at the midpoint. The rounding
 * boundary is the point at which a number switches from being rounded down to being rounded up.
 * For example, with rounding mode HALF_EVEN, HALF_UP, or HALF_DOWN, the rounding boundary is at
 * the midpoint, and this function would return true. However, for UP, DOWN, CEILING, and FLOOR,
 * the rounding boundary is at the "edge", and this function would return false.
 *
 * @param roundingMode The integer version of the {@link RoundingMode}.
 * @return true if rounding mode is HALF_EVEN, HALF_UP, or HALF_DOWN; false otherwise.
 */
inline bool roundsAtMidpoint(int roundingMode) {
    switch (roundingMode) {
        case RoundingMode::UNUM_ROUND_UP:
        case RoundingMode::UNUM_ROUND_DOWN:
        case RoundingMode::UNUM_ROUND_CEILING:
        case RoundingMode::UNUM_ROUND_FLOOR:
            return false;

        default:
            return true;
    }
}

/**
 * Computes the number of fraction digits in a double. Used for computing maxFrac for an increment.
 * Calls into the DoubleToStringConverter library to do so.
 *
 * @param singleDigit An output parameter; set to a number if that is the
 *        only digit in the double, or -1 if there is more than one digit.
 */
digits_t doubleFractionLength(double input, int8_t* singleDigit);

} // namespace roundingutils


/**
 * Encapsulates a Precision and a RoundingMode and performs rounding on a DecimalQuantity.
 *
 * This class does not exist in Java: instead, the base Precision class is used.
 */
class RoundingImpl {
  public:
    RoundingImpl() = default;  // defaults to pass-through rounder

    RoundingImpl(const Precision& precision, UNumberFormatRoundingMode roundingMode,
                 const CurrencyUnit& currency, UErrorCode& status);

    static RoundingImpl passThrough();

    /** Required for ScientificFormatter */
    bool isSignificantDigits() const;

    /**
     * Rounding endpoint used by Engineering and Compact notation. Chooses the most appropriate multiplier (magnitude
     * adjustment), applies the adjustment, rounds, and returns the chosen multiplier.
     *
     * <p>
     * In most cases, this is simple. However, when rounding the number causes it to cross a multiplier boundary, we
     * need to re-do the rounding. For example, to display 999,999 in Engineering notation with 2 sigfigs, first you
     * guess the multiplier to be -3. However, then you end up getting 1000E3, which is not the correct output. You then
     * change your multiplier to be -6, and you get 1.0E6, which is correct.
     *
     * @param input The quantity to process.
     * @param producer Function to call to return a multiplier based on a magnitude.
     * @return The number of orders of magnitude the input was adjusted by this method.
     */
    int32_t
    chooseMultiplierAndApply(impl::DecimalQuantity &input, const impl::MultiplierProducer &producer,
                             UErrorCode &status);

    void apply(impl::DecimalQuantity &value, UErrorCode &status) const;

    /** Version of {@link #apply} that obeys minInt constraints. Used for scientific notation compatibility mode. */
    void apply(impl::DecimalQuantity &value, int32_t minInt, UErrorCode status);

  private:
    Precision fPrecision;
    UNumberFormatRoundingMode fRoundingMode;
    bool fPassThrough = true;  // default value
};


} // namespace impl
} // namespace number
U_NAMESPACE_END

#endif //__NUMBER_ROUNDINGUTILS_H__

#endif /* #if !UCONFIG_NO_FORMATTING */
