// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

// Allow implicit conversion from char16_t* to UnicodeString for this file:
// Helpful in toString methods and elsewhere.
#define UNISTR_FROM_STRING_EXPLICIT

#include "fphdlimp.h"
#include "number_utypes.h"
#include "numparse_types.h"
#include "formattedval_impl.h"
#include "number_decnum.h"
#include "unicode/numberformatter.h"
#include "unicode/unumberformatter.h"

using namespace icu;
using namespace icu::number;
using namespace icu::number::impl;


U_NAMESPACE_BEGIN
namespace number {
namespace impl {

/**
 * Implementation class for UNumberFormatter. Wraps a LocalizedNumberFormatter.
 */
struct UNumberFormatterData : public UMemory,
        // Magic number as ASCII == "NFR" (NumberFormatteR)
        public IcuCApiHelper<UNumberFormatter, UNumberFormatterData, 0x4E465200> {
    LocalizedNumberFormatter fFormatter;
};

struct UFormattedNumberImpl;

// Magic number as ASCII == "FDN" (FormatteDNumber)
typedef IcuCApiHelper<UFormattedNumber, UFormattedNumberImpl, 0x46444E00> UFormattedNumberApiHelper;

struct UFormattedNumberImpl : public UFormattedValueImpl, public UFormattedNumberApiHelper {
    UFormattedNumberImpl();
    ~UFormattedNumberImpl();

    FormattedNumber fImpl;
    UFormattedNumberData fData;
};

UFormattedNumberImpl::UFormattedNumberImpl()
        : fImpl(&fData) {
    fFormattedValue = &fImpl;
}

UFormattedNumberImpl::~UFormattedNumberImpl() {
    // Disown the data from fImpl so it doesn't get deleted twice
    fImpl.fData = nullptr;
}

}
}
U_NAMESPACE_END


UPRV_FORMATTED_VALUE_CAPI_NO_IMPLTYPE_AUTO_IMPL(
    UFormattedNumber,
    UFormattedNumberImpl,
    UFormattedNumberApiHelper,
    unumf)


const DecimalQuantity* icu::number::impl::validateUFormattedNumberToDecimalQuantity(
        const UFormattedNumber* uresult, UErrorCode& status) {
    auto* result = UFormattedNumberApiHelper::validate(uresult, status);
    if (U_FAILURE(status)) {
        return nullptr;
    }
    return &result->fData.quantity;
}



U_CAPI UNumberFormatter* U_EXPORT2
unumf_openForSkeletonAndLocale(const UChar* skeleton, int32_t skeletonLen, const char* locale,
                               UErrorCode* ec) {
    auto* impl = new UNumberFormatterData();
    if (impl == nullptr) {
        *ec = U_MEMORY_ALLOCATION_ERROR;
        return nullptr;
    }
    // Readonly-alias constructor (first argument is whether we are NUL-terminated)
    UnicodeString skeletonString(skeletonLen == -1, skeleton, skeletonLen);
    impl->fFormatter = NumberFormatter::forSkeleton(skeletonString, *ec).locale(locale);
    return impl->exportForC();
}

U_CAPI UNumberFormatter* U_EXPORT2
unumf_openForSkeletonAndLocaleWithError(const UChar* skeleton, int32_t skeletonLen, const char* locale,
                                         UParseError* perror, UErrorCode* ec) {
    auto* impl = new UNumberFormatterData();
    if (impl == nullptr) {
        *ec = U_MEMORY_ALLOCATION_ERROR;
        return nullptr;
    }
    // Readonly-alias constructor (first argument is whether we are NUL-terminated)
    UnicodeString skeletonString(skeletonLen == -1, skeleton, skeletonLen);
    impl->fFormatter = NumberFormatter::forSkeleton(skeletonString, *perror, *ec).locale(locale);
    return impl->exportForC();
}

U_CAPI void U_EXPORT2
unumf_formatInt(const UNumberFormatter* uformatter, int64_t value, UFormattedNumber* uresult,
                UErrorCode* ec) {
    const UNumberFormatterData* formatter = UNumberFormatterData::validate(uformatter, *ec);
    auto* result = UFormattedNumberApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) { return; }

    result->fData.getStringRef().clear();
    result->fData.quantity.setToLong(value);
    formatter->fFormatter.formatImpl(&result->fData, *ec);
}

U_CAPI void U_EXPORT2
unumf_formatDouble(const UNumberFormatter* uformatter, double value, UFormattedNumber* uresult,
                   UErrorCode* ec) {
    const UNumberFormatterData* formatter = UNumberFormatterData::validate(uformatter, *ec);
    auto* result = UFormattedNumberApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) { return; }

    result->fData.getStringRef().clear();
    result->fData.quantity.setToDouble(value);
    formatter->fFormatter.formatImpl(&result->fData, *ec);
}

U_CAPI void U_EXPORT2
unumf_formatDecimal(const UNumberFormatter* uformatter, const char* value, int32_t valueLen,
                    UFormattedNumber* uresult, UErrorCode* ec) {
    const UNumberFormatterData* formatter = UNumberFormatterData::validate(uformatter, *ec);
    auto* result = UFormattedNumberApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) { return; }

    result->fData.getStringRef().clear();
    result->fData.quantity.setToDecNumber({value, valueLen}, *ec);
    if (U_FAILURE(*ec)) { return; }
    formatter->fFormatter.formatImpl(&result->fData, *ec);
}

U_CAPI int32_t U_EXPORT2
unumf_resultToString(const UFormattedNumber* uresult, UChar* buffer, int32_t bufferCapacity,
                     UErrorCode* ec) {
    const auto* result = UFormattedNumberApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) { return 0; }

    if (buffer == nullptr ? bufferCapacity != 0 : bufferCapacity < 0) {
        *ec = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }

    return result->fData.toTempString(*ec).extract(buffer, bufferCapacity, *ec);
}

U_CAPI UBool U_EXPORT2
unumf_resultNextFieldPosition(const UFormattedNumber* uresult, UFieldPosition* ufpos, UErrorCode* ec) {
    const auto* result = UFormattedNumberApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) { return FALSE; }

    if (ufpos == nullptr) {
        *ec = U_ILLEGAL_ARGUMENT_ERROR;
        return FALSE;
    }

    FieldPosition fp;
    fp.setField(ufpos->field);
    fp.setBeginIndex(ufpos->beginIndex);
    fp.setEndIndex(ufpos->endIndex);
    bool retval = result->fData.nextFieldPosition(fp, *ec);
    ufpos->beginIndex = fp.getBeginIndex();
    ufpos->endIndex = fp.getEndIndex();
    // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool
    return retval ? TRUE : FALSE;
}

U_CAPI void U_EXPORT2
unumf_resultGetAllFieldPositions(const UFormattedNumber* uresult, UFieldPositionIterator* ufpositer,
                                 UErrorCode* ec) {
    const auto* result = UFormattedNumberApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) { return; }

    if (ufpositer == nullptr) {
        *ec = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    auto* fpi = reinterpret_cast<FieldPositionIterator*>(ufpositer);
    FieldPositionIteratorHandler fpih(fpi, *ec);
    result->fData.getAllFieldPositions(fpih, *ec);
}

U_CAPI int32_t U_EXPORT2
unumf_resultToDecimalNumber(
        const UFormattedNumber* uresult,
        char* dest,
        int32_t destCapacity,
        UErrorCode* ec) {
    const auto* result = UFormattedNumberApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) {
        return 0;
    }
    DecNum decnum;
    return result->fData.quantity
        .toDecNum(decnum, *ec)
        .toCharString(*ec)
        .extract(dest, destCapacity, *ec);
}

U_CAPI void U_EXPORT2
unumf_close(UNumberFormatter* f) {
    UErrorCode localStatus = U_ZERO_ERROR;
    const UNumberFormatterData* impl = UNumberFormatterData::validate(f, localStatus);
    delete impl;
}


#endif /* #if !UCONFIG_NO_FORMATTING */



























