/*
**********************************************************************
*   Copyright (c) 2001-2004, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   11/19/2001  aliu        Creation.
**********************************************************************
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_TRANSLITERATION

#include "esctrn.h"
#include "util.h"

U_NAMESPACE_BEGIN

static const UChar UNIPRE[] = {85,43,0}; // "U+"
static const UChar BS_u[] = {92,117,0}; // "\\u"
static const UChar BS_U[] = {92,85,0}; // "\\U"
static const UChar XMLPRE[] = {38,35,120,0}; // "&#x"
static const UChar XML10PRE[] = {38,35,0}; // "&#"
static const UChar PERLPRE[] = {92,120,123,0}; // "\\x{"
static const UChar SEMI[] = {59,0}; // ";"
static const UChar RBRACE[] = {125,0}; // "}"
static const UChar EMPTY[] = {0}; // ""

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EscapeTransliterator)

/**
 * Factory methods
 */
Transliterator* EscapeTransliterator::_createUnicode(const UnicodeString& ID, Token /*context*/) {
    // Unicode: "U+10FFFF" hex, min=4, max=6
    return new EscapeTransliterator(ID, UNIPRE, EMPTY, 16, 4, TRUE, NULL);
}
Transliterator* EscapeTransliterator::_createJava(const UnicodeString& ID, Token /*context*/) {
    // Java: "\\uFFFF" hex, min=4, max=4
    return new EscapeTransliterator(ID, BS_u, EMPTY, 16, 4, FALSE, NULL);
}
Transliterator* EscapeTransliterator::_createC(const UnicodeString& ID, Token /*context*/) {
    // C: "\\uFFFF" hex, min=4, max=4; \\U0010FFFF hex, min=8, max=8
    return new EscapeTransliterator(ID, BS_u, EMPTY, 16, 4, TRUE,
             new EscapeTransliterator(EMPTY, BS_U, EMPTY, 16, 8, TRUE, NULL));
}
Transliterator* EscapeTransliterator::_createXML(const UnicodeString& ID, Token /*context*/) {
    // XML: "&#x10FFFF;" hex, min=1, max=6
    return new EscapeTransliterator(ID, XMLPRE, SEMI, 16, 1, TRUE, NULL);
}
Transliterator* EscapeTransliterator::_createXML10(const UnicodeString& ID, Token /*context*/) {
    // XML10: "&1114111;" dec, min=1, max=7 (not really "Any-Hex")
    return new EscapeTransliterator(ID, XML10PRE, SEMI, 10, 1, TRUE, NULL);
}
Transliterator* EscapeTransliterator::_createPerl(const UnicodeString& ID, Token /*context*/) {
    // Perl: "\\x{263A}" hex, min=1, max=6
    return new EscapeTransliterator(ID, PERLPRE, RBRACE, 16, 1, TRUE, NULL);
}

/**
 * Registers standard variants with the system.  Called by
 * Transliterator during initialization.
 */
void EscapeTransliterator::registerIDs() {
    Token t = integerToken(0);

    Transliterator::_registerFactory(UNICODE_STRING_SIMPLE("Any-Hex/Unicode"), _createUnicode, t);

    Transliterator::_registerFactory(UNICODE_STRING_SIMPLE("Any-Hex/Java"), _createJava, t);

    Transliterator::_registerFactory(UNICODE_STRING_SIMPLE("Any-Hex/C"), _createC, t);

    Transliterator::_registerFactory(UNICODE_STRING_SIMPLE("Any-Hex/XML"), _createXML, t);

    Transliterator::_registerFactory(UNICODE_STRING_SIMPLE("Any-Hex/XML10"), _createXML10, t);

    Transliterator::_registerFactory(UNICODE_STRING_SIMPLE("Any-Hex/Perl"), _createPerl, t);

    Transliterator::_registerFactory(UNICODE_STRING_SIMPLE("Any-Hex"), _createJava, t);
}

/**
 * Constructs an escape transliterator with the given ID and
 * parameters.  See the class member documentation for details.
 */
EscapeTransliterator::EscapeTransliterator(const UnicodeString& newID,
                         const UnicodeString& _prefix, const UnicodeString& _suffix,
                         int32_t _radix, int32_t _minDigits,
                         UBool _grokSupplementals,
                         EscapeTransliterator* adoptedSupplementalHandler) :
    Transliterator(newID, NULL)
{
    this->prefix = _prefix;
    this->suffix = _suffix;
    this->radix = _radix;
    this->minDigits = _minDigits;
    this->grokSupplementals = _grokSupplementals;
    this->supplementalHandler = adoptedSupplementalHandler;
}

/**
 * Copy constructor.
 */
EscapeTransliterator::EscapeTransliterator(const EscapeTransliterator& o) :
    Transliterator(o),
    prefix(o.prefix),
    suffix(o.suffix),
    radix(o.radix),
    minDigits(o.minDigits),
    grokSupplementals(o.grokSupplementals) {
    supplementalHandler = (o.supplementalHandler != 0) ?
        new EscapeTransliterator(*o.supplementalHandler) : NULL;
}

EscapeTransliterator::~EscapeTransliterator() {
    delete supplementalHandler;
}

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

/**
 * Implements {@link Transliterator#handleTransliterate}.
 */
void EscapeTransliterator::handleTransliterate(Replaceable& text,
                                               UTransPosition& pos,
                                               UBool /*isIncremental*/) const
{
    /* TODO: Verify that isIncremental can be ignored */
    int32_t start = pos.start;
    int32_t limit = pos.limit;

    UnicodeString buf(prefix);
    int32_t prefixLen = prefix.length();
    UBool redoPrefix = FALSE;

    while (start < limit) {
        int32_t c = grokSupplementals ? text.char32At(start) : text.charAt(start);
        int32_t charLen = grokSupplementals ? UTF_CHAR_LENGTH(c) : 1;

        if ((c & 0xFFFF0000) != 0 && supplementalHandler != NULL) {
            buf.truncate(0);
            buf.append(supplementalHandler->prefix);
            ICU_Utility::appendNumber(buf, c, supplementalHandler->radix,
                                  supplementalHandler->minDigits);
            buf.append(supplementalHandler->suffix);
            redoPrefix = TRUE;
        } else {
            if (redoPrefix) {
                buf.truncate(0);
                buf.append(prefix);
                redoPrefix = FALSE;
            } else {
                buf.truncate(prefixLen);
            }
            ICU_Utility::appendNumber(buf, c, radix, minDigits);
            buf.append(suffix);
        }

        text.handleReplaceBetween(start, start + charLen, buf);
        start += buf.length();
        limit += buf.length() - charLen;
    }

    pos.contextLimit += limit - pos.limit;
    pos.limit = limit;
    pos.start = start;
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_TRANSLITERATION */

//eof
