//##header J2SE15
//#if defined(FOUNDATION10) || defined(J2SE13)
//#else
/*
*******************************************************************************
*   Copyright (C) 2007, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*/

package com.ibm.icu.dev.test.bidi;

import com.ibm.icu.text.Bidi;
import java.text.AttributedString;
import java.awt.font.TextAttribute;
import java.text.AttributedCharacterIterator;
import java.awt.font.NumericShaper;

/**
 * Regression test for java.text.Bidi compatibility
 *
 * @author Matitiahu Allouche
 */

public class TestCompatibility extends BidiTest {

    void compareBidi(Bidi bidi, java.text.Bidi jbidi)
    {
        byte paraLevel = bidi.getParaLevel();
        if (bidi.baseIsLeftToRight() != jbidi.baseIsLeftToRight()) {
            errln("Discrepancy in baseIsLeftToRight for case " +
                  "(level=" + paraLevel + "): " +
                  u16ToPseudo(bidi.getTextAsString()) +
                  "\n    bidi: " + bidi.baseIsLeftToRight() +
                  "\n   jbidi: " + jbidi.baseIsLeftToRight());
        }
        if (bidi.getBaseLevel() != jbidi.getBaseLevel()) {
            errln("Discrepancy in getBaseLevel for case " +
                  "(level=" + paraLevel + "): " +
                  u16ToPseudo(bidi.getTextAsString()) +
                  "\n    bidi: " + bidi.getBaseLevel() +
                  "\n   jbidi: " + jbidi.getBaseLevel());
        }
        if (bidi.getLength() != jbidi.getLength()) {
            errln("Discrepancy in getLength for case " +
                  "(level=" + paraLevel + "): " +
                  u16ToPseudo(bidi.getTextAsString()) +
                  "\n    bidi: " + bidi.getLength() +
                  "\n   jbidi: " + jbidi.getLength());
        }
        int len = bidi.getLength();
        for (int i = 0; i < len; i++) {
            if (bidi.getLevelAt(i) != jbidi.getLevelAt(i)) {
                errln("Discrepancy in getLevelAt for offset " + i +
                      " of case " +
                      "(level=" + paraLevel + "): " +
                      u16ToPseudo(bidi.getTextAsString()) +
                      "\n    bidi: " + bidi.getLevelAt(i) +
                      "\n   jbidi: " + jbidi.getLevelAt(i));
            }
        }
        if (bidi.getRunCount() != jbidi.getRunCount()) {
            if (!(len == 0 && jbidi.getRunCount() == 1)) {
                errln("Discrepancy in getRunCount for case " +
                      "(level=" + paraLevel + "): " +
                      u16ToPseudo(bidi.getTextAsString()) +
                      "\n    bidi: " + bidi.getRunCount() +
                      "\n   jbidi: " + jbidi.getRunCount());
            }
        }
        int runCount = bidi.getRunCount();
        for (int i = 0; i < runCount; i++) {
            if (bidi.getRunLevel(i) != jbidi.getRunLevel(i)) {
                errln("Discrepancy in getRunLevel for run " + i +
                      " of case " +
                      "(level=" + paraLevel + "): " +
                      u16ToPseudo(bidi.getTextAsString()) +
                      "\n    bidi: " + bidi.getRunLevel(i) +
                      "\n   jbidi: " + jbidi.getRunLevel(i));
            }
            if (bidi.getRunLimit(i) != jbidi.getRunLimit(i)) {
                errln("Discrepancy in getRunLimit for run " + i +
                      " of case " +
                      "(level=" + paraLevel + "): " +
                      u16ToPseudo(bidi.getTextAsString()) +
                      "\n    bidi: " + bidi.getRunLimit(i) +
                      "\n   jbidi: " + jbidi.getRunLimit(i));
            }
            if (bidi.getRunStart(i) != jbidi.getRunStart(i)) {
                errln("Discrepancy in getRunStart for run " + i +
                      " of case " +
                      "(level=" + paraLevel + "): " +
                      u16ToPseudo(bidi.getTextAsString()) +
                      "\n    bidi: " + bidi.getRunStart(i) +
                      "\n   jbidi: " + jbidi.getRunStart(i));
            }
        }
        if (bidi.isLeftToRight() != jbidi.isLeftToRight()) {
            errln("Discrepancy in isLeftToRight for case " +
                  "(level=" + paraLevel + "): " +
                  u16ToPseudo(bidi.getTextAsString()) +
                  "\n    bidi: " + bidi.isLeftToRight() +
                  "\n   jbidi: " + jbidi.isLeftToRight());
        }
        if (bidi.isMixed() != jbidi.isMixed()) {
            errln("Discrepancy in isMixed for case " +
                  "(level=" + paraLevel + "): " +
                  u16ToPseudo(bidi.getTextAsString()) +
                  "\n    bidi: " + bidi.isMixed() +
                  "\n   jbidi: " + jbidi.isMixed());
        }
        if (bidi.isRightToLeft() != jbidi.isRightToLeft()) {
            errln("Discrepancy in isRightToLeft for case " +
                  "(level=" + paraLevel + "): " +
                  u16ToPseudo(bidi.getTextAsString()) +
                  "\n    bidi: " + bidi.isRightToLeft() +
                  "\n   jbidi: " + jbidi.isRightToLeft());
        }
        char[] text = bidi.getText();
        if (Bidi.requiresBidi(text, 0, text.length) !=
            java.text.Bidi.requiresBidi(text, 0, text.length)) {
            errln("Discrepancy in requiresBidi for case " +
                  u16ToPseudo(bidi.getTextAsString()) +
                  "\n    bidi: " + Bidi.requiresBidi(text, 0, text.length) +
                  "\n   jbidi: " + java.text.Bidi.requiresBidi(text, 0, text.length));
        }
        /* skip the next test, since the toString implementation are
         * not compatible
        if (!bidi.toString().equals(jbidi.toString())) {
            errln("Discrepancy in toString for case " +
                  "(level=" + paraLevel + "): " +
                  u16ToPseudo(bidi.getTextAsString() +
                  "\n    bidi: " + bidi.toString() +
                  "\n   jbidi: " + jbidi.toString()));
        }
         */
    }

    public void testCompatibility()
    {
        // This test case does not work well on Java 1.4/1.4.1 environment,
        // because of insufficient Bidi implementation in these versions.
        String javaVersion = System.getProperty("java.version");
        if (javaVersion.startsWith("1.4.0") || javaVersion.startsWith("1.4.1")) {
            logln("\nSkipping TestCompatibility.  The test case is known to fail on Java "
                    + javaVersion + "\n");
            return;
        }
        logln("\nEntering TestCompatibility\n");
        /* check constant field values */
        int val;
        val = Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
        val = Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
        val = Bidi.DIRECTION_LEFT_TO_RIGHT;
        val = Bidi.DIRECTION_RIGHT_TO_LEFT;
        logln("last val = " + val);

        String[] data = {"",
                         /* the following 2 cases are skipped, because
                          * java.text.Bidi has bugs which cause discrepancies
                         "abc",
                         "ABC",
                          */
                         "abc def",
                         "ABC DEF",
                         "abc 123 def",
                         "ABC 123 DEF",
                         "abc DEF ghi",
                         "abc DEF 123 xyz",
                         "abc GHIJ 12345 def KLM"
                        };
        int dataCnt = data.length;
        Bidi bidi;
        java.text.Bidi jbidi;
        for (int i = 0; i < dataCnt; i++) {
            String src = pseudoToU16(data[i]);
            bidi = new Bidi(src, Bidi.DIRECTION_LEFT_TO_RIGHT);
            jbidi = new java.text.Bidi(src, java.text.Bidi.DIRECTION_LEFT_TO_RIGHT);
            compareBidi(bidi, jbidi);
            bidi = new Bidi(src, Bidi.DIRECTION_RIGHT_TO_LEFT);
            jbidi = new java.text.Bidi(src, java.text.Bidi.DIRECTION_RIGHT_TO_LEFT);
            compareBidi(bidi, jbidi);
            char[] chars = src.toCharArray();
            bidi = new Bidi(chars, 0, null, 0, chars.length, Bidi.DIRECTION_LEFT_TO_RIGHT);
            jbidi = new java.text.Bidi(chars, 0, null, 0, chars.length, java.text.Bidi.DIRECTION_LEFT_TO_RIGHT);
            compareBidi(bidi, jbidi);
        }
        /* check bogus flags */
        bidi = new Bidi("abc", 999);
        assertEquals("\nDirection should be LTR", Bidi.LTR, bidi.getDirection());
        /* check constructor with overriding embeddings */
        bidi = new Bidi(new char[] { 's', 's', 's' }, 0,
                        new byte[] {(byte) -7, (byte) -2, (byte) -3 },
                        0, 3, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
        jbidi = new java.text.Bidi(new char[] { 's', 's', 's' }, 0,
                        new byte[] {(byte) -7, (byte) -2, (byte) -3 },
                        0, 3, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);

        AttributedString as = new AttributedString("HEBREW 123 english MOREHEB");
        as.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);
        as.addAttribute(TextAttribute.NUMERIC_SHAPING, NumericShaper.getShaper(NumericShaper.ARABIC));
        as.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(1), 0, 26);
        as.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-1), 0, 6);
        as.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-1), 19, 26);
        AttributedCharacterIterator aci = as.getIterator();
        bidi = new Bidi(aci);
        jbidi = new java.text.Bidi(aci);
        compareBidi(bidi, jbidi);
        String out = bidi.writeReordered(0);
        logln("Output #1 of Bidi(AttributedCharacterIterator): " + out);

        as = new AttributedString("HEBREW 123 english MOREHEB");
        as.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);
        as.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(0), 0, 26);
        aci = as.getIterator();
        bidi = new Bidi(aci);
        jbidi = new java.text.Bidi(aci);
        compareBidi(bidi, jbidi);
        out = bidi.writeReordered(0);
        logln("Output #2 of Bidi(AttributedCharacterIterator): " + out);

        as = new AttributedString("HEBREW 123 english MOREHEB");
        aci = as.getIterator();
        bidi = new Bidi(aci);
        jbidi = new java.text.Bidi(aci);
        compareBidi(bidi, jbidi);
        out = bidi.writeReordered(0);
        logln("Output #3 of Bidi(AttributedCharacterIterator): " + out);

        char[] text = "abc==(123)==>def".toCharArray();
        bidi = new Bidi(text, 3, null, 0, 10, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
        jbidi = new java.text.Bidi(text, 3, null, 0, 10, java.text.Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
        compareBidi(bidi, jbidi);
        out = bidi.writeReordered(0);
        logln("Output of Bidi(abc==(123)==>def,3,null,0,10, DEFAULT_LTR): " + out);
        bidi = new Bidi(text, 3, null, 0, 10, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
        jbidi = new java.text.Bidi(text, 3, null, 0, 10, java.text.Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
        compareBidi(bidi, jbidi);
        out = bidi.writeReordered(0);
        logln("Output of Bidi(abc==(123)==>def,3,null,0,10, DEFAULT_RTL): " + out);
        byte[] levels = new byte[] {0,0,0,-1,-1,-1,0,0,0,0};
        bidi = new Bidi(text, 3, levels, 0, 10, Bidi.DIRECTION_LEFT_TO_RIGHT);
        jbidi = new java.text.Bidi(text, 3, levels, 0, 10, java.text.Bidi.DIRECTION_LEFT_TO_RIGHT);
        compareBidi(bidi, jbidi);
        out = bidi.writeReordered(0);
        logln("Output of Bidi(abc==(123)==>def,3,levels,0,10, LTR): " + out);
        bidi = new Bidi(text, 3, levels, 0, 10, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
        jbidi = new java.text.Bidi(text, 3, levels, 0, 10, java.text.Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
        compareBidi(bidi, jbidi);
        out = bidi.writeReordered(0);
        logln("Output of Bidi(abc==(123)==>def,3,levels,0,10, DEFAULT_RTL): " + out);

        /* test reorderVisually */
        byte[] myLevels = new byte[] {1,2,0,1,2,1,2,0,1,2};
        Character[] objects = new Character[10];
        levels = new byte[objects.length];
        for (int i = 0; i < objects.length; i++) {
            objects[i] = new Character((char)('a'+i));
            levels[i] = myLevels[i];
        }
        Bidi.reorderVisually(levels, 3, objects, 3, 7);
        String strbidi = "";
        for (int i = 0; i < objects.length; i++) {
            strbidi += objects[i].toString();
        }
        for (int i = 0; i < objects.length; i++) {
            objects[i] = new Character((char)('a'+i));
            levels[i] = myLevels[i];
        }
        java.text.Bidi.reorderVisually(levels, 3, objects, 3, 7);
        String strjbidi = "";
        for (int i = 0; i < objects.length; i++) {
            strjbidi += objects[i].toString();
        }
        if (!strjbidi.equals(strbidi)) {
            errln("Discrepancy in reorderVisually " +
                  "\n      bidi: " + strbidi +
                  "\n     jbidi: " + strjbidi);
        } else {
            logln("Correct match in reorderVisually " +
                  "\n      bidi: " + strbidi +
                  "\n     jbidi: " + strjbidi);
        }

        logln("\nExiting TestCompatibility\n");
    }

    public static void main(String[] args) {
        try {
            new TestCompatibility().run(args);
        }
        catch (Exception e) {
            System.out.println(e);
        }
    }
}
//#endif
