// © 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.
 *
 * file name: precisison.cpp
 */

#include <math.h>

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "digitlst.h"
#include "fmtableimp.h"
#include "precision.h"
#include "putilimp.h"
#include "visibledigits.h"

U_NAMESPACE_BEGIN

static const int32_t gPower10[] = {1, 10, 100, 1000};

FixedPrecision::FixedPrecision() 
        : fExactOnly(FALSE), fFailIfOverMax(FALSE), fRoundingMode(DecimalFormat::kRoundHalfEven) {
    fMin.setIntDigitCount(1);
    fMin.setFracDigitCount(0);
}

UBool
FixedPrecision::isRoundingRequired(
        int32_t upperExponent, int32_t lowerExponent) const {
    int32_t leastSigAllowed = fMax.getLeastSignificantInclusive();
    int32_t maxSignificantDigits = fSignificant.getMax();
    int32_t roundDigit;
    if (maxSignificantDigits == INT32_MAX) {
        roundDigit = leastSigAllowed;
    } else {
        int32_t limitDigit = upperExponent - maxSignificantDigits;
        roundDigit =
                limitDigit > leastSigAllowed ? limitDigit : leastSigAllowed;
    }
    return (roundDigit > lowerExponent);
}

DigitList &
FixedPrecision::round(
        DigitList &value, int32_t exponent, UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return value;
    }
    value .fContext.status &= ~DEC_Inexact;
    if (!fRoundingIncrement.isZero()) {
        if (exponent == 0) {
            value.quantize(fRoundingIncrement, status);
        } else {
            DigitList adjustedIncrement(fRoundingIncrement);
            adjustedIncrement.shiftDecimalRight(exponent);
            value.quantize(adjustedIncrement, status);
        }
        if (U_FAILURE(status)) {
            return value;
        }
    }
    int32_t leastSig = fMax.getLeastSignificantInclusive();
    if (leastSig == INT32_MIN) {
        value.round(fSignificant.getMax());
    } else {
        value.roundAtExponent(
                exponent + leastSig,
                fSignificant.getMax());
    }
    if (fExactOnly && (value.fContext.status & DEC_Inexact)) {
        status = U_FORMAT_INEXACT_ERROR;
    } else if (fFailIfOverMax) {
        // Smallest interval for value stored in interval
        DigitInterval interval;
        value.getSmallestInterval(interval);
        if (fMax.getIntDigitCount() < interval.getIntDigitCount()) {
            status = U_ILLEGAL_ARGUMENT_ERROR;
        }
    }
    return value;
}

DigitInterval &
FixedPrecision::getIntervalForZero(DigitInterval &interval) const {
    interval = fMin;
    if (fSignificant.getMin() > 0) {
        interval.expandToContainDigit(interval.getIntDigitCount() - fSignificant.getMin());
    }
    interval.shrinkToFitWithin(fMax);
    return interval;
}

DigitInterval &
FixedPrecision::getInterval(
        int32_t upperExponent, DigitInterval &interval) const {
    if (fSignificant.getMin() > 0) {
        interval.expandToContainDigit(
                upperExponent - fSignificant.getMin());
    }
    interval.expandToContain(fMin);
    interval.shrinkToFitWithin(fMax);
    return interval;
}

DigitInterval &
FixedPrecision::getInterval(
        const DigitList &value, DigitInterval &interval) const {
    if (value.isZero()) {
        interval = fMin;
        if (fSignificant.getMin() > 0) {
            interval.expandToContainDigit(interval.getIntDigitCount() - fSignificant.getMin());
        }
    } else {
        value.getSmallestInterval(interval);
        if (fSignificant.getMin() > 0) {
            interval.expandToContainDigit(
                    value.getUpperExponent() - fSignificant.getMin());
        }
        interval.expandToContain(fMin);
    }
    interval.shrinkToFitWithin(fMax);
    return interval;
}

UBool
FixedPrecision::isFastFormattable() const {
    return (fMin.getFracDigitCount() == 0 && fSignificant.isNoConstraints() && fRoundingIncrement.isZero() && !fFailIfOverMax);
}

UBool
FixedPrecision::handleNonNumeric(DigitList &value, VisibleDigits &digits) {
    if (value.isNaN()) {
        digits.setNaN();
        return TRUE;
    }
    if (value.isInfinite()) {
        digits.setInfinite();
        if (!value.isPositive()) {
            digits.setNegative();
        }
        return TRUE;
    }
    return FALSE;
}

VisibleDigits &
FixedPrecision::initVisibleDigits(
        DigitList &value,
        VisibleDigits &digits,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return digits;
    }
    digits.clear();
    if (handleNonNumeric(value, digits)) {
        return digits;
    }
    if (!value.isPositive()) {
        digits.setNegative();
    }
    value.setRoundingMode(fRoundingMode);
    round(value, 0, status);
    getInterval(value, digits.fInterval);
    digits.fExponent = value.getLowerExponent();
    value.appendDigitsTo(digits.fDigits, status);
    return digits;
}

VisibleDigits &
FixedPrecision::initVisibleDigits(
        int64_t value,
        VisibleDigits &digits,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return digits;
    }
    if (!fRoundingIncrement.isZero()) {
        // If we have round increment, use digit list.
        DigitList digitList;
        digitList.set(value);
        return initVisibleDigits(digitList, digits, status);
    }
    // Try fast path
    if (initVisibleDigits(value, 0, digits, status)) {
        digits.fAbsDoubleValue = fabs((double) value);
        digits.fAbsDoubleValueSet = U_SUCCESS(status) && !digits.isOverMaxDigits();
        return digits;
    }
    // Oops have to use digit list
    DigitList digitList;
    digitList.set(value);
    return initVisibleDigits(digitList, digits, status);
}

VisibleDigits &
FixedPrecision::initVisibleDigits(
        double value,
        VisibleDigits &digits,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return digits;
    }
    digits.clear();
    if (uprv_isNaN(value)) {
        digits.setNaN();
        return digits;
    }
    if (uprv_isPositiveInfinity(value)) {
        digits.setInfinite();
        return digits;
    }
    if (uprv_isNegativeInfinity(value)) {
        digits.setInfinite();
        digits.setNegative();
        return digits;
    }
    if (!fRoundingIncrement.isZero()) {
        // If we have round increment, use digit list.
        DigitList digitList;
        digitList.set(value);
        return initVisibleDigits(digitList, digits, status);
    }
    // Try to find n such that value * 10^n is an integer
    int32_t n = -1;
    double scaled;
    for (int32_t i = 0; i < UPRV_LENGTHOF(gPower10); ++i) {
        scaled = value * gPower10[i];
        if (scaled > MAX_INT64_IN_DOUBLE || scaled < -MAX_INT64_IN_DOUBLE) {
            break;
        }
        if (scaled == floor(scaled)) {
            n = i;
            break;
        }
    }
    // Try fast path
    if (n >= 0 && initVisibleDigits(static_cast<int64_t>(scaled), -n, digits, status)) {
        digits.fAbsDoubleValue = fabs(value);
        digits.fAbsDoubleValueSet = U_SUCCESS(status) && !digits.isOverMaxDigits();
        // Adjust for negative 0 because when we cast to an int64,
        // negative 0 becomes positive 0.
        if (scaled == 0.0 && uprv_isNegative(scaled)) {
            digits.setNegative();
        }
        return digits;
    }

    // Oops have to use digit list
    DigitList digitList;
    digitList.set(value);
    return initVisibleDigits(digitList, digits, status);
}

UBool
FixedPrecision::initVisibleDigits(
        int64_t mantissa,
        int32_t exponent,
        VisibleDigits &digits,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return TRUE;
    }
    digits.clear();

    // Precompute fAbsIntValue if it is small enough, but we don't know yet
    // if it will be valid.
    UBool absIntValueComputed = FALSE;
    if (mantissa > -1000000000000000000LL /* -1e18 */
            && mantissa < 1000000000000000000LL /* 1e18 */) {
        digits.fAbsIntValue = mantissa;
        if (digits.fAbsIntValue < 0) {
            digits.fAbsIntValue = -digits.fAbsIntValue;
        }
        int32_t i = 0;
        int32_t maxPower10Exp = UPRV_LENGTHOF(gPower10) - 1;
        for (; i > exponent + maxPower10Exp; i -= maxPower10Exp) {
            digits.fAbsIntValue /= gPower10[maxPower10Exp];
        }
        digits.fAbsIntValue /= gPower10[i - exponent];
        absIntValueComputed = TRUE;
    }
    if (mantissa == 0) {
        getIntervalForZero(digits.fInterval);
        digits.fAbsIntValueSet = absIntValueComputed;
        return TRUE;
    }
    // be sure least significant digit is non zero
    while (mantissa % 10 == 0) {
        mantissa /= 10;
        ++exponent;
    }
    if (mantissa < 0) {
        digits.fDigits.append((char) -(mantissa % -10), status);
        mantissa /= -10;
        digits.setNegative();
    }
    while (mantissa) {
        digits.fDigits.append((char) (mantissa % 10), status);
        mantissa /= 10;
    }
    if (U_FAILURE(status)) {
        return TRUE;
    }
    digits.fExponent = exponent;
    int32_t upperExponent = exponent + digits.fDigits.length();
    if (fFailIfOverMax && upperExponent > fMax.getIntDigitCount()) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return TRUE;
    }
    UBool roundingRequired =
            isRoundingRequired(upperExponent, exponent);
    if (roundingRequired) {
        if (fExactOnly) {
            status = U_FORMAT_INEXACT_ERROR;
            return TRUE;
        }
        return FALSE;
    }
    digits.fInterval.setLeastSignificantInclusive(exponent);
    digits.fInterval.setMostSignificantExclusive(upperExponent);
    getInterval(upperExponent, digits.fInterval);

    // The intValue we computed above is only valid if our visible digits
    // doesn't exceed the maximum integer digits allowed.
    digits.fAbsIntValueSet = absIntValueComputed && !digits.isOverMaxDigits();
    return TRUE;
}

VisibleDigitsWithExponent &
FixedPrecision::initVisibleDigitsWithExponent(
        DigitList &value,
        VisibleDigitsWithExponent &digits,
        UErrorCode &status) const {
    digits.clear();
    initVisibleDigits(value, digits.fMantissa, status);
    return digits;
}

VisibleDigitsWithExponent &
FixedPrecision::initVisibleDigitsWithExponent(
        double value,
        VisibleDigitsWithExponent &digits,
        UErrorCode &status) const {
    digits.clear();
    initVisibleDigits(value, digits.fMantissa, status);
    return digits;
}

VisibleDigitsWithExponent &
FixedPrecision::initVisibleDigitsWithExponent(
        int64_t value,
        VisibleDigitsWithExponent &digits,
        UErrorCode &status) const {
    digits.clear();
    initVisibleDigits(value, digits.fMantissa, status);
    return digits;
}

ScientificPrecision::ScientificPrecision() : fMinExponentDigits(1) {
}

DigitList &
ScientificPrecision::round(DigitList &value, UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return value;
    }
    int32_t exponent = value.getScientificExponent(
            fMantissa.fMin.getIntDigitCount(), getMultiplier());
    return fMantissa.round(value, exponent, status);
}

int32_t
ScientificPrecision::toScientific(DigitList &value) const {
    return value.toScientific(
            fMantissa.fMin.getIntDigitCount(), getMultiplier());
}

int32_t
ScientificPrecision::getMultiplier() const {
    int32_t maxIntDigitCount = fMantissa.fMax.getIntDigitCount();
    if (maxIntDigitCount == INT32_MAX) {
        return 1;
    }
    int32_t multiplier =
        maxIntDigitCount - fMantissa.fMin.getIntDigitCount() + 1;
    return (multiplier < 1 ? 1 : multiplier);
}

VisibleDigitsWithExponent &
ScientificPrecision::initVisibleDigitsWithExponent(
        DigitList &value,
        VisibleDigitsWithExponent &digits,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return digits;
    }
    digits.clear();
    if (FixedPrecision::handleNonNumeric(value, digits.fMantissa)) {
        return digits;
    }
    value.setRoundingMode(fMantissa.fRoundingMode);
    int64_t exponent = toScientific(round(value, status));
    fMantissa.initVisibleDigits(value, digits.fMantissa, status);
    FixedPrecision exponentPrecision;
    exponentPrecision.fMin.setIntDigitCount(fMinExponentDigits);
    exponentPrecision.initVisibleDigits(exponent, digits.fExponent, status);
    digits.fHasExponent = TRUE;
    return digits;
}

VisibleDigitsWithExponent &
ScientificPrecision::initVisibleDigitsWithExponent(
        double value,
        VisibleDigitsWithExponent &digits,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return digits;
    }
    DigitList digitList;
    digitList.set(value);
    return initVisibleDigitsWithExponent(digitList, digits, status);
}

VisibleDigitsWithExponent &
ScientificPrecision::initVisibleDigitsWithExponent(
        int64_t value,
        VisibleDigitsWithExponent &digits,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return digits;
    }
    DigitList digitList;
    digitList.set(value);
    return initVisibleDigitsWithExponent(digitList, digits, status);
}


U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
