/*
 *******************************************************************************
 * Copyright (C) 2007-2011, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

package com.ibm.icu.tests;

import java.math.BigInteger;
import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Locale;

import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.util.ULocale;

public class NumberFormatTest extends ICUTestCase {

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.NumberFormat(NumberFormat)'
     */
    public void testNumberFormat() {
        NumberFormat nf = new NumberFormat(java.text.NumberFormat.getInstance());
        assertEquals(nf, NumberFormat.getInstance());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(Object, StringBuffer, FieldPosition)'
     */
    public void testFormatObjectStringBufferFieldPosition() {
        Number num = new Long(1234L);
        StringBuffer buf = new StringBuffer();
        FieldPosition fp = new FieldPosition(NumberFormat.INTEGER_FIELD);
        NumberFormat.getInstance().format(num, buf, fp);
        assertEquals("1,234", buf.toString());
        assertEquals(0, fp.getBeginIndex());
        assertEquals(5, fp.getEndIndex());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.parseObject(String, ParsePosition)'
     */
    public void testParseObjectStringParsePosition() {
        ParsePosition pp = new ParsePosition(0);
        Object result = NumberFormat.getInstance().parse("1,234", pp);
        assertEquals(result, new Long(1234));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(double)'
     */
    public void testFormatDouble() {
        assertEquals("1,234.567", NumberFormat.getInstance().format(1234.567));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(long)'
     */
    public void testFormatLong() {
        assertEquals("1,234", NumberFormat.getInstance().format(1234L));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(BigInteger)'
     */
    public void testFormatBigInteger() {
        // note, java doesn't handle biginteger with full precision.
        BigInteger bi = new BigInteger("123456");
        assertEquals("123,456", java.text.NumberFormat.getInstance().format(bi));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(double, StringBuffer, FieldPosition)'
     */
    public void testFormatDoubleStringBufferFieldPosition() {
        StringBuffer buf = new StringBuffer();
        FieldPosition fp = new FieldPosition(NumberFormat.FRACTION_FIELD);
        assertEquals("123,456.789", NumberFormat.getInstance().format(123456.789, buf, fp).toString());
        assertEquals(8, fp.getBeginIndex());
        assertEquals(11, fp.getEndIndex());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(long, StringBuffer, FieldPosition)'
     */
    public void testFormatLongStringBufferFieldPosition() {
        StringBuffer buf = new StringBuffer();
        FieldPosition fp = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
        assertEquals("123,456", NumberFormat.getInstance().format(123456L, buf, fp).toString());
        assertEquals(3, fp.getBeginIndex());
        assertEquals(4, fp.getEndIndex());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(BigInteger, StringBuffer, FieldPosition)'
     */
    public void testFormatBigIntegerStringBufferFieldPosition() {
        // note, java doesn't handle biginteger with full precision.
        StringBuffer buf = new StringBuffer();
        FieldPosition fp = new FieldPosition(0);
        BigInteger bi = new BigInteger("123456");
        assertEquals("123,456", java.text.NumberFormat.getInstance().format(bi, buf, fp).toString());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.parse(String, ParsePosition)'
     */
    public void testParseStringParsePosition() {
        ParsePosition pp = new ParsePosition(3);
        assertEquals(new Long(123456), NumberFormat.getInstance().parse("xxx123,456yyy", pp));
        assertEquals(10, pp.getIndex());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.parse(String)'
     */
    public void testParseString() throws ParseException {
        Number result = NumberFormat.getInstance().parse("123,456,yyy");
        assertEquals(new Long(123456), result);
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.isParseIntegerOnly()'
     */
    public void testIsParseIntegerOnly() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setParseIntegerOnly(true);
        assertTrue(nf.isParseIntegerOnly());
        nf.setParseIntegerOnly(false);
        assertFalse(nf.isParseIntegerOnly());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.setParseIntegerOnly(boolean)'
     */
    public void testSetParseIntegerOnly() throws ParseException {
        String str = "123.456,yyy";
        NumberFormat nf = NumberFormat.getInstance();
        assertEquals(new Double(123.456), nf.parse(str));
        nf.setParseIntegerOnly(true);
        assertEquals(new Long(123), nf.parse(str));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance()'
     */
    public void testGetInstance() {
        // used everywhere, no need to test
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance(Locale)'
     */
    public void testGetInstanceLocale() {
        NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
        assertEquals("123,456", nf.format(123.456));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance(ULocale)'
     */
    public void testGetInstanceULocale() {
        NumberFormat nf = NumberFormat.getInstance(ULocale.GERMANY);
        assertEquals("123,456", nf.format(123.456));            
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance()'
     */
    public void testGetNumberInstance() {
        NumberFormat nf = NumberFormat.getNumberInstance();
        assertEquals("123,456.789", nf.format(123456.789));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance(Locale)'
     */
    public void testGetNumberInstanceLocale() {
        NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMANY);
        assertEquals("123.456,789", nf.format(123456.789));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance(ULocale)'
     */
    public void testGetNumberInstanceULocale() {
        NumberFormat nf = NumberFormat.getNumberInstance(ULocale.GERMANY);
        assertEquals("123.456,789", nf.format(123456.789));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance()'
     */
    public void testGetIntegerInstance() {
        NumberFormat nf = NumberFormat.getIntegerInstance();
        assertEquals("123,457", nf.format(123456.789)); // rounds
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance(Locale)'
     */
    public void testGetIntegerInstanceLocale() {
        NumberFormat nf = NumberFormat.getIntegerInstance(Locale.GERMANY);
        assertEquals("123.457", nf.format(123456.789)); // rounds
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance(ULocale)'
     */
    public void testGetIntegerInstanceULocale() {
        NumberFormat nf = NumberFormat.getIntegerInstance(ULocale.GERMANY);
        assertEquals("123.457", nf.format(123456.789)); // rounds
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance()'
     */
    public void testGetCurrencyInstance() {
        NumberFormat nf = NumberFormat.getCurrencyInstance();
        assertEquals("$123,456.99", nf.format(123456.99));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance(Locale)'
     */
    public void testGetCurrencyInstanceLocale() {
        NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.GERMANY);
        assertEquals("123.456,99 \u20AC", nf.format(123456.99));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance(ULocale)'
     */
    public void testGetCurrencyInstanceULocale() {
        NumberFormat nf = NumberFormat.getCurrencyInstance(ULocale.GERMANY);
        assertEquals("123.456,99 \u20AC", nf.format(123456.99));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance()'
     */
    public void testGetPercentInstance() {
        NumberFormat nf = NumberFormat.getPercentInstance();
        assertEquals("123,456%", nf.format(1234.56));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance(Locale)'
     */
    public void testGetPercentInstanceLocale() {
        NumberFormat nf = NumberFormat.getPercentInstance(Locale.GERMANY);
        assertEquals("123.456%", nf.format(1234.56));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance(ULocale)'
     */
    public void testGetPercentInstanceULocale() {
        NumberFormat nf = NumberFormat.getPercentInstance(ULocale.GERMANY);
        assertEquals("123.456%", nf.format(1234.56));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance()'
     */
    public void testGetScientificInstance() {
        NumberFormat nf = NumberFormat.getScientificInstance();
        assertEquals(".123456E4", nf.format(1234.56));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance(Locale)'
     */
    public void testGetScientificInstanceLocale() {
        NumberFormat nf = NumberFormat.getScientificInstance(Locale.GERMANY);
        assertEquals(",123456E4", nf.format(1234.56));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance(ULocale)'
     */
    public void testGetScientificInstanceULocale() {
        NumberFormat nf = NumberFormat.getScientificInstance(ULocale.GERMANY);
        assertEquals(",123456E4", nf.format(1234.56));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getAvailableLocales()'
     */
    public void testGetAvailableLocales() {
        Locale[] ilocales = NumberFormat.getAvailableLocales();
        if (ICUTestCase.testingWrapper) {
            Locale[] jlocales = java.text.NumberFormat.getAvailableLocales();
            for (int i = 0; i < ilocales.length; ++i) {
                assertEquals(jlocales[i], ilocales[i]);
            }
        }
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getAvailableULocales()'
     */
    public void testGetAvailableULocales() {
        ULocale[] ulocales = NumberFormat.getAvailableULocales();
        if (ICUTestCase.testingWrapper) {
            Locale[] jlocales = java.text.NumberFormat.getAvailableLocales();
            for (int i = 0; i < ulocales.length; ++i) {
                assertEquals(jlocales[i], ulocales[i].toLocale());
            }
        }
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.isGroupingUsed()'
     */
    public void testIsGroupingUsed() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(true);
        assertTrue(nf.isGroupingUsed());
        nf.setGroupingUsed(false);
        assertFalse(nf.isGroupingUsed());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.setGroupingUsed(boolean)'
     */
    public void testSetGroupingUsed() {
        NumberFormat nf = NumberFormat.getInstance();
        assertEquals("123,456,789", nf.format(123456789));
        nf.setGroupingUsed(false);
        assertEquals("123456789", nf.format(123456789));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getMaximumIntegerDigits()'
     */
    public void testGetMaximumIntegerDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumIntegerDigits(4);
        assertEquals(4, nf.getMaximumIntegerDigits());
        nf.setMaximumIntegerDigits(6);
        assertEquals(6, nf.getMaximumIntegerDigits());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.setMaximumIntegerDigits(int)'
     */
    public void testSetMaximumIntegerDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumIntegerDigits(4);
        assertEquals("3,456", nf.format(123456)); // high digits truncated
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getMinimumIntegerDigits()'
     */
    public void testGetMinimumIntegerDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMinimumIntegerDigits(4);
        assertEquals(4, nf.getMinimumIntegerDigits());
        nf.setMinimumIntegerDigits(6);
        assertEquals(6, nf.getMinimumIntegerDigits());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.setMinimumIntegerDigits(int)'
     */
    public void testSetMinimumIntegerDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMinimumIntegerDigits(4);
        assertEquals("0,012", nf.format(12)); // pad out with zero, grouping still used
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getMaximumFractionDigits()'
     */
    public void testGetMaximumFractionDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumFractionDigits(4);
        assertEquals(4, nf.getMaximumFractionDigits());
        nf.setMaximumFractionDigits(6);
        assertEquals(6, nf.getMaximumFractionDigits());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.setMaximumFractionDigits(int)'
     */
    public void testSetMaximumFractionDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumFractionDigits(4);
        assertEquals("1.2346", nf.format(1.2345678)); // low digits rounded
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.getMinimumFractionDigits()'
     */
    public void testGetMinimumFractionDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMinimumFractionDigits(4);
        assertEquals(4, nf.getMinimumFractionDigits());
        nf.setMinimumFractionDigits(6);
        assertEquals(6, nf.getMinimumFractionDigits());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.setMinimumFractionDigits(int)'
     */
    public void testSetMinimumFractionDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMinimumFractionDigits(4);
        assertEquals("1.2000", nf.format(1.2));
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.toString()'
     */
    public void testToString() {
        assertNotNull(NumberFormat.getInstance().toString());
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.hashCode()'
     */
    public void testHashCode() {
        NumberFormat nf = NumberFormat.getInstance();
        NumberFormat eq = NumberFormat.getInstance(Locale.US);
        NumberFormat neq = NumberFormat.getInstance(Locale.GERMANY);
                
        ICUTestCase.testEHCS(nf, eq, neq);
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.clone()'
     */
    public void testClone() {
        // see testHashCode
    }

    /*
     * Test method for 'com.ibm.icu.x.text.NumberFormat.equals(Object)'
     */
    public void testEqualsObject() {
        // see testHashCode
    }
}
