// © 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 "numrange_impl.h"
#include "number_decnum.h"
#include "unicode/numberrangeformatter.h"
#include "unicode/unumberrangeformatter.h"

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


U_NAMESPACE_BEGIN
namespace number {
namespace impl {

/**
 * Implementation class for UNumberRangeFormatter. Wraps a LocalizedRangeNumberFormatter.
 */
struct UNumberRangeFormatterData : public UMemory,
        // Magic number as ASCII == "NRF" (NumberRangeFormatter)
        public IcuCApiHelper<UNumberRangeFormatter, UNumberRangeFormatterData, 0x4E524600> {
    LocalizedNumberRangeFormatter fFormatter;
};

struct UFormattedNumberRangeImpl;

// Magic number as ASCII == "FDN" (FormatteDNumber)
typedef IcuCApiHelper<UFormattedNumberRange, UFormattedNumberRangeImpl, 0x46444E00> UFormattedNumberRangeApiHelper;

struct UFormattedNumberRangeImpl : public UFormattedValueImpl, public UFormattedNumberRangeApiHelper {
    UFormattedNumberRangeImpl();
    ~UFormattedNumberRangeImpl();

    FormattedNumberRange fImpl;
    UFormattedNumberRangeData fData;
};

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

UFormattedNumberRangeImpl::~UFormattedNumberRangeImpl() {
    // 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(
    UFormattedNumberRange,
    UFormattedNumberRangeImpl,
    UFormattedNumberRangeApiHelper,
    unumrf)


U_CAPI UNumberRangeFormatter* U_EXPORT2
unumrf_openForSkeletonWithCollapseAndIdentityFallback(
        const UChar* skeleton,
        int32_t skeletonLen,
        UNumberRangeCollapse collapse,
        UNumberRangeIdentityFallback identityFallback,
        const char* locale,
        UParseError* perror,
        UErrorCode* ec) {
    auto* impl = new UNumberRangeFormatterData();
    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 = NumberRangeFormatter::withLocale(locale)
        .numberFormatterBoth(NumberFormatter::forSkeleton(skeletonString, *perror, *ec))
        .collapse(collapse)
        .identityFallback(identityFallback);
    return impl->exportForC();
}

U_CAPI void U_EXPORT2
unumrf_formatDoubleRange(
        const UNumberRangeFormatter* uformatter,
        double first,
        double second,
        UFormattedNumberRange* uresult,
        UErrorCode* ec) {
    const UNumberRangeFormatterData* formatter = UNumberRangeFormatterData::validate(uformatter, *ec);
    auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) { return; }

    result->fData.getStringRef().clear();
    result->fData.quantity1.setToDouble(first);
    result->fData.quantity2.setToDouble(second);
    formatter->fFormatter.formatImpl(result->fData, first == second, *ec);
}

U_CAPI void U_EXPORT2
unumrf_formatDecimalRange(
        const UNumberRangeFormatter* uformatter,
        const char* first, int32_t firstLen,
        const char* second, int32_t secondLen,
        UFormattedNumberRange* uresult,
        UErrorCode* ec) {
    const UNumberRangeFormatterData* formatter = UNumberRangeFormatterData::validate(uformatter, *ec);
    auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) { return; }

    result->fData.getStringRef().clear();
    result->fData.quantity1.setToDecNumber({first, firstLen}, *ec);
    result->fData.quantity2.setToDecNumber({second, secondLen}, *ec);
    formatter->fFormatter.formatImpl(result->fData, first == second, *ec);
}

U_CAPI UNumberRangeIdentityResult U_EXPORT2
unumrf_resultGetIdentityResult(
        const UFormattedNumberRange* uresult,
        UErrorCode* ec) {
    auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
    if (U_FAILURE(*ec)) {
        return UNUM_IDENTITY_RESULT_COUNT;
    }
    return result->fData.identityResult;
}

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

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

U_CAPI void U_EXPORT2
unumrf_close(UNumberRangeFormatter* f) {
    UErrorCode localStatus = U_ZERO_ERROR;
    const UNumberRangeFormatterData* impl = UNumberRangeFormatterData::validate(f, localStatus);
    delete impl;
}


#endif /* #if !UCONFIG_NO_FORMATTING */
