/*
**********************************************************************
*   Copyright (C) 2001, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   05/24/01    aliu        Creation.
**********************************************************************
*/

#include "unicode/uchar.h"
#include "unicode/titletrn.h"

U_NAMESPACE_BEGIN

/**
 * ID for this transliterator.
 */
const char TitlecaseTransliterator::_ID[] = "Any-Title";

TitlecaseTransliterator::TitlecaseTransliterator(UnicodeFilter* adoptedFilter) :
    Transliterator(_ID, adoptedFilter) {
    // Need to look back 2 characters in the case of "can't"
    setMaximumContextLength(2);
}

/**
 * Destructor.
 */
TitlecaseTransliterator::~TitlecaseTransliterator() {}

/**
 * Copy constructor.
 */
TitlecaseTransliterator::TitlecaseTransliterator(const TitlecaseTransliterator& o) :
    Transliterator(o) {}

/**
 * Assignment operator.
 */
TitlecaseTransliterator& TitlecaseTransliterator::operator=(
                             const TitlecaseTransliterator& o) {
    Transliterator::operator=(o);
    return *this;
}

/**
 * Transliterator API.
 */
Transliterator* TitlecaseTransliterator::clone(void) const {
    return new TitlecaseTransliterator(*this);
}

/**
 * Implements {@link Transliterator#handleTransliterate}.
 */
void TitlecaseTransliterator::handleTransliterate(
                                  Replaceable& text, UTransPosition& offsets,
                                  UBool isIncremental) const {

    // NOTE: This method contains some special case code to handle
    // apostrophes between alpha characters.  We want to have
    // "can't" => "Can't" (not "Can'T").  This may be incorrect
    // for some locales, e.g., "l'arbre" => "L'Arbre" (?).
    // TODO: Revisit this.

    // Determine if there is a preceding letter character in the
    // left context (if there is any left context).
    UBool wasLastCharALetter = FALSE;
    if (offsets.start > offsets.contextStart) {
        UChar c = text.charAt(offsets.start - 1);
        // Handle the case "Can'|t", where the | marks the context
        // boundary.  We only handle a single apostrophe.
        if (c == 0x0027 /*'*/ && (offsets.start-2) >= offsets.contextStart) {
            c = text.charAt(offsets.start - 2);
        }
        wasLastCharALetter = u_isalpha(c);
    }

    // The buffer used to batch up changes to be made
    UnicodeString buffer;
    int32_t bufStart = 0;
    int32_t bufLimit = -1;

    int32_t start;
    for (start = offsets.start; start < offsets.limit; ++start) {
        // For each character, if the preceding character was a
        // non-letter, and this character is a letter, then apply
        // the titlecase transformation.  Otherwise apply the
        // lowercase transformation.
        UChar32 c = text.charAt(start);
        if (u_isalpha(c)) {
            UChar32 newChar;
            if (wasLastCharALetter) {
                newChar = u_tolower(c);
            } else {
                newChar = u_totitle(c);
            }
            if (c != newChar) {
                // This is the simple way of doing this:
                //text.replace(start, start+1,
                //             String.valueOf((char) newChar));

                // Instead, we do something more complicated that
                // minimizes the number of calls to
                // Replaceable.replace().  We batch up the changes
                // we want to make in a buffer, recording
                // our position and dumping the buffer out when a
                // non-contiguous change arrives.
                if (bufLimit == start) {
                    ++bufLimit;
                    // Fall through and append newChar below
                } else {
                    if (buffer.length() > 0) {
                        text.handleReplaceBetween(bufStart, bufLimit, buffer);
                        buffer.truncate(0);
                    }
                    bufStart = start;
                    bufLimit = start+1;
                    // Fall through and append newChar below
                }
                buffer.append(newChar);
            }
            wasLastCharALetter = TRUE;
        } else if (c == 0x0027 /*'*/ && wasLastCharALetter) {
            // Ignore a single embedded apostrophe, so that "can't" =>
            // "Can't", not "Can'T".
        } else {
            wasLastCharALetter = FALSE;
        }
    }
    // assert(start == offsets.limit);
    offsets.start = start;

    if (buffer.length() > 0) {
        text.handleReplaceBetween(bufStart, bufLimit, buffer);
    }
}

U_NAMESPACE_END

