/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 2000-2003, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/
/************************************************************************
*   Date        Name        Description
*   1/03/2000   Madhu        Creation.
************************************************************************/

#include "unicode/utypes.h"

#if !UCONFIG_NO_TRANSLITERATION

#include "ittrans.h"
#include "transapi.h"
#include "unicode/utypes.h"
#include "unicode/translit.h"
#include "rbt.h"
#include "unicode/unifilt.h"
#include "cpdtrans.h"
#include "nultrans.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "unicode/rep.h"
#include "unicode/locid.h"
#include "unicode/uniset.h"
int32_t getInt(UnicodeString str)
{
    char buffer[20];
    int len=str.length();
    if(len>=20) {
        len=19;
    }
    str.extract(0, len, buffer, "");
    buffer[len]=0;
    return atoi(buffer);
}

//---------------------------------------------
// runIndexedTest
//---------------------------------------------

void
TransliteratorAPITest::runIndexedTest(int32_t index, UBool exec,
                                      const char* &name, char* /*par*/) {
    switch (index) {
        TESTCASE(0,TestgetInverse);
        TESTCASE(1,TestgetID);
        TESTCASE(2,TestGetDisplayName);
        TESTCASE(3,TestTransliterate1);
        TESTCASE(4,TestTransliterate2);
        TESTCASE(5,TestTransliterate3);
        TESTCASE(6,TestSimpleKeyboardTransliterator);
        TESTCASE(7,TestKeyboardTransliterator1);
        TESTCASE(8,TestKeyboardTransliterator2);
        TESTCASE(9,TestKeyboardTransliterator3);
        TESTCASE(10,TestGetAdoptFilter);
        TESTCASE(11,TestClone);
        TESTCASE(12,TestNullTransliterator);
        TESTCASE(13,TestRegisterUnregister);
        default: name = ""; break;
    }
}


void TransliteratorAPITest::TestgetID() {
    UnicodeString trans="Latin-Greek";
    UnicodeString ID;
    UParseError parseError;
    UErrorCode status = U_ZERO_ERROR;
    Transliterator* t= Transliterator::createInstance(trans, UTRANS_FORWARD, parseError, status);
    if(t==0 || U_FAILURE(status)){
        errln("FAIL: construction of Latin-Greek");
        return;
    }else{
        ID= t->getID();
        if(ID != trans)
            errln("FAIL: getID returned " + ID + " instead of Latin-Greek");
        delete t;
    }
    int i;
    for (i=0; i<Transliterator::countAvailableIDs(); i++){
        status = U_ZERO_ERROR;
        ID = (UnicodeString) Transliterator::getAvailableID(i);
        t = Transliterator::createInstance(ID, UTRANS_FORWARD, parseError, status);
        if(t == 0){
            errln("FAIL: " + ID);
            continue;
        }
        if(ID != t->getID())
            errln("FAIL: getID() returned " + t->getID() + " instead of " + ID);
        delete t;
    }
    ID=(UnicodeString)Transliterator::getAvailableID(i);
    if(ID != (UnicodeString)Transliterator::getAvailableID(0)){
        errln("FAIL: calling getAvailableID(index > coundAvailableIDs) should make index=0\n");
    }

    Transliterator* t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
    Transliterator* t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError, status);
    if(t1 ==0 || t2 == 0){
        errln("FAIL: construction");
        return;
    }
    Transliterator* t3=t1->clone();
    Transliterator* t4=t2->clone();

    if(t1->getID() != t3->getID() || t2->getID() != t4->getID() || 
       t1->getID() == t4->getID() || t2->getID() == t3->getID() || 
       t1->getID()== t4->getID() )
            errln("FAIL: getID or clone failed");


    Transliterator* t5=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
    if(t5 == 0)
        errln("FAIL: construction");
    if(t1->getID() != t5->getID() || t5->getID() != t3->getID() || t1->getID() != t3->getID())
        errln("FAIL: getID or clone failed");


    delete t1;
    delete t2;
    delete t3;
    delete t4;
    delete t5;
}

void TransliteratorAPITest::TestgetInverse() {
     UErrorCode status = U_ZERO_ERROR;
     UParseError parseError;
     Transliterator* t1    = Transliterator::createInstance("Katakana-Latin", UTRANS_FORWARD, parseError, status);
     Transliterator* invt1 = Transliterator::createInstance("Latin-Katakana", UTRANS_FORWARD, parseError, status);
     Transliterator* t2    = Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
     Transliterator* invt2 = Transliterator::createInstance("Devanagari-Latin", UTRANS_FORWARD, parseError, status);
     if(t1 == 0 || invt1 == 0 || t2 == 0 || invt2 == 0) {
         errln("FAIL: in instantiation");
         return;
     }

     Transliterator* inverse1=t1->createInverse(status);
     Transliterator* inverse2=t2->createInverse(status);
     if(inverse1->getID() != invt1->getID() || inverse2->getID() != invt2->getID()
        || inverse1->getID() == invt2->getID() || inverse2->getID() == invt1->getID() ) 
        errln("FAIL: getInverse() ");

     UnicodeString TransID[]={
       "Halfwidth-Fullwidth",
       "Fullwidth-Halfwidth",
       "Greek-Latin" ,
       "Latin-Greek", 
       //"Arabic-Latin", // removed in 2.0
       //"Latin-Arabic",
       "Katakana-Latin",
       "Latin-Katakana",
       //"Hebrew-Latin", // removed in 2.0
       //"Latin-Hebrew",
       "Cyrillic-Latin", 
       "Latin-Cyrillic", 
       "Devanagari-Latin", 
       "Latin-Devanagari", 
       "Any-Hex",
       "Hex-Any"
     };
     for(uint32_t i=0; i<sizeof(TransID)/sizeof(TransID[0]); i=i+2){
         Transliterator *trans1=Transliterator::createInstance(TransID[i], UTRANS_FORWARD, parseError, status);
         if(t1 == 0){
           errln("FAIL: in instantiation for" + TransID[i]);
           continue;
         }
         Transliterator *inver1=trans1->createInverse(status);
         if(inver1->getID() != TransID[i+1] )
             errln("FAIL :getInverse() for " + TransID[i] + " returned " + inver1->getID() + " instead of " + TransID[i+1]);
         delete inver1;
         delete trans1;
     }
     delete t1;
     delete t2;
     delete invt1;
     delete invt2;
     delete inverse1;
     delete inverse2;

}

void TransliteratorAPITest::TestClone(){
    Transliterator *t1, *t2, *t3, *t4;
    UErrorCode status = U_ZERO_ERROR;
    UParseError parseError;
    t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
    t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError, status);
    if(t1 == 0 || t2 == 0){
        errln("FAIL: construction");
        return;
    }
    t3=t1->clone();
    t4=t2->clone();

    if(t1->getID() != t3->getID() || t2->getID() != t4->getID() )
        errln("FAIL: clone or getID failed");
    if(t1->getID()==t4->getID() || t2->getID()==t3->getID() ||  t1->getID()==t4->getID())
        errln("FAIL: clone or getID failed");
     
    delete t1;
    delete t2;
    delete t3;
    delete t4;

}

void TransliteratorAPITest::TestGetDisplayName() {
    UnicodeString dispNames[]= { 
         //ID, displayName
        //"CurlyQuotes-StraightQuotes" ,"CurlyQuotes to StraightQuotes",
          "Any-Hex"                ,"Any to Hex Escape",
          "Halfwidth-Fullwidth"        ,"Halfwidth to Fullwidth" ,
          //"Latin-Arabic"               ,"Latin to Arabic"      ,
          "Latin-Devanagari"           ,"Latin to Devanagari"  ,
          "Greek-Latin"                ,"Greek to Latin"       ,
          //"Arabic-Latin"               ,"Arabic to Latin"      ,
          "Hex-Any"                ,"Hex Escape to Any",
          "Cyrillic-Latin"             ,"Cyrillic to Latin"    ,
          "Latin-Greek"                ,"Latin to Greek"       ,
          "Latin-Katakana"                 ,"Latin to Katakana"        ,
          //"Latin-Hebrew"               ,"Latin to Hebrew"      ,
          "Katakana-Latin"                 ,"Katakana to Latin"        
      };
    UnicodeString name="";
    Transliterator* t;
    UnicodeString message;
    UErrorCode status = U_ZERO_ERROR;
    UParseError parseError;

#if UCONFIG_NO_FORMATTING
    logln("Skipping, UCONFIG_NO_FORMATTING is set\n");
    return;
#else

    for (uint32_t i=0; i<sizeof(dispNames)/sizeof(dispNames[0]); i=i+2 ) {
        t = Transliterator::createInstance(dispNames[i+0], UTRANS_FORWARD, parseError, status);
        if(t==0){
             errln("FAIL: construction: " + dispNames[i+0]);
             status = U_ZERO_ERROR;
             continue;
        }
        t->getDisplayName(t->getID(), name);
        message="Display name for ID:" + t->getID();
      //  doTest(message, name, dispNames[i+1]); //!!! This will obviously fail for any locale other than english and its children!!!
        name=""; 
        t->getDisplayName(t->getID(), Locale::getUS(), name);
        message.remove();
        message.append("Display name for on english locale ID:");
        message.append(t->getID());
    // message="Display name for on english locale ID:" + t->getID();
        doTest(message, name, dispNames[i+1]);
        name="";

        delete t;
    }
#endif

}

void TransliteratorAPITest::TestTransliterate1(){

    UnicodeString Data[]={ 
         //ID, input string, transliterated string
         "Any-Hex",         "hello",    UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", "") ,
         "Hex-Any",         UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), "hello"  ,
         "Latin-Devanagari",CharsToUnicodeString("bha\\u0304rata"), CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924") ,
         "Latin-Devanagari",UnicodeString("kra ksha khra gra cra dya dhya",""), CharsToUnicodeString("\\u0915\\u094D\\u0930 \\u0915\\u094D\\u0936 \\u0916\\u094D\\u0930 \\u0917\\u094D\\u0930 \\u091a\\u094D\\u0930 \\u0926\\u094D\\u092F \\u0927\\u094D\\u092F") ,

         "Devanagari-Latin",    CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"),        UnicodeString("bh\\u0101rata"),
     //  "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"),               CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042") ,
     //  "Expanded-Contracted", CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042"), CharsToUnicodeString("\\u00C0\\u00C1\\u0042") ,
         //"Latin-Arabic",        "aap",                                 CharsToUnicodeString("\\u0627\\u06A4")     ,
         //"Arabic-Latin",        CharsToUnicodeString("\\u0627\\u06A4"),                      "aap" 
    };

    UnicodeString gotResult;
    UnicodeString temp;
    UnicodeString message;
    Transliterator* t;
    logln("Testing transliterate");
    UErrorCode status = U_ZERO_ERROR;
    UParseError parseError;

    for(uint32_t i=0;i<sizeof(Data)/sizeof(Data[0]); i=i+3){
        t=Transliterator::createInstance(Data[i+0], UTRANS_FORWARD, parseError, status);
        if(t==0){
            errln("FAIL: construction: " + Data[i+0] + " Error: "  + u_errorName(status));
            errln("PreContext: " + prettify(parseError.preContext) + " PostContext: " + prettify( parseError.postContext) );
            status = U_ZERO_ERROR;
            continue;
        }
        gotResult = Data[i+1];
        t->transliterate(gotResult);
        message=t->getID() + "->transliterate(UnicodeString, UnicodeString) for\n\t Source:" + prettify(Data[i+1]);
        doTest(message, gotResult, Data[i+2]);

        //doubt here
        temp=Data[i+1];
        t->transliterate(temp);
        message.remove();
        message.append(t->getID());
        message.append("->transliterate(Replaceable) for \n\tSource:");
        message.append(Data[i][1]);
        doTest(message, temp, Data[i+2]);

        callEverything(t, __LINE__);
        delete t;
    }
}

void TransliteratorAPITest::TestTransliterate2(){
     //testing tranliterate(String text, int start, int limit, StringBuffer result)
   UnicodeString Data2[]={
         //ID, input string, start, limit, transliterated string
         "Any-Hex",         "hello! How are you?",  "0", "5", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F! How are you?", "") ,
         "Any-Hex",         "hello! How are you?",  "7", "12", UnicodeString("\\u0048\\u006F\\u0077\\u0020\\u0061", ""), UnicodeString("hello! \\u0048\\u006F\\u0077\\u0020\\u0061re you?", ""),
         "Hex-Any",         CharsToUnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F\\u0021\\u0020"), "0", "5",  "hello", "hello! "  ,
       //  "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"),        "1", "2",  CharsToUnicodeString("\\u0041\\u0301"), CharsToUnicodeString("\\u00C0\\u0041\\u0301\\u0042") ,
         "Devanagari-Latin",    CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), "0", "1",  "bha", CharsToUnicodeString("bha\\u093E\\u0930\\u0924") ,
         "Devanagari-Latin",    CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), "1", "2",  "\\u0314\\u0101", CharsToUnicodeString("\\u092D\\u0314\\u0101\\u0930\\u0924")  

    };
    logln("\n   Testing transliterate(String, int, int, StringBuffer)");
    Transliterator* t;
    UnicodeString gotResBuf;
    UnicodeString temp;
    int32_t start, limit;
    UErrorCode status = U_ZERO_ERROR;
    UParseError parseError;

    for(uint32_t i=0; i<sizeof(Data2)/sizeof(Data2[0]); i=i+6){
        t=Transliterator::createInstance(Data2[i+0], UTRANS_FORWARD, parseError, status);
        if(t==0){
            errln("FAIL: construction: " + prettify(Data2[i+0]));
            continue;
        }
        start=getInt(Data2[i+2]);
        limit=getInt(Data2[i+3]);
        Data2[i+1].extractBetween(start, limit, gotResBuf);
        t->transliterate(gotResBuf);
        //  errln("FAIL: calling transliterate on " + t->getID());
        doTest(t->getID() + ".transliterate(UnicodeString, int32_t, int32_t, UnicodeString):(" + start + "," + limit + ")  for \n\t source: " + prettify(Data2[i+1]), gotResBuf, Data2[i+4]);

        temp=Data2[i+1];
        t->transliterate(temp, start, limit);
        doTest(t->getID() + ".transliterate(Replaceable, int32_t, int32_t, ):(" + start + "," + limit + ")  for \n\t source: " + prettify(Data2[i+1]), temp, Data2[i+5]);
        status = U_ZERO_ERROR;
        callEverything(t, __LINE__);
        delete t;
        t = NULL;
    }

    status = U_ZERO_ERROR;
    logln("\n   Try calling transliterate with illegal start and limit values");
    t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
    if(U_FAILURE(status)) {
      errln("Error creating transliterator %s", u_errorName(status));
      delete t;
      return;
    }
    gotResBuf = temp = "try start greater than limit";
    t->transliterate(gotResBuf, 10, 5);
    if(gotResBuf == temp) {
        logln("OK: start greater than limit value handled correctly");
    } else {
        errln("FAIL: start greater than limit value returned" + gotResBuf);
    }

    callEverything(t, __LINE__);
    delete t;

}
void TransliteratorAPITest::TestTransliterate3(){
    UnicodeString rs="This is the replaceable String";
    UnicodeString Data[] = {
        "0",  "0",  "This is the replaceable String",
        "2",  "3",  UnicodeString("Th\\u0069s is the replaceable String", ""),
        "21", "23", UnicodeString("Th\\u0069s is the repl\\u0061\\u0063eable String", ""),
        "14", "17", UnicodeString("Th\\u0069s is t\\u0068\\u0065\\u0020repl\\u0061\\u0063eable String", ""),
    };
    int start, limit;
    UnicodeString message;
    UParseError parseError;
    UErrorCode status = U_ZERO_ERROR;
    Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
    if(U_FAILURE(status)) {
      errln("Error creating transliterator %s", u_errorName(status));
      delete t;
      return;
    }

    if(t == 0)
        errln("FAIL : construction");
    for(uint32_t i=0; i<sizeof(Data)/sizeof(Data[0]); i=i+3){
        start=getInt(Data[i+0]);
        limit=getInt(Data[i+1]);
        t->transliterate(rs, start, limit);
        message=t->getID() + ".transliterate(ReplaceableString, start, limit):("+start+","+limit+"):";
        doTest(message, rs, Data[i+2]); 
    }
    delete t;
}

void TransliteratorAPITest::TestSimpleKeyboardTransliterator(){
    logln("simple call to transliterate");
    UErrorCode status=U_ZERO_ERROR;
    UParseError parseError;
    Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
    if(t == 0) {
        UnicodeString context;

        if (parseError.preContext[0]) {
            context += (UnicodeString)" at " + parseError.preContext;
        }
        if (parseError.postContext[0]) {
            context += (UnicodeString)" | " + parseError.postContext;
        }
        errln((UnicodeString)"FAIL: can't create Any-Hex, " +
              (UnicodeString)u_errorName(status) + context);
        return;
    }
    UTransPosition index={19,20,20,20};
    UnicodeString rs= "Transliterate this-''";
    UnicodeString insertion="abc";
    UnicodeString expected=UnicodeString("Transliterate this-'\\u0061\\u0062\\u0063'", "");
    t->transliterate(rs, index, insertion, status);
    if(U_FAILURE(status))
        errln("FAIL: " + t->getID()+ ".translitere(Replaceable, int[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status));
    t->finishTransliteration(rs, index);
    UnicodeString message="transliterate";
    doTest(message, rs, expected);

    logln("try calling transliterate with invalid index values");
    UTransPosition index1[]={
        //START, LIMIT, CURSOR
        {10, 10, 12, 10},   //invalid since CURSOR>LIMIT valid:-START <= CURSOR <= LIMIT
        {17, 16, 17, 17},   //invalid since START>LIMIT valid:-0<=START<=LIMIT
        {-1, 16, 14, 16},   //invalid since START<0
        {3,  50, 2,  50}    //invalid since LIMIT>text.length()
    };
    for(uint32_t i=0; i<sizeof(index1)/sizeof(index1[0]); i++){
        status=U_ZERO_ERROR;
        t->transliterate(rs, index1[i], insertion, status);
        if(status == U_ILLEGAL_ARGUMENT_ERROR)
            logln("OK: invalid index values handled correctly");
        else
            errln("FAIL: invalid index values didn't throw U_ILLEGAL_ARGUMENT_ERROR throw" + (UnicodeString)u_errorName(status));
    }

    delete t;
}
void TransliteratorAPITest::TestKeyboardTransliterator1(){
    UnicodeString Data[]={
        //insertion, buffer
        "a",   UnicodeString("\\u0061", "")                                           ,
        "bbb", UnicodeString("\\u0061\\u0062\\u0062\\u0062", "")                      ,
        "ca",  UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061", "")        ,
        " ",   UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020", "") ,
        "",    UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020", "")   ,

        "a",   UnicodeString("\\u0061", "")                                           ,
        "b",   UnicodeString("\\u0061\\u0062", "")                                    ,
        "z",   UnicodeString("\\u0061\\u0062\\u007A", "")                             ,
        "",    UnicodeString("\\u0061\\u0062\\u007A", "")                              

    };
    UParseError parseError;
    UErrorCode status = U_ZERO_ERROR;
    Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
    if(U_FAILURE(status)) {
      errln("Error creating transliterator %s", u_errorName(status));
      delete t;
      return;
    }
    //keyboardAux(t, Data);
    UTransPosition index={0, 0, 0, 0};
    UnicodeString s;
    uint32_t i;
    logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");
    for (i=0; i<10; i=i+2) {
       UnicodeString log;
       if (Data[i+0] != "") {
           log = s + " + " + Data[i+0] + " -> ";
           t->transliterate(s, index, Data[i+0], status);
           if(U_FAILURE(status)){
               errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status));
           continue;
           }
       }else {
           log = s + " => ";
           t->finishTransliteration(s, index);
       }
       // Show the start index '{' and the cursor '|'
       displayOutput(s, Data[i+1], log, index);
           
    }
    
    s="";
    status=U_ZERO_ERROR;
    index.contextStart = index.contextLimit = index.start = index.limit = 0;
    logln("Testing transliterate(Replaceable, int32_t, UChar, UErrorCode)");
    for(i=10; i<sizeof(Data)/sizeof(Data[0]); i=i+2){
        UnicodeString log;
         if (Data[i+0] != "") {
           log = s + " + " + Data[i+0] + " -> ";
           UChar c=Data[i+0].charAt(0);
           t->transliterate(s, index, c, status);
           if(U_FAILURE(status))
               errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UChar, UErrorCode)-->" + (UnicodeString)u_errorName(status));
               continue;
         }else {
           log = s + " => ";
           t->finishTransliteration(s, index);
         }
        // Show the start index '{' and the cursor '|'
        displayOutput(s, Data[i+1], log, index); 
    }

    delete t;
}

void TransliteratorAPITest::TestKeyboardTransliterator2(){
    UnicodeString Data[]={
        //insertion, buffer, index[START], index[LIMIT], index[CURSOR]
        //data for Any-Hex
        "abc",    UnicodeString("Initial String: add-\\u0061\\u0062\\u0063-", ""),                     "19", "20", "20",
        "a",      UnicodeString("In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""),        "2",  "3",  "2" ,
        "b",      UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0",  "0",  "0" ,
        "",       UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0",  "0",  "0" ,
        //data for Latin-Devanagiri
        CharsToUnicodeString("a\\u0304"),     CharsToUnicodeString("Hindi -\\u0906-"),                            "6", "7", "6",
        CharsToUnicodeString("ma\\u0304"),    CharsToUnicodeString("Hindi -\\u0906\\u092E\\u093E-"),              "7", "8", "7",
        CharsToUnicodeString("ra\\u0304"),    CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2",
        CharsToUnicodeString(""),       CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2"
        //data for contracted-Expanded
     //   CharsToUnicodeString("\\u00C1"), CharsToUnicodeString("Ad\\u0041\\u0301d here:"),             "1",  "2",  "1" ,
     //   CharsToUnicodeString("\\u00C0"), CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
     //   "",     CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
    };
    Transliterator *t;
    UnicodeString rs;
    UnicodeString dataStr;
    logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");       
    UErrorCode status = U_ZERO_ERROR;
    UParseError parseError;
    rs="Initial String: add--";
    t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
    if(t == 0)
        errln("FAIL : construction");
    else {
        keyboardAux(t, Data, rs, 0, 20);
        delete t;
    }

    rs="Hindi --";
    t=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
    if(t == 0)
        errln("FAIL : construction");
    else
        keyboardAux(t, Data, rs, 20, 40);


  //  rs="Add here:";
 //   t=Transliterator::createInstance("Contracted-Expanded");
 //   keyboardAux(t, Data, rs, 35, 55);


    delete t;
}

void TransliteratorAPITest::TestKeyboardTransliterator3(){
    UnicodeString s="This is the main string";
    UnicodeString Data[] = {
        "0", "0", "0",  "This is the main string",
        "1", "3", "2",  UnicodeString("Th\\u0069s is the main string", ""),
        "20", "21", "20",  UnicodeString("Th\\u0069s is the mai\\u006E string", "")
    };

    UErrorCode status=U_ZERO_ERROR;
    UParseError parseError;
    UTransPosition index={0, 0, 0, 0};
    logln("Testing transliterate(Replaceable, int32_t, UErrorCode)");
    Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
    if(U_FAILURE(status)) {
      errln("Error creating transliterator %s", u_errorName(status));
      delete t;
      return;
    }
    if(t == 0)
        errln("FAIL : construction");
    for(uint32_t i=0; i<sizeof(Data)/sizeof(Data[0]); i=i+4){
        UnicodeString log;
        index.contextStart=getInt(Data[i+0]);
        index.contextLimit=index.limit=getInt(Data[i+1]);
        index.start=getInt(Data[i+2]);
        t->transliterate(s, index, status);
        if(U_FAILURE(status)){
           errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UErrorCode)-->" + (UnicodeString)u_errorName(status));
           continue;
        }
        t->finishTransliteration(s, index);
        log = s + " => ";
        // Show the start index '{' and the cursor '|'
        displayOutput(s, Data[i+3], log, index); 
    }

    delete t;
}
void TransliteratorAPITest::TestNullTransliterator(){
    UnicodeString s("Transliterate using null transliterator");
    NullTransliterator *nullTrans=new NullTransliterator();
    int32_t transLimit;
    int32_t start=0;
    int32_t limit=s.length();
    UnicodeString replaceable=s;
    transLimit=nullTrans->transliterate(replaceable, start, limit);
    if(transLimit != limit){
        errln("ERROR: NullTransliterator->transliterate() failed");
    }
    doTest((UnicodeString)"nulTrans->transliterate", replaceable, s);
    replaceable.remove();
    replaceable.append(s);
    UTransPosition index;
    index.contextStart =start;
    index.contextLimit = limit;
    index.start = 0;
    index.limit = limit;
    nullTrans->handleTransliterate(replaceable, index, TRUE);
    if(index.start != limit){
        errln("ERROR: NullTransliterator->handleTransliterate() failed");
    }
    doTest((UnicodeString)"NullTransliterator->handleTransliterate", replaceable, s);
    callEverything(nullTrans, __LINE__);
    delete nullTrans;

    
}
void TransliteratorAPITest::TestRegisterUnregister(){
   
   UErrorCode status=U_ZERO_ERROR;
   UParseError parseError;
    /* Make sure it doesn't exist */
   if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, parseError, status) != NULL) {
      errln("FAIL: TestA-TestB already registered\n");
      return;
   }
   /* Check inverse too 
   if (Transliterator::createInstance("TestA-TestB",
                                      (UTransDirection)UTRANS_REVERSE) != NULL) {
      errln("FAIL: TestA-TestB inverse already registered\n");
      return;
   }
   */
   status =U_ZERO_ERROR;

   /* Create it */
   Transliterator *t = new RuleBasedTransliterator("TestA-TestB",
                                                   "a<>b",
                                                   status);
   /* Register it */
   Transliterator::registerInstance(t);

   /* Now check again -- should exist now*/
   Transliterator *s = Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, parseError, status);
   if (s == NULL) {
      errln("FAIL: TestA-TestB not registered\n");
      return;
   }
   callEverything(s, __LINE__);
   callEverything(t, __LINE__);
   delete s;
   
   /* Check inverse too
   s = Transliterator::createInstance("TestA-TestB",
                                      (UTransDirection)UTRANS_REVERSE);
   if (s == NULL) {
      errln("FAIL: TestA-TestB inverse not registered\n");
      return;
   }
   delete s;
   */
   
   /*unregister the instance*/
   Transliterator::unregister("TestA-TestB");
   /* now Make sure it doesn't exist */
   if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, parseError, status) != NULL) {
      errln("FAIL: TestA-TestB isn't unregistered\n");
      return;
   }

}


int gTestFilter1ClassID = 0;
int gTestFilter2ClassID = 0;
int gTestFilter3ClassID = 0;

/**
 * Used by TestFiltering().
 */
class TestFilter1 : public UnicodeFilter {
    UClassID getDynamicClassID()const { return &gTestFilter1ClassID; }
    virtual UnicodeFunctor* clone() const {
        return new TestFilter1(*this);
    }
    virtual UBool contains(UChar32 c) const {
       if(c==0x63 || c==0x61 || c==0x43 || c==0x41)
          return FALSE;
       else
          return TRUE;
    }
    // Stubs
    virtual UnicodeString& toPattern(UnicodeString& result,
                                     UBool /*escapeUnprintable*/) const {
        return result;
    }
    virtual UBool matchesIndexValue(uint8_t /*v*/) const {
        return FALSE;
    }
    virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
};
class TestFilter2 : public UnicodeFilter {
    UClassID getDynamicClassID()const { return &gTestFilter2ClassID; }
    virtual UnicodeFunctor* clone() const {
        return new TestFilter2(*this);
    }
    virtual UBool contains(UChar32 c) const {
        if(c==0x65 || c==0x6c)
           return FALSE;
        else
           return TRUE;
    }
    // Stubs
    virtual UnicodeString& toPattern(UnicodeString& result,
                                     UBool /*escapeUnprintable*/) const {
        return result;
    }
    virtual UBool matchesIndexValue(uint8_t /*v*/) const {
        return FALSE;
    }
    virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
};
class TestFilter3 : public UnicodeFilter {
    UClassID getDynamicClassID()const { return &gTestFilter3ClassID; }
    virtual UnicodeFunctor* clone() const {
        return new TestFilter3(*this);
    }
    virtual UBool contains(UChar32 c) const {
        if(c==0x6f || c==0x77)
           return FALSE;
        else
           return TRUE;
    }
    // Stubs
    virtual UnicodeString& toPattern(UnicodeString& result,
                                     UBool /*escapeUnprintable*/) const {
        return result;
    }
    virtual UBool matchesIndexValue(uint8_t /*v*/) const {
        return FALSE;
    }
    virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
};


void TransliteratorAPITest::TestGetAdoptFilter(){
    UErrorCode status = U_ZERO_ERROR;
    UParseError parseError;
    Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
    if(U_FAILURE(status)) {
      errln("Error creating transliterator %s", u_errorName(status));
      delete t;
      return;
    }
    if(t == 0)
        errln("FAIL : construction");
    const UnicodeFilter *u=t->getFilter();
    if(u != NULL){
      errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering");
    }
          
    UnicodeString got, temp, message;
    UnicodeString data="ABCabcbbCBa";
    temp = data;
    t->transliterate(temp);
    t->adoptFilter(new TestFilter1);

    got = data;
    t->transliterate(got);
    UnicodeString exp=UnicodeString("A\\u0042Ca\\u0062c\\u0062\\u0062C\\u0042a", "");
    message="transliteration after adoptFilter(a,A,c,C) ";
    doTest(message, got, exp);
         
    logln("Testing round trip");
    t->adoptFilter((UnicodeFilter*)u);
    if(t->getFilter() == NULL)
       logln("OK: adoptFilter and getFilter round trip worked");
    else
       errln("FAIL: adoptFilter or getFilter round trip failed");  

    got = data;
    t->transliterate(got);
    exp=UnicodeString("\\u0041\\u0042\\u0043\\u0061\\u0062\\u0063\\u0062\\u0062\\u0043\\u0042\\u0061", "");
    message="transliteration after adopting null filter";
    doTest(message, got, exp);
    message="adoptFilter round trip"; 
    doTest("adoptFilter round trip", got, temp);

    t->adoptFilter(new TestFilter2);
    callEverything(t, __LINE__);
    data="heelloe";
    exp=UnicodeString("\\u0068eell\\u006Fe", "");
    got = data;
    t->transliterate(got);
    message="transliteration using (e,l) filter";
    doTest("transliteration using (e,l) filter", got, exp);

    data="are well";
    exp=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", "");
    got = data;
    t->transliterate(got);
    doTest(message, got, exp);

    t->adoptFilter(new TestFilter3);
    data="ho, wow!";
    exp=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", "");
    got = data;
    t->transliterate(got);
    message="transliteration using (o,w) filter";
    doTest("transliteration using (o,w) filter", got, exp);

    data="owl";
    exp=UnicodeString("ow\\u006C", "");
    got = data;
    t->transliterate(got);
    doTest("transliteration using (o,w) filter", got, exp);

    delete t;

}



void TransliteratorAPITest::keyboardAux(Transliterator *t, UnicodeString DATA[], UnicodeString& s, int32_t begin, int32_t end) {
    UTransPosition index={0, 0, 0, 0};
    UErrorCode status=U_ZERO_ERROR;
    for (int32_t i=begin; i<end; i=i+5) {
        UnicodeString log;
        if (DATA[i+0] != "") {
             log = s + " + " + DATA[i] + " -> ";
             index.contextStart=getInt(DATA[i+2]);
             index.contextLimit=index.limit=getInt(DATA[i+3]);
             index.start=getInt(DATA[i+4]);
             t->transliterate(s, index, DATA[i+0], status);
             if(U_FAILURE(status)){
                 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status));
             continue;
             }
           log = s + " => ";
           t->finishTransliteration(s, index);
        }
         // Show the start index '{' and the cursor '|'
      displayOutput(s, DATA[i+1], log, index);
        
    }
}

void TransliteratorAPITest::displayOutput(const UnicodeString& got, const UnicodeString& expected, UnicodeString& log, UTransPosition& index){
 // Show the start index '{' and the cursor '|'
    UnicodeString a, b, c, d, e;
    got.extractBetween(0, index.contextStart, a);
    got.extractBetween(index.contextStart, index.start, b);
    got.extractBetween(index.start, index.limit, c);
    got.extractBetween(index.limit, index.contextLimit, d);
    got.extractBetween(index.contextLimit, got.length(), e);
    log.append(a).
        append((UChar)0x7b/*{*/).
        append(b).
        append((UChar)0x7c/*|*/).
        append(c).
        append((UChar)0x7c).
        append(d).
        append((UChar)0x7d/*}*/).
        append(e);
    if (got == expected) 
        logln("OK:" + prettify(log));
    else 
        errln("FAIL: " + prettify(log)  + ", expected " + prettify(expected));
}


/*Internal Functions used*/
void TransliteratorAPITest::doTest(const UnicodeString& message, const UnicodeString& result, const UnicodeString& expected){
    if (prettify(result) == prettify(expected)) 
        logln((UnicodeString)"Ok: " + prettify(message) + " passed \"" + prettify(expected) + "\"");
    else 
        errln((UnicodeString)"FAIL:" + message + " failed  Got-->" + prettify(result)+ ", Expected--> " + prettify(expected) );
}


//
//  callEverything    call all of the const (non-destructive) methods on a
//                    transliterator, just to verify that they don't fail in some
//                    destructive way.
//
#define CEASSERT(a) {if (!(a)) { \
errln("FAIL at line %d from line %d: %s", __LINE__, line, #a);  return; }}

void TransliteratorAPITest::callEverything(const Transliterator *tr, int line) {
    Transliterator *clonedTR = tr->clone();
    CEASSERT(clonedTR != NULL);

    int32_t  maxcl = tr->getMaximumContextLength();
    CEASSERT(clonedTR->getMaximumContextLength() == maxcl);

    UnicodeString id;
    UnicodeString clonedId;
    id = tr->getID();
    clonedId = clonedTR->getID();
    CEASSERT(id == clonedId);

    const UnicodeFilter *filter = tr->getFilter();
    const UnicodeFilter *clonedFilter = clonedTR->getFilter();
    if (filter == NULL || clonedFilter == NULL) {
        // If one filter is NULL they better both be NULL.
        CEASSERT(filter == clonedFilter);
    } else {
        CEASSERT(filter != clonedFilter);
    }

    UnicodeString rules;
    UnicodeString clonedRules;
    rules = tr->toRules(rules, FALSE);
    clonedRules = clonedTR->toRules(clonedRules, FALSE);
    CEASSERT(rules == clonedRules);

    UnicodeSet sourceSet;
    UnicodeSet clonedSourceSet;
    tr->getSourceSet(sourceSet);
    clonedTR->getSourceSet(clonedSourceSet);
    CEASSERT(clonedSourceSet == sourceSet);

    UnicodeSet targetSet;
    UnicodeSet clonedTargetSet;
    tr->getTargetSet(targetSet);
    clonedTR->getTargetSet(clonedTargetSet);
    CEASSERT(targetSet == clonedTargetSet);

    UClassID classID = tr->getDynamicClassID();
    CEASSERT(classID == clonedTR->getDynamicClassID());
    CEASSERT(classID != 0);

    delete clonedTR;
}




#endif /* #if !UCONFIG_NO_TRANSLITERATION */
