// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*****************************************************************************************
* Copyright (C) 2010-2012, International Business Machines
* Corporation and others. All Rights Reserved.
*****************************************************************************************
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/upluralrules.h"
#include "unicode/plurrule.h"
#include "unicode/locid.h"
#include "unicode/unistr.h"
#include "unicode/unum.h"
#include "unicode/numfmt.h"
#include "unicode/unumberformatter.h"
#include "number_decimalquantity.h"
#include "number_utypes.h"
#include "numrange_impl.h"

U_NAMESPACE_USE

namespace {

/**
 * Given a number and a format, returns the keyword of the first applicable
 * rule for the PluralRules object.
 * @param rules The plural rules.
 * @param obj The numeric object for which the rule should be determined.
 * @param fmt The NumberFormat specifying how the number will be formatted
 *        (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars").
 * @param status  Input/output parameter. If at entry this indicates a
 *                failure status, the method returns immediately; otherwise
 *                this is set to indicate the outcome of the call.
 * @return The keyword of the selected rule. Undefined in the case of an error.
 */
UnicodeString select(const PluralRules &rules, const Formattable& obj, const NumberFormat& fmt, UErrorCode& status) {
    if (U_SUCCESS(status)) {
        const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
        if (decFmt != NULL) {
            number::impl::DecimalQuantity dq;
            decFmt->formatToDecimalQuantity(obj, dq, status);
            if (U_SUCCESS(status)) {
                return rules.select(dq);
            }
        } else {
            double number = obj.getDouble(status);
            if (U_SUCCESS(status)) {
                return rules.select(number);
            }
        }
    }
    return UnicodeString();
}

}  // namespace

U_CAPI UPluralRules* U_EXPORT2
uplrules_open(const char *locale, UErrorCode *status)
{
    return uplrules_openForType(locale, UPLURAL_TYPE_CARDINAL, status);
}

U_CAPI UPluralRules* U_EXPORT2
uplrules_openForType(const char *locale, UPluralType type, UErrorCode *status)
{
    return (UPluralRules*)PluralRules::forLocale(Locale(locale), type, *status);
}

U_CAPI void U_EXPORT2
uplrules_close(UPluralRules *uplrules)
{
    delete (PluralRules*)uplrules;
}

U_CAPI int32_t U_EXPORT2
uplrules_select(const UPluralRules *uplrules,
                double number,
                UChar *keyword, int32_t capacity,
                UErrorCode *status)
{
    if (U_FAILURE(*status)) {
        return 0;
    }
    if (keyword == NULL ? capacity != 0 : capacity < 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    UnicodeString result = ((PluralRules*)uplrules)->select(number);
    return result.extract(keyword, capacity, *status);
}

U_CAPI int32_t U_EXPORT2
uplrules_selectFormatted(const UPluralRules *uplrules,
                const UFormattedNumber* number,
                UChar *keyword, int32_t capacity,
                UErrorCode *status)
{
    if (U_FAILURE(*status)) {
        return 0;
    }
    if (keyword == NULL ? capacity != 0 : capacity < 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    const number::impl::DecimalQuantity* dq =
        number::impl::validateUFormattedNumberToDecimalQuantity(number, *status);
    if (U_FAILURE(*status)) {
        return 0;
    }
    UnicodeString result = ((PluralRules*)uplrules)->select(*dq);
    return result.extract(keyword, capacity, *status);
}

U_CAPI int32_t U_EXPORT2
uplrules_selectForRange(const UPluralRules *uplrules,
                const UFormattedNumberRange* urange,
                UChar *keyword, int32_t capacity,
                UErrorCode *status)
{
    if (U_FAILURE(*status)) {
        return 0;
    }
    if (keyword == NULL ? capacity != 0 : capacity < 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    const number::impl::UFormattedNumberRangeData* impl =
        number::impl::validateUFormattedNumberRange(urange, *status);
    UnicodeString result = ((PluralRules*)uplrules)->select(impl, *status);
    return result.extract(keyword, capacity, *status);
}

U_CAPI int32_t U_EXPORT2
uplrules_selectWithFormat(const UPluralRules *uplrules,
                          double number,
                          const UNumberFormat *fmt,
                          UChar *keyword, int32_t capacity,
                          UErrorCode *status)
{
    if (U_FAILURE(*status)) {
        return 0;
    }
    const PluralRules* plrules = reinterpret_cast<const PluralRules*>(uplrules);
    const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
    if (plrules == NULL || nf == NULL || ((keyword == NULL)? capacity != 0 : capacity < 0)) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    Formattable obj(number);
    UnicodeString result = select(*plrules, obj, *nf, *status);
    return result.extract(keyword, capacity, *status);
}

U_CAPI UEnumeration* U_EXPORT2
uplrules_getKeywords(const UPluralRules *uplrules,
                     UErrorCode *status)
{
    if (U_FAILURE(*status)) {
        return NULL;
    }
    const PluralRules* plrules = reinterpret_cast<const PluralRules*>(uplrules);
    if (plrules == NULL) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return NULL;
    }
    StringEnumeration *senum = plrules->getKeywords(*status);
    if (U_FAILURE(*status)) {
        return NULL;
    }
    if (senum == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    return uenum_openFromStringEnumeration(senum, status);
}

#endif /* #if !UCONFIG_NO_FORMATTING */
