/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 2001, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/
/************************************************************************
*   This test program is intended for testing Replaceable class.
*
*   Date        Name        Description
*   11/28/2001  hshih       Ported back from Java.
* 
************************************************************************/

#include "unicode/utypes.h"

#if !UCONFIG_NO_TRANSLITERATION

#include "ittrans.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "unicode/rep.h"
#include "reptest.h"

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

    /**
     * This is a test class that simulates styled text.
     * It associates a style number (0..65535) with each character,
     * and maintains that style in the normal fashion:
     * When setting text from raw string or characters,<br>
     * Set the styles to the style of the first character replaced.<br>
     * If no characters are replaced, use the style of the previous character.<br>
     * If at start, use the following character<br>
     * Otherwise use NO_STYLE.
     */
class TestReplaceable : public Replaceable {
    UnicodeString chars;
    UnicodeString styles;
    
    static const UChar NO_STYLE;

    static const UChar NO_STYLE_MARK;

    /**
     * The address of this static class variable serves as this class's ID
     * for ICU "poor man's RTTI".
     */
    static const char fgClassID;

public:    
    TestReplaceable (const UnicodeString& text, 
                     const UnicodeString& newStyles) {
        chars = text;
        UnicodeString s;
        for (int i = 0; i < text.length(); ++i) {
            if (i < newStyles.length()) {
                s.append(newStyles.charAt(i));
            } else {
		if (text.charAt(i) == NO_STYLE_MARK) {
		    s.append(NO_STYLE);
		} else {
		    s.append((UChar)(i + 0x0031));
		}
            }
        }
        this->styles = s;
    }
    
    ~TestReplaceable(void) {}

    UnicodeString getStyles() {
        return styles;
    }
    
    UnicodeString toString() {
        UnicodeString s = chars;
        s.append("{");
        s.append(styles);
        s.append("}");
        return s;
    }

    void extractBetween(int32_t start, int32_t limit, UnicodeString& result) const {
        chars.extractBetween(start, limit, result);
    }

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

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @draft ICU 2.2
     */
    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }

protected:
    virtual int32_t getLength() const {
        return chars.length();
    }

    virtual UChar getCharAt(int32_t offset) const{
        return chars.charAt(offset);
    }

    virtual UChar32 getChar32At(int32_t offset) const{
        return chars.char32At(offset);
    }

    virtual void handleReplaceBetween(int32_t start, int32_t limit, const UnicodeString& text) {
        UnicodeString s;
        this->extractBetween(start, limit, s);
        if (s == text) return; // NO ACTION!
        this->chars.replaceBetween(start, limit, text);
        fixStyles(start, limit, text.length());
    }
    

    void fixStyles(int32_t start, int32_t limit, int32_t newLen) {
        UChar newStyle = NO_STYLE;
        if (start != limit && styles.charAt(start) != NO_STYLE) {
            newStyle = styles.charAt(start);
        } else if (start > 0 && getCharAt(start-1) != NO_STYLE_MARK) {
            newStyle = styles.charAt(start-1);
        } else if (limit < styles.length()) {
            newStyle = styles.charAt(limit);
        }
        // dumb implementation for now.
        UnicodeString s;
        for (int i = 0; i < newLen; ++i) {
	    // this doesn't really handle an embedded NO_STYLE_MARK
	    // in the middle of a long run of characters right -- but
	    // that case shouldn't happen anyway
	    if (getCharAt(start+i) == NO_STYLE_MARK) {
		s.append(NO_STYLE);
	    } else {
		s.append(newStyle);
	    }
        }
        styles.replaceBetween(start, limit, s);
    }

    virtual void copy(int32_t start, int32_t limit, int32_t dest) {
        chars.copy(start, limit, dest);
        styles.copy(start, limit, dest);
    }
};

const char TestReplaceable::fgClassID=0;

const UChar TestReplaceable::NO_STYLE  = 0x005F;

const UChar TestReplaceable::NO_STYLE_MARK = 0xFFFF;

void
ReplaceableTest::runIndexedTest(int32_t index, UBool exec,
                                      const char* &name, char* /*par*/) {
    switch (index) {
        TESTCASE(0,TestReplaceableClass);
        default: name = ""; break;
    }
}


void ReplaceableTest::TestReplaceableClass(void) {
    UChar rawTestArray[][6] = {
        {0x0041, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // ABCD
        {0x0061, 0x0062, 0x0063, 0x0064, 0x00DF, 0x0000}, // abcd\u00DF
        {0x0061, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // aBCD
        {0x0041, 0x0300, 0x0045, 0x0300, 0x0000, 0x0000}, // A\u0300E\u0300
        {0x00C0, 0x00C8, 0x0000, 0x0000, 0x0000, 0x0000}, // \u00C0\u00C8
        {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
        {0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000}, /* "wxyz" */
        {0x0077, 0x0078, 0x0079, 0x007A, 0x0075, 0x0000}, /* "wxyzu" */
	{0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000}, /* "xyz" */
	{0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
	{0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
	{0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
    };
    check("Lower", rawTestArray[0], "1234");
    check("Upper", rawTestArray[1], "123455"); // must map 00DF to SS
    check("Title", rawTestArray[2], "1234");
    check("NFC",   rawTestArray[3], "13");
    check("NFD",   rawTestArray[4], "1122");
    check("*(x) > A $1 B", rawTestArray[5], "11223");
    check("*(x)(y) > A $2 B $1 C $2 D", rawTestArray[6], "113322334");
    check("*(x)(y)(z) > A $3 B $2 C $1 D", rawTestArray[7], "114433225");
    // Disabled for 2.4.  TODO Revisit in 2.6 or later.
    //check("*x > a", rawTestArray[8], "223"); // expect "123"?
    //check("*x > a", rawTestArray[9], "113"); // expect "123"?
    //check("*x > a", rawTestArray[10], "_33"); // expect "_23"?
    //check("*(x) > A $1 B", rawTestArray[11], "__223");
}

void ReplaceableTest::check(const UnicodeString& transliteratorName, 
                            const UnicodeString& test, 
                            const UnicodeString& shouldProduceStyles) 
{
    UErrorCode status = U_ZERO_ERROR;
    TestReplaceable *tr = new TestReplaceable(test, "");
    UnicodeString expectedStyles = shouldProduceStyles;
    UnicodeString original = tr->toString();

    Transliterator* t;
    if (transliteratorName.charAt(0) == 0x2A /*'*'*/) {
        UnicodeString rules(transliteratorName);
        rules.remove(0,1);
        UParseError pe;
        t = Transliterator::createFromRules("test", rules, UTRANS_FORWARD,
                                            pe, status);
    } else {
        t = Transliterator::createInstance(transliteratorName, UTRANS_FORWARD, status);
    }
    if (U_FAILURE(status)) {
        log("FAIL: failed to create the ");
        log(transliteratorName);
        errln(" transliterator.");
        delete tr;
        return;
    }
    t->transliterate(*tr);
    UnicodeString newStyles = tr->getStyles();
    if (newStyles != expectedStyles) {
        errln("FAIL Styles: " + transliteratorName + "{" + original + "} => "
            + tr->toString() + "; should be {" + expectedStyles + "}!");
    } else {
        log("OK: ");
        log(transliteratorName);
        log("(");
        log(original);
        log(") => ");
        logln(tr->toString());
    }
    delete tr;
    delete t;
}

#endif /* #if !UCONFIG_NO_TRANSLITERATION */
