/*
 * Copyright (C) 2015, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *
 * file name: digitaffix.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 "digitaffix.h"
#include "fphdlimp.h"
#include "uassert.h"
#include "unistrappender.h"

U_NAMESPACE_BEGIN

DigitAffix::DigitAffix() : fAffix(), fAnnotations() {
}

DigitAffix::DigitAffix(
        const UChar *value, int32_t charCount, int32_t fieldId) 
        : fAffix(value, charCount),
          fAnnotations(charCount, (UChar) fieldId, charCount) {
}

void
DigitAffix::remove() {
    fAffix.remove();
    fAnnotations.remove();
}

void
DigitAffix::appendUChar(UChar value, int32_t fieldId) {
    fAffix.append(value);
    fAnnotations.append((UChar) fieldId);
}

void
DigitAffix::append(const UnicodeString &value, int32_t fieldId) {
    fAffix.append(value);
    {
        UnicodeStringAppender appender(fAnnotations);
        int32_t len = value.length();
        for (int32_t i = 0; i < len; ++i) {
            appender.append((UChar) fieldId);
        }
    }
}

void
DigitAffix::setTo(const UnicodeString &value, int32_t fieldId) {
    fAffix = value;
    fAnnotations.remove();
    {
        UnicodeStringAppender appender(fAnnotations);
        int32_t len = value.length();
        for (int32_t i = 0; i < len; ++i) {
            appender.append((UChar) fieldId);
        }
    }
}

void
DigitAffix::append(const UChar *value, int32_t charCount, int32_t fieldId) {
    fAffix.append(value, charCount);
    {
        UnicodeStringAppender appender(fAnnotations);
        for (int32_t i = 0; i < charCount; ++i) {
            appender.append((UChar) fieldId);
        }
    }
}

UnicodeString &
DigitAffix::format(FieldPositionHandler &handler, UnicodeString &appendTo) const {
    int32_t len = fAffix.length();
    if (len == 0) {
        return appendTo;
    }
    if (!handler.isRecording()) {
        return appendTo.append(fAffix);
    }
    U_ASSERT(fAffix.length() == fAnnotations.length());
    int32_t appendToStart = appendTo.length();
    int32_t lastId = (int32_t) fAnnotations.charAt(0);
    int32_t lastIdStart = 0;
    for (int32_t i = 1; i < len; ++i) {
        int32_t id = (int32_t) fAnnotations.charAt(i);
        if (id != lastId) {
            if (lastId != UNUM_FIELD_COUNT) {
                handler.addAttribute(lastId, appendToStart + lastIdStart, appendToStart + i);
            }
            lastId = id;
            lastIdStart = i;
        }
    }
    if (lastId != UNUM_FIELD_COUNT) {
        handler.addAttribute(lastId, appendToStart + lastIdStart, appendToStart + len);
    }
    return appendTo.append(fAffix);
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */
