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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "starboard/client_porting/poem/assert_poem.h"
#include "starboard/client_porting/poem/string_poem.h"
#include "unicode/plurrule.h"
#include "charstr.h"
#include "digitaffix.h"
#include "digitaffixesandpadding.h"
#include "digitlst.h"
#include "uassert.h"
#include "valueformatter.h"
#include "visibledigits.h"

U_NAMESPACE_BEGIN

UBool
DigitAffixesAndPadding::needsPluralRules() const {
    return (
            fPositivePrefix.hasMultipleVariants() ||
            fPositiveSuffix.hasMultipleVariants() ||
            fNegativePrefix.hasMultipleVariants() ||
            fNegativeSuffix.hasMultipleVariants());
}

UnicodeString &
DigitAffixesAndPadding::formatInt32(
        int32_t value,
        const ValueFormatter &formatter,
        FieldPositionHandler &handler,
        const PluralRules *optPluralRules,
        UnicodeString &appendTo,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return appendTo;
    }
    if (optPluralRules != NULL || fWidth > 0 || !formatter.isFastFormattable(value)) {
        VisibleDigitsWithExponent digits;
        formatter.toVisibleDigitsWithExponent(
                (int64_t) value, digits, status);
        return format(
                digits,
                formatter,
                handler,
                optPluralRules,
                appendTo,
                status);
    }
    UBool bPositive = value >= 0;
    const DigitAffix *prefix = bPositive ? &fPositivePrefix.getOtherVariant() : &fNegativePrefix.getOtherVariant();
    const DigitAffix *suffix = bPositive ? &fPositiveSuffix.getOtherVariant() : &fNegativeSuffix.getOtherVariant();
    if (value < 0) {
        value = -value;
    }
    prefix->format(handler, appendTo);
    formatter.formatInt32(value, handler, appendTo);
    return suffix->format(handler, appendTo);
}

static UnicodeString &
formatAffix(
        const DigitAffix *affix,
        FieldPositionHandler &handler,
        UnicodeString &appendTo) {
    if (affix) {
        affix->format(handler, appendTo);
    }
    return appendTo;
}

static int32_t
countAffixChar32(const DigitAffix *affix) {
    if (affix) {
        return affix->countChar32();
    }
    return 0;
}

UnicodeString &
DigitAffixesAndPadding::format(
        const VisibleDigitsWithExponent &digits,
        const ValueFormatter &formatter,
        FieldPositionHandler &handler,
        const PluralRules *optPluralRules,
        UnicodeString &appendTo,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return appendTo;
    }
    const DigitAffix *prefix = NULL;
    const DigitAffix *suffix = NULL;
    if (!digits.isNaN()) {
        UBool bPositive = !digits.isNegative();
        const PluralAffix *pluralPrefix = bPositive ? &fPositivePrefix : &fNegativePrefix;
        const PluralAffix *pluralSuffix = bPositive ? &fPositiveSuffix : &fNegativeSuffix;
        if (optPluralRules == NULL || digits.isInfinite()) {
            prefix = &pluralPrefix->getOtherVariant();
            suffix = &pluralSuffix->getOtherVariant();
        } else {
            UnicodeString count(optPluralRules->select(digits));
            prefix = &pluralPrefix->getByCategory(count);
            suffix = &pluralSuffix->getByCategory(count);
        }
    }
    if (fWidth <= 0) {
        formatAffix(prefix, handler, appendTo);
        formatter.format(digits, handler, appendTo);
        return formatAffix(suffix, handler, appendTo);
    }
    int32_t codePointCount = countAffixChar32(prefix) + formatter.countChar32(digits) + countAffixChar32(suffix);
    int32_t paddingCount = fWidth - codePointCount;
    switch (fPadPosition) {
    case kPadBeforePrefix:
        appendPadding(paddingCount, appendTo);
        formatAffix(prefix, handler, appendTo);
        formatter.format(digits, handler, appendTo);
        return formatAffix(suffix, handler, appendTo);
    case kPadAfterPrefix:
        formatAffix(prefix, handler, appendTo);
        appendPadding(paddingCount, appendTo);
        formatter.format(digits, handler, appendTo);
        return formatAffix(suffix, handler, appendTo);
    case kPadBeforeSuffix:
        formatAffix(prefix, handler, appendTo);
        formatter.format(digits, handler, appendTo);
        appendPadding(paddingCount, appendTo);
        return formatAffix(suffix, handler, appendTo);
    case kPadAfterSuffix:
        formatAffix(prefix, handler, appendTo);
        formatter.format(digits, handler, appendTo);
        formatAffix(suffix, handler, appendTo);
        return appendPadding(paddingCount, appendTo);
    default:
        U_ASSERT(FALSE);
        return appendTo;
    }
}

UnicodeString &
DigitAffixesAndPadding::format(
        DigitList &value,
        const ValueFormatter &formatter,
        FieldPositionHandler &handler,
        const PluralRules *optPluralRules,
        UnicodeString &appendTo,
        UErrorCode &status) const {
    VisibleDigitsWithExponent digits;
    formatter.toVisibleDigitsWithExponent(
            value, digits, status);
    if (U_FAILURE(status)) {
        return appendTo;
    }
    return format(
            digits, formatter, handler, optPluralRules, appendTo, status);
}

UnicodeString &
DigitAffixesAndPadding::appendPadding(int32_t paddingCount, UnicodeString &appendTo) const {
    for (int32_t i = 0; i < paddingCount; ++i) {
        appendTo.append(fPadChar);
    }
    return appendTo;
}


U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
