/*
 * Copyright (C) 2015, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *
 * file name: visibledigits.cpp
 */

#if !defined(STARBOARD)
#include <math.h>
#endif

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#if defined(STARBOARD)
#include "starboard/client_porting/poem/assert_poem.h"
#include "starboard/client_porting/poem/string_poem.h"
#endif  // defined(STARBOARD)
#include "cstring.h"
#include "decNumber.h"
#include "digitlst.h"
#include "uassert.h"
#include "visibledigits.h"

static const int32_t kNegative = 1;
static const int32_t kInfinite = 2;
static const int32_t kNaN = 4;

U_NAMESPACE_BEGIN

void VisibleDigits::setNegative() {
    fFlags |= kNegative;
}

void VisibleDigits::setNaN() {
    fFlags |= kNaN;
}

void VisibleDigits::setInfinite() {
    fFlags |= kInfinite;
}

void VisibleDigits::clear() {
    fInterval.clear();
    fDigits.clear();
    fExponent = 0;
    fFlags = 0;
    fAbsIntValue = 0LL;
    fAbsIntValueSet = FALSE;
    fAbsDoubleValue = 0.0;
    fAbsDoubleValueSet = FALSE;
}

UBool VisibleDigits::isNegative() const {
    return (fFlags & kNegative);
}

UBool VisibleDigits::isNaN() const {
    return (fFlags & kNaN);
}

UBool VisibleDigits::isInfinite() const {
    return (fFlags & kInfinite);
}

int32_t VisibleDigits::getDigitByExponent(int32_t digitPos) const {
    if (digitPos < fExponent || digitPos >= fExponent + fDigits.length()) {
        return 0;
    }
    const char *ptr = fDigits.data();
    return ptr[digitPos - fExponent];
}

UBool VisibleDigits::isOverMaxDigits() const {
    return (fExponent + fDigits.length() > fInterval.getMostSignificantExclusive());
}

UBool VisibleDigits::isNaNOrInfinity() const {
    return (fFlags & (kInfinite | kNaN)) != 0;
}

double VisibleDigits::computeAbsDoubleValue() const {
    // Take care of NaN and infinity
    if (isNaN()) {
        return uprv_getNaN();
    }
    if (isInfinite()) {
        return uprv_getInfinity();
    }

    // stack allocate a decNumber to hold MAX_DBL_DIGITS+3 significant digits
    char rawNumber[sizeof(decNumber) + MAX_DBL_DIGITS+3];
    decNumber *numberPtr = (decNumber *) rawNumber;

    int32_t mostSig = fInterval.getMostSignificantExclusive();
    int32_t mostSigNonZero = fExponent + fDigits.length();
    int32_t end = mostSig > mostSigNonZero ? mostSigNonZero : mostSig;
    int32_t leastSig = fInterval.getLeastSignificantInclusive();
    int32_t start = leastSig > fExponent ? leastSig : fExponent;
    if (end <= start) {
        return 0.0;
    }
    if (start < end - (MAX_DBL_DIGITS+3)) {
        start = end - (MAX_DBL_DIGITS+3);
    }
    uint8_t *pos = numberPtr->lsu;
    const char *src = &(fDigits.data()[start - fExponent]);
    for (int32_t i = start; i < end; ++i) {
        *pos++ = (uint8_t) (*src++);
    }
    numberPtr->exponent = start;
    numberPtr->bits = 0;
    numberPtr->digits = end - start;
    char str[MAX_DBL_DIGITS+18];
    uprv_decNumberToString(numberPtr, str);
    U_ASSERT(uprv_strlen(str) < MAX_DBL_DIGITS+18);
    char decimalSeparator = DigitList::getStrtodDecimalSeparator();
    if (decimalSeparator != '.') {
        char *decimalPt = strchr(str, '.');
        if (decimalPt != NULL) {
            *decimalPt = decimalSeparator;
        }
    }
    char *unused = NULL;
    return uprv_strtod(str, &unused);
}

void VisibleDigits::getFixedDecimal(
    double &source, int64_t &intValue, int64_t &f, int64_t &t, int32_t &v, UBool &hasIntValue) const {
    source = 0.0;
    intValue = 0;
    f = 0;
    t = 0;
    v = 0;
    hasIntValue = FALSE;
    if (isNaNOrInfinity()) {
        return;
    }

    // source
    if (fAbsDoubleValueSet) {
        source = fAbsDoubleValue;
    } else {
        source = computeAbsDoubleValue();
    }

    // visible decimal digits
    v = fInterval.getFracDigitCount();

    // intValue

    // If we initialized from an int64 just use that instead of
    // calculating
    if (fAbsIntValueSet) {
        intValue = fAbsIntValue;
    } else {
        int32_t startPos = fInterval.getMostSignificantExclusive();
        if (startPos > 18) {
            startPos = 18;
        }
        // process the integer digits
        for (int32_t i = startPos - 1; i >= 0; --i) {
            intValue = intValue * 10LL + getDigitByExponent(i);
        }
        if (intValue == 0LL && startPos > 0) {
            intValue = 100000000000000000LL;
        }
    }

    // f (decimal digits)
    // skip over any leading 0's in fraction digits.
    int32_t idx = -1;
    for (; idx >= -v && getDigitByExponent(idx) == 0; --idx);

    // Only process up to first 18 non zero fraction digits for decimalDigits
    // since that is all we can fit into an int64.
    for (int32_t i = idx; i >= -v && i > idx - 18; --i) {
        f = f * 10LL + getDigitByExponent(i);
    }

    // If we have no decimal digits, we don't have an integer value
    hasIntValue = (f == 0LL);

    // t (decimal digits without trailing zeros)
   t = f;
    while (t > 0 && t % 10LL == 0) {
        t /= 10;
    }
}

U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
