//##header
/*
 *******************************************************************************
 * Copyright (C) 2001-2006, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

/** 
 * Port From:   ICU4C v1.8.1 : format : IntlTestDecimalFormatAPI
 * Source File: $ICU4CRoot/source/test/intltest/dcfmapts.cpp
 **/

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

import java.text.AttributedCharacterIterator;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.util.Iterator;
import java.util.Locale;
import java.util.Vector;

import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.NumberFormat;

// This is an API test, not a unit test.  It doesn't test very many cases, and doesn't
// try to test the full functionality.  It just calls each function in the class and
// verifies that it works on a basic level.
public class IntlTestDecimalFormatAPIC extends com.ibm.icu.dev.test.TestFmwk {
    
    public static void main(String[] args)  throws Exception {
        new IntlTestDecimalFormatAPIC().run(args);
    }

    // This test checks various generic API methods in DecimalFormat to achieve 100% API coverage.
    public void TestAPI() {

        logln("DecimalFormat API test---");
        logln("");
        Locale.setDefault(Locale.ENGLISH);

        // ======= Test constructors

        logln("Testing DecimalFormat constructors");

        DecimalFormat def = new DecimalFormat();

        final String pattern = new String("#,##0.# FF");
        DecimalFormat pat = null;
        try {
            pat = new DecimalFormat(pattern);
        } catch (IllegalArgumentException e) {
            errln("ERROR: Could not create DecimalFormat (pattern)");
        }

        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.FRENCH);

        DecimalFormat cust1 = new DecimalFormat(pattern, symbols);

        // ======= Test clone(), assignment, and equality

        logln("Testing clone() and equality operators");

        Format clone = (Format) def.clone();
        if (!def.equals(clone)) {
            errln("ERROR: Clone() failed");
        }

        // ======= Test various format() methods

        logln("Testing various format() methods");

        //        final double d = -10456.0037; // this appears as -10456.003700000001 on NT
        //        final double d = -1.04560037e-4; // this appears as -1.0456003700000002E-4 on NT
        final double d = -10456.00370000000000; // this works!
        final long l = 100000000;
        logln("" + Double.toString(d) + " is the double value");

        StringBuffer res1 = new StringBuffer();
        StringBuffer res2 = new StringBuffer();
        StringBuffer res3 = new StringBuffer();
        StringBuffer res4 = new StringBuffer();
        FieldPosition pos1 = new FieldPosition(0);
        FieldPosition pos2 = new FieldPosition(0);
        FieldPosition pos3 = new FieldPosition(0);
        FieldPosition pos4 = new FieldPosition(0);

        res1 = def.format(d, res1, pos1);
        logln("" + Double.toString(d) + " formatted to " + res1);

        res2 = pat.format(l, res2, pos2);
        logln("" + l + " formatted to " + res2);

        res3 = cust1.format(d, res3, pos3);
        logln("" + Double.toString(d) + " formatted to " + res3);

        res4 = cust1.format(l, res4, pos4);
        logln("" + l + " formatted to " + res4);

        // ======= Test parse()

        logln("Testing parse()");

        String text = new String("-10,456.0037");
        ParsePosition pos = new ParsePosition(0);
        String patt = new String("#,##0.#");
        pat.applyPattern(patt);
        double d2 = pat.parse(text, pos).doubleValue();
        if (d2 != d) {
            errln(
                "ERROR: Roundtrip failed (via parse(" + Double.toString(d2) + " != " + Double.toString(d) + ")) for " + text); 
        }
        logln(text + " parsed into " + (long) d2);

        // ======= Test getters and setters

        logln("Testing getters and setters");

        final DecimalFormatSymbols syms = pat.getDecimalFormatSymbols();
        def.setDecimalFormatSymbols(syms);
        if (!pat.getDecimalFormatSymbols().equals(def.getDecimalFormatSymbols())) {
            errln("ERROR: set DecimalFormatSymbols() failed");
        }

        String posPrefix;
        pat.setPositivePrefix("+");
        posPrefix = pat.getPositivePrefix();
        logln("Positive prefix (should be +): " + posPrefix);
        if (posPrefix != "+") {
            errln("ERROR: setPositivePrefix() failed");
        }

        String negPrefix;
        pat.setNegativePrefix("-");
        negPrefix = pat.getNegativePrefix();
        logln("Negative prefix (should be -): " + negPrefix);
        if (negPrefix != "-") {
            errln("ERROR: setNegativePrefix() failed");
        }

        String posSuffix;
        pat.setPositiveSuffix("_");
        posSuffix = pat.getPositiveSuffix();
        logln("Positive suffix (should be _): " + posSuffix);
        if (posSuffix != "_") {
            errln("ERROR: setPositiveSuffix() failed");
        }

        String negSuffix;
        pat.setNegativeSuffix("~");
        negSuffix = pat.getNegativeSuffix();
        logln("Negative suffix (should be ~): " + negSuffix);
        if (negSuffix != "~") {
            errln("ERROR: setNegativeSuffix() failed");
        }

        long multiplier = 0;
        pat.setMultiplier(8);
        multiplier = pat.getMultiplier();
        logln("Multiplier (should be 8): " + multiplier);
        if (multiplier != 8) {
            errln("ERROR: setMultiplier() failed");
        }

        int groupingSize = 0;
        pat.setGroupingSize(2);
        groupingSize = pat.getGroupingSize();
        logln("Grouping size (should be 2): " + (long) groupingSize);
        if (groupingSize != 2) {
            errln("ERROR: setGroupingSize() failed");
        }

        pat.setDecimalSeparatorAlwaysShown(true);
        boolean tf = pat.isDecimalSeparatorAlwaysShown();
        logln(
            "DecimalSeparatorIsAlwaysShown (should be true) is " + (tf ? "true" : "false")); 
        if (tf != true) {
            errln("ERROR: setDecimalSeparatorAlwaysShown() failed");
        }

        String funkyPat;
        funkyPat = pat.toPattern();
        logln("Pattern is " + funkyPat);

        String locPat;
        locPat = pat.toLocalizedPattern();
        logln("Localized pattern is " + locPat);

        // ======= Test applyPattern()

        logln("Testing applyPattern()");

        String p1 = new String("#,##0.0#;(#,##0.0#)");
        logln("Applying pattern " + p1);
        pat.applyPattern(p1);
        String s2;
        s2 = pat.toPattern();
        logln("Extracted pattern is " + s2);
        if (!s2.equals(p1)) {
            errln("ERROR: toPattern() result did not match pattern applied");
        }

        String p2 = new String("#,##0.0# FF;(#,##0.0# FF)");
        logln("Applying pattern " + p2);
        pat.applyLocalizedPattern(p2);
        String s3;
        s3 = pat.toLocalizedPattern();
        logln("Extracted pattern is " + s3);
        if (!s3.equals(p2)) {
            errln("ERROR: toLocalizedPattern() result did not match pattern applied");
        }

        // ======= Test getStaticClassID()

        //        logln("Testing instanceof()");

        //        try {
        //           NumberFormat test = new DecimalFormat();

        //            if (! (test instanceof DecimalFormat)) {
        //                errln("ERROR: instanceof failed");
        //            }
        //        }
        //        catch (Exception e) {
        //            errln("ERROR: Couldn't create a DecimalFormat");
        //        }
       
    }

    public void TestRounding() {
        double Roundingnumber = 2.55;
        double Roundingnumber1 = -2.55;
        //+2.55 results   -2.55 results
        double result[] = {
            3, -3,   
            2, -2, 
            3, -2, 
            2, -3, 
            3, -3, 
            3, -3, 
            3, -3 
        };
        DecimalFormat pat = new DecimalFormat();
        String s = "";
        s = pat.toPattern();
        logln("pattern = " + s);
        int mode;
        int i = 0;
        String message;
        String resultStr;
        for (mode = 0; mode < 7; mode++) {
            pat.setRoundingMode(mode);
            if (pat.getRoundingMode() != mode) {
                errln(
                     "SetRoundingMode or GetRoundingMode failed for mode=" + mode); 
            }

            //for +2.55 with RoundingIncrement=1.0
            pat.setRoundingIncrement(1.0);
            resultStr = pat.format(Roundingnumber);
            message = "round(" + (double) Roundingnumber
                    + "," + mode + ",FALSE) with RoundingIncrement=1.0==>"; 
            verify(message, resultStr, result[i++]);
            message = "";
            resultStr = "";

            //for -2.55 with RoundingIncrement=1.0
            resultStr = pat.format(Roundingnumber1);
            message = "round(" + (double) Roundingnumber1
                    + "," + mode + ",FALSE) with RoundingIncrement=1.0==>"; 
            verify(message, resultStr, result[i++]);
            message = "";
            resultStr = "";
        }
    }

//#ifndef FOUNDATION
    public void testFormatToCharacterIterator() {

        Number number = new Double(350.76);
        Number negativeNumber = new Double(-350.76);

        Locale us = Locale.US;
        Locale tr = new Locale("tr", "TR");

        // test number instance
        t_Format(1, number, NumberFormat.getNumberInstance(us),
                getNumberVectorUS());

//        // test percent instance
        t_Format(3, number, NumberFormat.getPercentInstance(us),
                getPercentVectorUS());
//
//        // test permille pattern
        DecimalFormat format = new DecimalFormat("###0.##\u2030");
//        t_Format(4, number, format, getPermilleVector());

        // test exponential pattern with positive exponent
        format = new DecimalFormat("00.0#E0");
        t_Format(5, number, format, getPositiveExponentVector());

//        // test exponential pattern with negative exponent
        format = new DecimalFormat("0000.0#E0");
        t_Format(6, number, format, getNegativeExponentVector());

        // test currency instance with US Locale
        t_Format(7, number, NumberFormat.getCurrencyInstance(us),
                getPositiveCurrencyVectorUS());

//        // test negative currency instance with US Locale
        t_Format(8, negativeNumber, NumberFormat.getCurrencyInstance(us),
                getNegativeCurrencyVectorUS());

//        // test multiple grouping seperators
        number = new Long(100300400);
        t_Format(11, number, NumberFormat.getNumberInstance(us),
                getNumberVector2US());

//        // test 0
        number = new Long(0);
        t_Format(12, number, NumberFormat.getNumberInstance(us),
                getZeroVector());
    }

    private static Vector getNumberVectorUS() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 3, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(3, 4, NumberFormat.Field.DECIMAL_SEPARATOR));
        v.add(new FieldContainer(4, 6, NumberFormat.Field.FRACTION));
        return v;
    }
    
    private static Vector getPositiveCurrencyVectorTR() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 3, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(4, 6, NumberFormat.Field.CURRENCY));
        return v;
    }

    private static Vector getNegativeCurrencyVectorTR() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 1, NumberFormat.Field.SIGN));
        v.add(new FieldContainer(1, 4, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(5, 7, NumberFormat.Field.CURRENCY));
        return v;
    }

    private static Vector getPositiveCurrencyVectorUS() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 1, NumberFormat.Field.CURRENCY));
        v.add(new FieldContainer(1, 4, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(4, 5, NumberFormat.Field.DECIMAL_SEPARATOR));
        v.add(new FieldContainer(5, 7, NumberFormat.Field.FRACTION));
        return v;
    }

    private static Vector getNegativeCurrencyVectorUS() {
        Vector v = new Vector();
        v.add(new FieldContainer(1, 2, NumberFormat.Field.CURRENCY));
        v.add(new FieldContainer(2, 5, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(5, 6, NumberFormat.Field.DECIMAL_SEPARATOR));
        v.add(new FieldContainer(6, 8, NumberFormat.Field.FRACTION));
        return v;
    }

    private static Vector getPercentVectorUS() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 2, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(2, 3, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(2, 3, NumberFormat.Field.GROUPING_SEPARATOR));
        v.add(new FieldContainer(3, 6, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(6, 7, NumberFormat.Field.PERCENT));
        return v;
    }

    private static Vector getPermilleVector() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 6, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(6, 7, NumberFormat.Field.PERMILLE));
        return v;
    }

    private static Vector getNegativeExponentVector() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 4, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(4, 5, NumberFormat.Field.DECIMAL_SEPARATOR));
        v.add(new FieldContainer(5, 6, NumberFormat.Field.FRACTION));
        v.add(new FieldContainer(6, 7, NumberFormat.Field.EXPONENT_SYMBOL));
        v.add(new FieldContainer(7, 8, NumberFormat.Field.EXPONENT_SIGN));
        v.add(new FieldContainer(8, 9, NumberFormat.Field.EXPONENT));
        return v;
    }

    private static Vector getPositiveExponentVector() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 2, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(2, 3, NumberFormat.Field.DECIMAL_SEPARATOR));
        v.add(new FieldContainer(3, 5, NumberFormat.Field.FRACTION));
        v.add(new FieldContainer(5, 6, NumberFormat.Field.EXPONENT_SYMBOL));
        v.add(new FieldContainer(6, 7, NumberFormat.Field.EXPONENT));
        return v;
    }

    private static Vector getNumberVector2US() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 3, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(3, 4, NumberFormat.Field.GROUPING_SEPARATOR));
        v.add(new FieldContainer(3, 4, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(4, 7, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(7, 8, NumberFormat.Field.GROUPING_SEPARATOR));
        v.add(new FieldContainer(7, 8, NumberFormat.Field.INTEGER));
        v.add(new FieldContainer(8, 11, NumberFormat.Field.INTEGER));
        return v;
    }

    private static Vector getZeroVector() {
        Vector v = new Vector();
        v.add(new FieldContainer(0, 1, NumberFormat.Field.INTEGER));
        return v;
    }    
    
    private void t_Format(int count, Object object, Format format,
            Vector expectedResults) {
        Vector results = findFields(format.formatToCharacterIterator(object));
        assertTrue("Test " + count
                + ": Format returned incorrect CharacterIterator for "
                + format.format(object), compare(results, expectedResults));
    }

    /**
     * compares two vectors regardless of the order of their elements
     */
    private static boolean compare(Vector vector1, Vector vector2) {
        return vector1.size() == vector2.size() && vector1.containsAll(vector2);
    }
    
    /**
     * finds attributes with regards to char index in this
     * AttributedCharacterIterator, and puts them in a vector
     * 
     * @param iterator
     * @return a vector, each entry in this vector are of type FieldContainer ,
     *         which stores start and end indexes and an attribute this range
     *         has
     */
    private static Vector findFields(AttributedCharacterIterator iterator) {
        Vector result = new Vector();
        while (iterator.getIndex() != iterator.getEndIndex()) {
            int start = iterator.getRunStart();
            int end = iterator.getRunLimit();

            Iterator it = iterator.getAttributes().keySet().iterator();
            while (it.hasNext()) {
                AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) it
                        .next();
                Object value = iterator.getAttribute(attribute);
                result.add(new FieldContainer(start, end, attribute, value));
                // System.out.println(start + " " + end + ": " + attribute + ",
                // " + value );
                // System.out.println("v.add(new FieldContainer(" + start +"," +
                // end +"," + attribute+ "," + value+ "));");
            }
            iterator.setIndex(end);
        }
        return result;
    }
    protected static class FieldContainer {
        int start, end;

        AttributedCharacterIterator.Attribute attribute;

        Object value;

//         called from support_decimalformat and support_simpledateformat tests
        public FieldContainer(int start, int end,
        AttributedCharacterIterator.Attribute attribute) {
            this(start, end, attribute, attribute);
        }

//         called from support_messageformat tests
        public FieldContainer(int start, int end, AttributedCharacterIterator.Attribute attribute, int value) {
        this(start, end, attribute, new Integer(value));
        }

//         called from support_messageformat tests
        public FieldContainer(int start, int end, AttributedCharacterIterator.Attribute attribute,
        Object value) {
        this.start = start;
        this.end = end;
        this.attribute = attribute;
        this.value = value;
        }

        public boolean equals(Object obj) {
        if (!(obj instanceof FieldContainer))
        return false;

        FieldContainer fc = (FieldContainer) obj;
        return (start == fc.start && end == fc.end
        && attribute == fc.attribute && value.equals(fc.value));
        }
    } 
//#endif

    /*Helper functions */
    public void verify(String message, String got, double expected) {
        logln(message + got + " Expected : " + (long)expected);
        String expectedStr = "";
        expectedStr=expectedStr + (long)expected;
        if(!got.equals(expectedStr) ) {
            errln("ERROR: Round() failed:  " + message + got + "  Expected : " + expectedStr);
        }
    }
}
//eof
