// © 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 && !UPRV_INCOMPLETE_CPP11_SUPPORT
#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;
    }
}

} // namespace roundingutils
} // namespace impl
} // namespace number
U_NAMESPACE_END

#endif //__NUMBER_ROUNDINGUTILS_H__

#endif /* #if !UCONFIG_NO_FORMATTING */
