/*
 *******************************************************************************
 * Copyright (C) 1996-2007, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.rbbi;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.BreakIterator;
import java.text.CharacterIterator;
import java.util.Arrays;
import java.util.Locale;

public class BreakIteratorRegTest extends TestFmwk
{
    public static void main(String[] args) throws Exception {
        new BreakIteratorRegTest().run(args);
    }

    public void TestRegUnreg() {
    Locale thailand_locale = new Locale("th", "TH", "");
    Locale foo_locale = new Locale("fu", "FU", "FOO");
    BreakIterator jwbi = BreakIterator.getWordInstance(Locale.JAPAN);
    BreakIterator uwbi = BreakIterator.getWordInstance(Locale.US);
    BreakIterator usbi = BreakIterator.getSentenceInstance(Locale.US);
    BreakIterator twbi = BreakIterator.getWordInstance(thailand_locale);
    BreakIterator rwbi = BreakIterator.getWordInstance(new Locale("", "", ""));

    BreakIterator sbi = (BreakIterator)usbi.clone();
    // todo: this will cause the test to fail, no way to set a breakiterator to null text so can't fix yet.
    // String text = "This is some test, by golly. Boy, they don't make tests like they used to, do they?  This here test ain't worth $2.50.  Nope.";
    // sbi.setText(text);

    assertTrue(!BreakIterator.unregister(""), "unregister before register"); // coverage

    Object key0 = BreakIterator.registerInstance((BreakIterator)twbi.clone(), foo_locale, BreakIterator.KIND_WORD);
    Object key1 = BreakIterator.registerInstance(sbi, Locale.US, BreakIterator.KIND_WORD);
    Object key2 = BreakIterator.registerInstance((BreakIterator)twbi.clone(), Locale.US, BreakIterator.KIND_WORD);
    
    {
        BreakIterator test0 = BreakIterator.getWordInstance(Locale.JAPAN);
        BreakIterator test1 = BreakIterator.getWordInstance(Locale.US);
        BreakIterator test2 = BreakIterator.getSentenceInstance(Locale.US);
        BreakIterator test3 = BreakIterator.getWordInstance(thailand_locale);
        BreakIterator test4 = BreakIterator.getWordInstance(foo_locale);

        assertEqual(test0, jwbi, "japan word == japan word");
        assertEqual(test1, twbi, "us word == thai word");
        assertEqual(test2, usbi, "us sentence == us sentence");
        assertEqual(test3, twbi, "thai word == thai word");
        assertEqual(test4, twbi, "foo word == thai word");
    }

    //Locale[] locales = BreakIterator.getAvailableLocales();
    
    assertTrue(BreakIterator.unregister(key2), "unregister us word (thai word)");
    assertTrue(!BreakIterator.unregister(key2), "unregister second time");
    boolean error = false;
    try {
        BreakIterator.unregister(null);
    }
    catch (IllegalArgumentException e) {
        error = true;
    }

    assertTrue(error, "unregister null");

    {
        CharacterIterator sci = BreakIterator.getWordInstance(Locale.US).getText();
        int len = sci.getEndIndex() - sci.getBeginIndex();
        assertEqual(len, 0, "us word text: " + getString(sci));
    }

    assertTrue(Arrays.asList(BreakIterator.getAvailableLocales()).contains(foo_locale), "foo_locale");
    assertTrue(BreakIterator.unregister(key0), "unregister foo word (thai word)");
    assertTrue(!Arrays.asList(BreakIterator.getAvailableLocales()).contains(foo_locale), "no foo_locale");
    assertEqual(BreakIterator.getWordInstance(Locale.US), usbi, "us word == us sentence");
    
    assertTrue(BreakIterator.unregister(key1), "unregister us word (us sentence)");
    {
        BreakIterator test0 = BreakIterator.getWordInstance(Locale.JAPAN);
        BreakIterator test1 = BreakIterator.getWordInstance(Locale.US);
        BreakIterator test2 = BreakIterator.getSentenceInstance(Locale.US);
        BreakIterator test3 = BreakIterator.getWordInstance(thailand_locale);
        BreakIterator test4 = BreakIterator.getWordInstance(foo_locale);

        assertEqual(test0, jwbi, "japanese word break");
        assertEqual(test1, uwbi, "us sentence-word break");
        assertEqual(test2, usbi, "us sentence break");
        assertEqual(test3, twbi, "thai word break");
        assertEqual(test4, rwbi, "root word break");

        CharacterIterator sci = test1.getText();
        int len = sci.getEndIndex() - sci.getBeginIndex();
        assertEqual(len, 0, "us sentence-word break text: " + getString(sci));
    }
    }

    private void assertEqual(Object lhs, Object rhs, String msg) {
    msg(msg, lhs.equals(rhs) ? LOG : ERR, true, true);
    }

    private void assertEqual(int lhs, int rhs, String msg) {
    msg(msg, lhs == rhs ? LOG : ERR, true, true);
    }

    private void assertTrue(boolean arg, String msg) {
    msg(msg, arg ? LOG : ERR, true, true);
    }

    private static String getString(CharacterIterator ci) {
    StringBuffer buf = new StringBuffer(ci.getEndIndex() - ci.getBeginIndex() + 2);
    buf.append("'");
    for (char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) {
        buf.append(c);
    }
    buf.append("'");
    return buf.toString();
    }
}
