// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 *   Copyright (C) 1997-2009,2014 International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 *   Date        Name        Description
 *   06/21/00    aliu        Creation.
 *******************************************************************************
 */

#include "unicode/utypes.h"

#if !UCONFIG_NO_TRANSLITERATION

#include "unicode/utrans.h"
#include "unicode/putil.h"
#include "unicode/rep.h"
#include "unicode/translit.h"
#include "unicode/unifilt.h"
#include "unicode/uniset.h"
#include "unicode/ustring.h"
#include "unicode/uenum.h"
#include "unicode/uset.h"
#include "uenumimp.h"
#include "cpputils.h"
#include "rbt.h"

// Following macro is to be followed by <return value>';' or just ';'
#define utrans_ENTRY(s) if ((s)==NULL || U_FAILURE(*(s))) return

/********************************************************************
 * Replaceable-UReplaceableCallbacks glue
 ********************************************************************/

/**
 * Make a UReplaceable + UReplaceableCallbacks into a Replaceable object.
 */
U_NAMESPACE_BEGIN
class ReplaceableGlue : public Replaceable {

    UReplaceable *rep;
    const UReplaceableCallbacks *func;

public:

    ReplaceableGlue(UReplaceable *replaceable,
                    const UReplaceableCallbacks *funcCallback);

    virtual ~ReplaceableGlue();

    virtual void handleReplaceBetween(int32_t start,
                                      int32_t limit,
                                      const UnicodeString& text);

    virtual void extractBetween(int32_t start,
                                int32_t limit,
                                UnicodeString& target) const;

    virtual void copy(int32_t start, int32_t limit, int32_t dest);

    // virtual Replaceable *clone() const { return NULL; } same as default

    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @draft ICU 2.2
     */
    virtual UClassID getDynamicClassID() const;

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @draft ICU 2.2
     */
    static UClassID U_EXPORT2 getStaticClassID();

protected:

    virtual int32_t getLength() const;

    virtual UChar getCharAt(int32_t offset) const;

    virtual UChar32 getChar32At(int32_t offset) const;
};

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ReplaceableGlue)

ReplaceableGlue::ReplaceableGlue(UReplaceable *replaceable,
                                 const UReplaceableCallbacks *funcCallback)
  : Replaceable()
{
    this->rep = replaceable;
    this->func = funcCallback;
}

ReplaceableGlue::~ReplaceableGlue() {}

int32_t ReplaceableGlue::getLength() const {
    return (*func->length)(rep);
}

UChar ReplaceableGlue::getCharAt(int32_t offset) const {
    return (*func->charAt)(rep, offset);
}

UChar32 ReplaceableGlue::getChar32At(int32_t offset) const {
    return (*func->char32At)(rep, offset);
}

void ReplaceableGlue::handleReplaceBetween(int32_t start,
                          int32_t limit,
                          const UnicodeString& text) {
    (*func->replace)(rep, start, limit, text.getBuffer(), text.length());
}

void ReplaceableGlue::extractBetween(int32_t start,
                                     int32_t limit,
                                     UnicodeString& target) const {
    (*func->extract)(rep, start, limit, target.getBuffer(limit-start));
    target.releaseBuffer(limit-start);
}

void ReplaceableGlue::copy(int32_t start, int32_t limit, int32_t dest) {
    (*func->copy)(rep, start, limit, dest);
}
U_NAMESPACE_END
/********************************************************************
 * General API
 ********************************************************************/
U_NAMESPACE_USE

U_CAPI UTransliterator* U_EXPORT2
utrans_openU(const UChar *id,
             int32_t idLength,
             UTransDirection dir,
             const UChar *rules,
             int32_t rulesLength,
             UParseError *parseError,
             UErrorCode *status) {
    if(status==NULL || U_FAILURE(*status)) {
        return NULL;
    }
    if (id == NULL) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return NULL;
    }
    UParseError temp;
    
    if(parseError == NULL){
        parseError = &temp;
    }
    
    UnicodeString ID(idLength<0, id, idLength); // r-o alias

    if(rules==NULL){

        Transliterator *trans = NULL;

        trans = Transliterator::createInstance(ID, dir, *parseError, *status);
        
        if(U_FAILURE(*status)){
            return NULL;
        }
        return (UTransliterator*) trans;
    }else{
        UnicodeString ruleStr(rulesLength < 0,
                              rules,
                              rulesLength); // r-o alias

        Transliterator *trans = NULL;
        trans = Transliterator::createFromRules(ID, ruleStr, dir, *parseError, *status); 
        if(U_FAILURE(*status)) { 
            return NULL;
        }

        return (UTransliterator*) trans;
    }
}

U_CAPI UTransliterator* U_EXPORT2
utrans_open(const char* id,
            UTransDirection dir,
            const UChar* rules,         /* may be Null */
            int32_t rulesLength,        /* -1 if null-terminated */ 
            UParseError* parseError,    /* may be Null */
            UErrorCode* status) {
    UnicodeString ID(id, -1, US_INV); // use invariant converter
    return utrans_openU(ID.getBuffer(), ID.length(), dir,
                        rules, rulesLength,
                        parseError, status);
}

U_CAPI UTransliterator* U_EXPORT2
utrans_openInverse(const UTransliterator* trans,
                   UErrorCode* status) {

    utrans_ENTRY(status) NULL;

    UTransliterator* result =
        (UTransliterator*) ((Transliterator*) trans)->createInverse(*status);

    return result;
}

U_CAPI UTransliterator* U_EXPORT2
utrans_clone(const UTransliterator* trans,
             UErrorCode* status) {

    utrans_ENTRY(status) NULL;

    if (trans == NULL) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return NULL;
    }

    Transliterator *t = ((Transliterator*) trans)->clone();
    if (t == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
    }
    return (UTransliterator*) t;
}

U_CAPI void U_EXPORT2
utrans_close(UTransliterator* trans) {
    delete (Transliterator*) trans;
}

U_CAPI const UChar * U_EXPORT2
utrans_getUnicodeID(const UTransliterator *trans,
                    int32_t *resultLength) {
    // Transliterator keeps its ID NUL-terminated
    const UnicodeString &ID=((Transliterator*) trans)->getID();
    if(resultLength!=NULL) {
        *resultLength=ID.length();
    }
    return ID.getBuffer();
}

U_CAPI int32_t U_EXPORT2
utrans_getID(const UTransliterator* trans,
             char* buf,
             int32_t bufCapacity) {
    return ((Transliterator*) trans)->getID().extract(0, 0x7fffffff, buf, bufCapacity, US_INV);
}

U_CAPI void U_EXPORT2
utrans_register(UTransliterator* adoptedTrans,
                UErrorCode* status) {
    utrans_ENTRY(status);
    // status currently ignored; may remove later
    Transliterator::registerInstance((Transliterator*) adoptedTrans);
}

U_CAPI void U_EXPORT2
utrans_unregisterID(const UChar* id, int32_t idLength) {
    UnicodeString ID(idLength<0, id, idLength); // r-o alias
    Transliterator::unregister(ID);
}

U_CAPI void U_EXPORT2
utrans_unregister(const char* id) {
    UnicodeString ID(id, -1, US_INV); // use invariant converter
    Transliterator::unregister(ID);
}

U_CAPI void U_EXPORT2
utrans_setFilter(UTransliterator* trans,
                 const UChar* filterPattern,
                 int32_t filterPatternLen,
                 UErrorCode* status) {

    utrans_ENTRY(status);
    UnicodeFilter* filter = NULL;
    if (filterPattern != NULL && *filterPattern != 0) {
        // Create read only alias of filterPattern:
        UnicodeString pat(filterPatternLen < 0, filterPattern, filterPatternLen);
        filter = new UnicodeSet(pat, *status);
        /* test for NULL */
        if (filter == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        if (U_FAILURE(*status)) {
            delete filter;
            filter = NULL;
        }
    }
    ((Transliterator*) trans)->adoptFilter(filter);
}

U_CAPI int32_t U_EXPORT2
utrans_countAvailableIDs(void) {
    return Transliterator::countAvailableIDs();
}

U_CAPI int32_t U_EXPORT2
utrans_getAvailableID(int32_t index,
                      char* buf, // may be NULL
                      int32_t bufCapacity) {
    return Transliterator::getAvailableID(index).extract(0, 0x7fffffff, buf, bufCapacity, US_INV);
}

/* Transliterator UEnumeration ---------------------------------------------- */

typedef struct UTransEnumeration {
    UEnumeration uenum;
    int32_t index, count;
} UTransEnumeration;

U_CDECL_BEGIN
static int32_t U_CALLCONV
utrans_enum_count(UEnumeration *uenum, UErrorCode *pErrorCode) {
    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
        return 0;
    }
    return ((UTransEnumeration *)uenum)->count;
}

static const UChar* U_CALLCONV
utrans_enum_unext(UEnumeration *uenum,
                  int32_t* resultLength,
                  UErrorCode *pErrorCode) {
    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
        return 0;
    }

    UTransEnumeration *ute=(UTransEnumeration *)uenum;
    int32_t index=ute->index;
    if(index<ute->count) {
        const UnicodeString &ID=Transliterator::getAvailableID(index);
        ute->index=index+1;
        if(resultLength!=NULL) {
            *resultLength=ID.length();
        }
        // Transliterator keeps its ID NUL-terminated
        return ID.getBuffer();
    }

    if(resultLength!=NULL) {
        *resultLength=0;
    }
    return NULL;
}

static void U_CALLCONV
utrans_enum_reset(UEnumeration *uenum, UErrorCode *pErrorCode) {
    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
        return;
    }

    UTransEnumeration *ute=(UTransEnumeration *)uenum;
    ute->index=0;
    ute->count=Transliterator::countAvailableIDs();
}

static void U_CALLCONV
utrans_enum_close(UEnumeration *uenum) {
    uprv_free(uenum);
}
U_CDECL_END

static const UEnumeration utransEnumeration={
    NULL,
    NULL,
    utrans_enum_close,
    utrans_enum_count,
    utrans_enum_unext,
    uenum_nextDefault,
    utrans_enum_reset
};

U_CAPI UEnumeration * U_EXPORT2
utrans_openIDs(UErrorCode *pErrorCode) {
    UTransEnumeration *ute;

    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
        return NULL;
    }

    ute=(UTransEnumeration *)uprv_malloc(sizeof(UTransEnumeration));
    if(ute==NULL) {
        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    ute->uenum=utransEnumeration;
    ute->index=0;
    ute->count=Transliterator::countAvailableIDs();
    return (UEnumeration *)ute;
}

/********************************************************************
 * Transliteration API
 ********************************************************************/

U_CAPI void U_EXPORT2
utrans_trans(const UTransliterator* trans,
             UReplaceable* rep,
             const UReplaceableCallbacks* repFunc,
             int32_t start,
             int32_t* limit,
             UErrorCode* status) {

    utrans_ENTRY(status);

    if (trans == 0 || rep == 0 || repFunc == 0 || limit == 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    ReplaceableGlue r(rep, repFunc);

    *limit = ((Transliterator*) trans)->transliterate(r, start, *limit);
}

U_CAPI void U_EXPORT2
utrans_transIncremental(const UTransliterator* trans,
                        UReplaceable* rep,
                        const UReplaceableCallbacks* repFunc,
                        UTransPosition* pos,
                        UErrorCode* status) {

    utrans_ENTRY(status);

    if (trans == 0 || rep == 0 || repFunc == 0 || pos == 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    ReplaceableGlue r(rep, repFunc);

    ((Transliterator*) trans)->transliterate(r, *pos, *status);
}

U_CAPI void U_EXPORT2
utrans_transUChars(const UTransliterator* trans,
                   UChar* text,
                   int32_t* textLength,
                   int32_t textCapacity,
                   int32_t start,
                   int32_t* limit,
                   UErrorCode* status) {

    utrans_ENTRY(status);

    if (trans == 0 || text == 0 || limit == 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
 
    int32_t textLen = (textLength == NULL || *textLength < 0)
        ? u_strlen(text) : *textLength;
    // writeable alias: for this ct, len CANNOT be -1 (why?)
    UnicodeString str(text, textLen, textCapacity);

    *limit = ((Transliterator*) trans)->transliterate(str, start, *limit);

    // Copy the string buffer back to text (only if necessary)
    // and fill in *neededCapacity (if neededCapacity != NULL).
    textLen = str.extract(text, textCapacity, *status);
    if(textLength != NULL) {
        *textLength = textLen;
    }
}

U_CAPI void U_EXPORT2
utrans_transIncrementalUChars(const UTransliterator* trans,
                              UChar* text,
                              int32_t* textLength,
                              int32_t textCapacity,
                              UTransPosition* pos,
                              UErrorCode* status) {

    utrans_ENTRY(status);

    if (trans == 0 || text == 0 || pos == 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    int32_t textLen = (textLength == NULL || *textLength < 0)
        ? u_strlen(text) : *textLength;
    // writeable alias: for this ct, len CANNOT be -1 (why?)
    UnicodeString str(text, textLen, textCapacity);

    ((Transliterator*) trans)->transliterate(str, *pos, *status);

    // Copy the string buffer back to text (only if necessary)
    // and fill in *neededCapacity (if neededCapacity != NULL).
    textLen = str.extract(text, textCapacity, *status);
    if(textLength != NULL) {
        *textLength = textLen;
    }
}

U_CAPI int32_t U_EXPORT2
utrans_toRules(     const UTransliterator* trans,
                    UBool escapeUnprintable,
                    UChar* result, int32_t resultLength,
                    UErrorCode* status) {
    utrans_ENTRY(status) 0;
    if ( (result==NULL)? resultLength!=0: resultLength<0 ) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }

    UnicodeString res;
    res.setTo(result, 0, resultLength);
    ((Transliterator*) trans)->toRules(res, escapeUnprintable);
    return res.extract(result, resultLength, *status);
}

U_CAPI USet* U_EXPORT2
utrans_getSourceSet(const UTransliterator* trans,
                    UBool ignoreFilter,
                    USet* fillIn,
                    UErrorCode* status) {
    utrans_ENTRY(status) fillIn;

    if (fillIn == NULL) {
        fillIn = uset_openEmpty();
    }
    if (ignoreFilter) {
        ((Transliterator*) trans)->handleGetSourceSet(*((UnicodeSet*)fillIn));
    } else {
        ((Transliterator*) trans)->getSourceSet(*((UnicodeSet*)fillIn));
    }
    return fillIn;
}

#endif /* #if !UCONFIG_NO_TRANSLITERATION */
