/*
 *******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 * $Source: 
 * $Date: 
 * $Revision: 
 *
 *****************************************************************************************
 */

/** 
 * Port From:   ICU4C v2.1 : Collate/CollationCurrencyTest
 * Source File: $ICU4CRoot/source/test/intltest/currcoll.cpp
 **/
 
package com.ibm.icu.dev.test.collator;
 
import com.ibm.icu.dev.test.*;
import com.ibm.icu.text.*;
import java.util.Locale;
 
public class CollationCurrencyTest extends TestFmwk {
    public static void main(String[] args) throws Exception {
        new CollationCurrencyTest().run(args);
    }
    
    public void TestCurrency() {
        // All the currency symbols, in collation order
        char[][] currency = {
            { 0x00A4 }, /*00A4; L; [14 36, 03, 03]    # [082B.0020.0002] # CURRENCY SIGN*/
            { 0x00A2 }, /*00A2; L; [14 38, 03, 03]    # [082C.0020.0002] # CENT SIGN*/
            { 0xFFE0 }, /*FFE0; L; [14 38, 03, 05]    # [082C.0020.0003] # FULLWIDTH CENT SIGN*/
            { 0x0024 }, /*0024; L; [14 3A, 03, 03]    # [082D.0020.0002] # DOLLAR SIGN*/
            { 0xFF04 }, /*FF04; L; [14 3A, 03, 05]    # [082D.0020.0003] # FULLWIDTH DOLLAR SIGN*/
            { 0xFE69 }, /*FE69; L; [14 3A, 03, 1D]    # [082D.0020.000F] # SMALL DOLLAR SIGN*/
            { 0x00A3 }, /*00A3; L; [14 3C, 03, 03]    # [082E.0020.0002] # POUND SIGN*/
            { 0xFFE1 }, /*FFE1; L; [14 3C, 03, 05]    # [082E.0020.0003] # FULLWIDTH POUND SIGN*/
            { 0x00A5 }, /*00A5; L; [14 3E, 03, 03]    # [082F.0020.0002] # YEN SIGN*/
            { 0xFFE5 }, /*FFE5; L; [14 3E, 03, 05]    # [082F.0020.0003] # FULLWIDTH YEN SIGN*/
            { 0x09F2 }, /*09F2; L; [14 40, 03, 03]    # [0830.0020.0002] # BENGALI RUPEE MARK*/
            { 0x09F3 }, /*09F3; L; [14 42, 03, 03]    # [0831.0020.0002] # BENGALI RUPEE SIGN*/
            { 0x0E3F }, /*0E3F; L; [14 44, 03, 03]    # [0832.0020.0002] # THAI CURRENCY SYMBOL BAHT*/
            { 0x17DB }, /*17DB; L; [14 46, 03, 03]    # [0833.0020.0002] # KHMER CURRENCY SYMBOL RIEL*/
            { 0x20A0 }, /*20A0; L; [14 48, 03, 03]    # [0834.0020.0002] # EURO-CURRENCY SIGN*/
            { 0x20A1 }, /*20A1; L; [14 4A, 03, 03]    # [0835.0020.0002] # COLON SIGN*/
            { 0x20A2 }, /*20A2; L; [14 4C, 03, 03]    # [0836.0020.0002] # CRUZEIRO SIGN*/
            { 0x20A3 }, /*20A3; L; [14 4E, 03, 03]    # [0837.0020.0002] # FRENCH FRANC SIGN*/
            { 0x20A4 }, /*20A4; L; [14 50, 03, 03]    # [0838.0020.0002] # LIRA SIGN*/
            { 0x20A5 }, /*20A5; L; [14 52, 03, 03]    # [0839.0020.0002] # MILL SIGN*/
            { 0x20A6 }, /*20A6; L; [14 54, 03, 03]    # [083A.0020.0002] # NAIRA SIGN*/
            { 0x20A7 }, /*20A7; L; [14 56, 03, 03]    # [083B.0020.0002] # PESETA SIGN*/
            { 0x20A9 }, /*20A9; L; [14 58, 03, 03]    # [083C.0020.0002] # WON SIGN*/
            { 0xFFE6 }, /*FFE6; L; [14 58, 03, 05]    # [083C.0020.0003] # FULLWIDTH WON SIGN*/
            { 0x20AA }, /*20AA; L; [14 5A, 03, 03]    # [083D.0020.0002] # NEW SHEQEL SIGN*/
            { 0x20AB }, /*20AB; L; [14 5C, 03, 03]    # [083E.0020.0002] # DONG SIGN*/
            { 0x20AC }, /*20AC; L; [14 5E, 03, 03]    # [083F.0020.0002] # EURO SIGN*/
            { 0x20AD }, /*20AD; L; [14 60, 03, 03]    # [0840.0020.0002] # KIP SIGN*/
            { 0x20AE }, /*20AE; L; [14 62, 03, 03]    # [0841.0020.0002] # TUGRIK SIGN*/
            { 0x20AF } /*20AF; L; [14 64, 03, 03]    # [0842.0020.0002] # DRACHMA SIGN*/
        };
    
        int i, j;
        int expectedResult = 0;
        RuleBasedCollator c = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH);
        
        // Compare each currency symbol against all the
        // currency symbols, including itself
        String source;
        String target;
        
        for (i = 0; i < currency.length; i += 1) {
            for (j = 0; j < currency.length; j += 1) {
                source = new String(currency[i]);
                target = new String(currency[j]);

                if (i < j) {
                    expectedResult = -1;
                } else if ( i == j) {
                    expectedResult = 0;
                } else {
                    expectedResult = 1;
                }

                int compareResult = c.compare(source, target);
                CollationKey sourceKey = null;
            
                sourceKey = c.getCollationKey(source);

                if (sourceKey == null) {
                    errln("Couldn't get collationKey for source");
                    continue;
                }
            
                CollationKey targetKey = null;
                targetKey = c.getCollationKey(target);
                if (targetKey == null) {
                    errln("Couldn't get collationKey for source");
                    continue;
                }

                int keyResult = sourceKey.compareTo(targetKey);

                reportCResult( source, target, sourceKey, targetKey, compareResult, keyResult, compareResult, expectedResult );
            }
        }
    }
    
    private void reportCResult( String source, String target, CollationKey sourceKey, CollationKey targetKey,
                                int compareResult, int keyResult, int incResult, int expectedResult ) {
        if (expectedResult < -1 || expectedResult > 1) {
            errln("***** invalid call to reportCResult ****");
            return;
        }

        boolean ok1 = (compareResult == expectedResult);
        boolean ok2 = (keyResult == expectedResult);
        boolean ok3 = (incResult == expectedResult);

        if (ok1 && ok2 && ok3 && !isVerbose()) {
            return;    
        } else {
            String msg1 = ok1? "Ok: compare(\"" : "FAIL: compare(\"";
            String msg2 = "\", \"";
            String msg3 = "\") returned ";
            String msg4 = "; expected ";
            
            String sExpect = new String("");
            String sResult = new String("");
            sResult = appendCompareResult(compareResult, sResult);
            sExpect = appendCompareResult(expectedResult, sExpect);
            if (ok1) {
                logln(msg1 + source + msg2 + target + msg3 + sResult);
            } else {
                errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
            }
            
            msg1 = ok2 ? "Ok: key(\"" : "FAIL: key(\"";
            msg2 = "\").compareTo(key(\"";
            msg3 = "\")) returned ";
            sResult = appendCompareResult(keyResult, sResult);
            if (ok2) {
                logln(msg1 + source + msg2 + target + msg3 + sResult);
            } else {
                errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
                msg1 = "  ";
                msg2 = " vs. ";
                errln(msg1 + prettify(sourceKey) + msg2 + prettify(targetKey));
            }
            
            msg1 = ok3 ? "Ok: incCompare(\"" : "FAIL: incCompare(\"";
            msg2 = "\", \"";
            msg3 = "\") returned ";

            sResult = appendCompareResult(incResult, sResult);

            if (ok3) {
                logln(msg1 + source + msg2 + target + msg3 + sResult);
            } else {
                errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
            }                
        }
    }
    
    private String appendCompareResult(int result, String target){
        if (result == -1) {
            target += "LESS";
        } else if (result == 0) {
            target += "EQUAL";
        } else if (result == 1) {
            target += "GREATER";
        } else {
            String huh = "?";
            target += huh + result;
        }
        return target;
    }
    
    String prettify(CollationKey sourceKey) {
        int i;
        byte[] bytes= sourceKey.toByteArray();
        String target = "[";
    
        for (i = 0; i < bytes.length; i++) {
            target += Integer.toHexString(bytes[i]);
            target += " ";
        }
        target += "]";
        return target;
    }
}