/*
 *******************************************************************************
 * Copyright (C) 2006-2011, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

package com.ibm.icu.tests;

import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Locale;

import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;

public class DateFormatTest extends ICUTestCase {
    private Calendar aCal;
    private Calendar anESTCal;
    private Date aDate;
    private String aDateString;
    private String aTimeString;
    private String anESTTimeString;
    private String aDateTimeString;
    private String aShortDateTimeString;
    private String aDefaultESTDateTimeString;
    private DateFormat aDF;
    private StringBuffer aBuf;
    private FieldPosition anFP;
    private FieldPosition anFPField;

    private static int YEAR_POS_START = 8;
    private static int YEAR_POS_END = 12;

    protected void setUp() throws Exception {
        super.setUp();
                
        java.util.GregorianCalendar gcal = new java.util.GregorianCalendar();
        gcal.clear();
        gcal.set(java.util.GregorianCalendar.YEAR, 1990);
        gcal.set(java.util.GregorianCalendar.MONTH, java.util.GregorianCalendar.DECEMBER);
        gcal.set(java.util.GregorianCalendar.DATE, 17);
        gcal.set(java.util.GregorianCalendar.HOUR, 5);
        gcal.set(java.util.GregorianCalendar.MINUTE, 17);
        aCal = new Calendar(gcal);
        anESTCal = Calendar.getInstance();
        anESTCal.setTimeZone(TimeZone.getTimeZone("EST"));
        aDate = gcal.getTime();
        aDateString = "Dec 17, 1990"; // medium -- the default
        aTimeString = "5:17:00 AM"; // medium
        anESTTimeString = "8:17:00 AM";
        aDateTimeString = "Dec 17, 1990 5:17:00 AM"; // medium, medium
        aDefaultESTDateTimeString = "Dec 17, 1990 8:17 AM"; // medium, short -- the default
        aShortDateTimeString = "12/17/90 5:17 AM"; // short, short
        aDF = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US);
        aBuf = new StringBuffer();
        anFP = new FieldPosition(DateFormat.YEAR_FIELD);
        anFPField = new FieldPosition(DateFormat.Field.YEAR);
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.hashCode()'
     */
    public final void testHashCode() {
        DateFormat df = DateFormat.getInstance();
        DateFormat eq = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
        testEHCS(df, eq, aDF);
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.DateFormat(DateFormat)'
     */
    public final void testDateFormat() {
        DateFormat df = new DateFormat(java.text.DateFormat.getInstance());
        assertEquals(DateFormat.getInstance(), df);
    }

    private void assertEqualDateString(StringBuffer buf) {
        assertEquals(aDateTimeString, buf.toString());
    }
        
    private void assertEqualDateString(String str) {
        assertEquals(aDateTimeString, str);
    }
        
    /*
     * Test method for 'com.ibm.icu.text.DateFormat.format(Object, StringBuffer, FieldPosition)'
     */
    public final void testFormatObjectStringBufferFieldPosition() {
        assertEqualDateString(aDF.format(aDate, aBuf, anFP));
        assertEquals(YEAR_POS_START, anFP.getBeginIndex());
        assertEquals(YEAR_POS_END, anFP.getEndIndex());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.format(Calendar, StringBuffer, FieldPosition)'
     */
    public final void testFormatCalendarStringBufferFieldPosition() {
        assertEqualDateString(aDF.format(aCal, aBuf, anFP));
        assertEquals(YEAR_POS_START, anFP.getBeginIndex());
        assertEquals(YEAR_POS_END, anFP.getEndIndex());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.format(Date, StringBuffer, FieldPosition)'
     */
    public final void testFormatDateStringBufferFieldPosition() {
        assertEqualDateString(aDF.format(aDate, aBuf, anFPField));
        assertEquals(YEAR_POS_START, anFPField.getBeginIndex());
        assertEquals(YEAR_POS_END, anFPField.getEndIndex());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.format(Date)'
     */
    public final void testFormatDate() {
        assertEqualDateString(aDF.format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.parse(String)'
     */
    public final void testParseString() throws Exception {
        assertEquals(aDate, aDF.parse(aDateTimeString));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.parse(String, Calendar, ParsePosition)'
     */
    public final void testParseStringCalendarParsePosition() {
        aDF.parse(aDateTimeString, aCal, new ParsePosition(0));
        assertEquals(aDate, aCal.getTime());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.parse(String, ParsePosition)'
     */
    public final void testParseStringParsePosition() {
        assertEquals(aDate, aDF.parse(aDateTimeString, new ParsePosition(0)));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.parseObject(String, ParsePosition)'
     */
    public final void testParseObjectStringParsePosition() {
        assertEquals(aDate, aDF.parseObject(aDateTimeString, new ParsePosition(0)));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance()'
     */
    public final void testGetTimeInstance() {
        assertEquals(aTimeString, DateFormat.getTimeInstance().format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int)'
     */
    public final void testGetTimeInstanceInt() {
        assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int, Locale)'
     */
    public final void testGetTimeInstanceIntLocale() {
        assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int, ULocale)'
     */
    public final void testGetTimeInstanceIntULocale() {
        assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM, ULocale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance()'
     */
    public final void testGetDateInstance() {
        assertEquals(aDateString, DateFormat.getDateInstance().format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int)'
     */
    public final void testGetDateInstanceInt() {
        assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int, Locale)'
     */
    public final void testGetDateInstanceIntLocale() {
        assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int, ULocale)'
     */
    public final void testGetDateInstanceIntULocale() {
        assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM, ULocale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance()'
     */
    public final void testGetDateTimeInstance() {
        assertEquals(aDateTimeString, DateFormat.getDateTimeInstance().format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int)'
     */
    public final void testGetDateTimeInstanceIntInt() {
        assertEquals(aDateTimeString, 
                     DateFormat.getDateTimeInstance(
                                                    DateFormat.MEDIUM, DateFormat.MEDIUM).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int, Locale)'
     */
    public final void testGetDateTimeInstanceIntIntLocale() {
        assertEquals(aDateTimeString, 
                     DateFormat.getDateTimeInstance(
                                                    DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int, ULocale)'
     */
    public final void testGetDateTimeInstanceIntIntULocale() {
        assertEquals(aDateTimeString, 
                     DateFormat.getDateTimeInstance(
                                                    DateFormat.MEDIUM, DateFormat.MEDIUM, ULocale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getInstance()'
     */
    public final void testGetInstance() {
        assertEquals(aShortDateTimeString, DateFormat.getInstance().format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getAvailableLocales()'
     */
    public final void testGetAvailableLocales() {
        Locale[] locales = DateFormat.getAvailableLocales();
        if (ICUTestCase.testingWrapper) {
            ICUTestCase.assertArraysEqual(java.text.DateFormat.getAvailableLocales(), locales);
        } else {
            assertNotNull(locales);
        }
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.setCalendar(Calendar)'
     */
    public final void testSetCalendar() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeZone(TimeZone.getTimeZone("EST"));
        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
        df.setCalendar(cal);
        assertEquals("8:17 AM", df.format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getCalendar()'
     */
    public final void testGetCalendar() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeZone(TimeZone.getTimeZone("EST"));
        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
        df.setCalendar(cal);
        assertEquals(cal, df.getCalendar());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.setNumberFormat(NumberFormat)'
     */
    public final void testSetNumberFormat() {
        // no easy way to test effect of setting the number format
        NumberFormat nf = NumberFormat.getInstance();
        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
        df.setNumberFormat(nf);
        // note, can't actually USE the dateformat since it changes the calendar
        assertEquals(nf, df.getNumberFormat());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getNumberFormat()'
     */
    public final void testGetNumberFormat() {
        // see testSetNumberFormat
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.setTimeZone(TimeZone)'
     */
    public final void testSetTimeZone() {
        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
        TimeZone tz = TimeZone.getTimeZone("EST");
        df.setTimeZone(tz);
        assertEquals("8:17 AM", df.format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getTimeZone()'
     */
    public final void testGetTimeZone() {
        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
        TimeZone tz = TimeZone.getTimeZone("EST");
        df.setTimeZone(tz);
        assertEquals(tz, df.getTimeZone());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.setLenient(boolean)'
     */
    public final void testSetLenient() throws Exception {
        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
        df.parse("2/31/90"); // succeeds, default is lenient
        df.setLenient(false);
        try {
            df.parse("2/31/90");
            throw new Exception("strict parse should have failed");
        }
        catch (ParseException e) {
            // ok, this is what we expect
        }
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.isLenient()'
     */
    public final void testIsLenient() {
        DateFormat df = DateFormat.getInstance();
        assertTrue(df.isLenient());
        df.setLenient(false);
        assertFalse(df.isLenient());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int, Locale)'
     */
    public final void testGetDateInstanceCalendarIntLocale() {
        assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM, Locale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int, ULocale)'
     */
    public final void testGetDateInstanceCalendarIntULocale() {
        assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM, ULocale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int, Locale)'
     */
    public final void testGetTimeInstanceCalendarIntLocale() {
        assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM, Locale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int, ULocale)'
     */
    public final void testGetTimeInstanceCalendarIntULocale() {
        assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM, ULocale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int, Locale)'
     */
    public final void testGetDateTimeInstanceCalendarIntIntLocale() {
        assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT, Locale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int, ULocale)'
     */
    public final void testGetDateTimeInstanceCalendarIntIntULocale() {
        assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT, ULocale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar, Locale)'
     */
    public final void testGetInstanceCalendarLocale() {
        assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal, Locale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar, ULocale)'
     */
    public final void testGetInstanceCalendarULocale() {
        assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal, ULocale.US).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar)'
     */
    public final void testGetInstanceCalendar() {
        assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int)'
     */
    public final void testGetDateInstanceCalendarInt() {
        assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int)'
     */
    public final void testGetTimeInstanceCalendarInt() {
        assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int)'
     */
    public final void testGetDateTimeInstanceCalendarIntInt() {
        assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT).format(aDate));
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.toString()'
     */
    public final void testToString() {
        assertNotNull(aDF.toString());
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.clone()'
     */
    public final void testClone() {
        // see testHashCode
    }

    /*
     * Test method for 'com.ibm.icu.text.DateFormat.equals(Object)'
     */
    public final void testEqualsObject() {
        // see testHashCode
    }
}
