// 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.
 *
 * 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(scaled, -n, digits, status)) {
        digits.fAbsDoubleValue = fabs(value);
        digits.fAbsDoubleValueSet = U_SUCCESS(status) && !digits.isOverMaxDigits();
        // Adjust for negative 0 becuase 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 */
