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

import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Locale;

import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.JapaneseCalendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;

/**
 * Tests for the <code>JapaneseCalendar</code> class.
 */
public class JapaneseTest extends CalendarTest {
    public static void main(String args[]) throws Exception {
        new JapaneseTest().run(args);
    }

    public void TestCoverage() {
    {
        // new JapaneseCalendar(TimeZone)
        JapaneseCalendar cal = new JapaneseCalendar(TimeZone.getDefault());
        if(cal == null){
            errln("could not create JapaneseCalendar with TimeZone");
        }
    }

    {
        // new JapaneseCalendar(ULocale)
        JapaneseCalendar cal = new JapaneseCalendar(ULocale.getDefault());
        if(cal == null){
            errln("could not create JapaneseCalendar with ULocale");
        }
    }

    {
        // new JapaneseCalendar(TimeZone, ULocale)
        JapaneseCalendar cal = new JapaneseCalendar(TimeZone.getDefault(), ULocale.getDefault());
        if(cal == null){
            errln("could not create JapaneseCalendar with TimeZone ULocale");
        }
    }

    {
        // new JapaneseCalendar(Locale)
        JapaneseCalendar cal = new JapaneseCalendar(Locale.getDefault());
        if(cal == null){
            errln("could not create JapaneseCalendar with Locale");
        }
    }

    {
        // new JapaneseCalendar(TimeZone, Locale)
        JapaneseCalendar cal = new JapaneseCalendar(TimeZone.getDefault(), Locale.getDefault());
        if(cal == null){
            errln("could not create JapaneseCalendar with TimeZone Locale");
        }
    }

    {
        // new JapaneseCalendar(Date)
        JapaneseCalendar cal = new JapaneseCalendar(new Date());
        if(cal == null){
            errln("could not create JapaneseCalendar with Date");
        }
    }

    {
        // new JapaneseCalendar(int year, int month, int date)
        JapaneseCalendar cal = new JapaneseCalendar(1868, Calendar.JANUARY, 1);
        if(cal == null){
            errln("could not create JapaneseCalendar with year,month,date");
        }
    }

    {
        // new JapaneseCalendar(int era, int year, int month, int date)
        JapaneseCalendar cal = new JapaneseCalendar(JapaneseCalendar.MEIJI, 43, Calendar.JANUARY, 1);
        if(cal == null){
            errln("could not create JapaneseCalendar with era,year,month,date");
        }
    }

    {
        // new JapaneseCalendar(int year, int month, int date, int hour, int minute, int second)
        JapaneseCalendar cal = new JapaneseCalendar(1868, Calendar.JANUARY, 1, 1, 1, 1);
        if(cal == null){
            errln("could not create JapaneseCalendar with year,month,date,hour,min,second");
        }
    }

    {
        // limits
        JapaneseCalendar cal = new JapaneseCalendar();
        DateFormat fmt = cal.getDateTimeFormat(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH);

        cal.set(Calendar.ERA, JapaneseCalendar.MEIJI);
        logln("date: " + cal.getTime());
        logln("min era: " + cal.getMinimum(Calendar.ERA));
        logln("min year: " + cal.getMinimum(Calendar.YEAR));
        cal.set(Calendar.YEAR, cal.getActualMaximum(Calendar.YEAR));
        logln("date: " + fmt.format(cal.getTime()));
        cal.add(Calendar.YEAR, 1);
        logln("date: " + fmt.format(cal.getTime()));
    }

    {
        // data
        JapaneseCalendar cal = new JapaneseCalendar(1868, Calendar.JANUARY, 1);
        Date time = cal.getTime();

        String[] calendarLocales = {
        "en", "ja_JP"
        };

        String[] formatLocales = {
        "en", "ja"
        };
        for (int i = 0; i < calendarLocales.length; ++i) {
            String calLocName = calendarLocales[i];
            Locale calLocale = LocaleUtility.getLocaleFromName(calLocName);
            cal = new JapaneseCalendar(calLocale);

            for (int j = 0; j < formatLocales.length; ++j) {
                String locName = formatLocales[j];
                Locale formatLocale = LocaleUtility.getLocaleFromName(locName);
                DateFormat format = DateFormat.getDateTimeInstance(cal, DateFormat.FULL, DateFormat.FULL, formatLocale);
                logln(calLocName + "/" + locName + " --> " + format.format(time));
            }
        }
    }
    }
    
    public void Test3860()
    {
        ULocale loc = new ULocale("ja_JP@calendar=japanese");
        Calendar cal = new JapaneseCalendar(loc);
        DateFormat enjformat = cal.getDateTimeFormat(0,0,new ULocale("en_JP@calendar=japanese"));
        DateFormat format = cal.getDateTimeFormat(0,0,loc);
        ((SimpleDateFormat)format).applyPattern("y.M.d");  // Note: just 'y' doesn't work here.
        ParsePosition pos = new ParsePosition(0);
        Date aDate = format.parse("1.1.9", pos); // after the start of heisei accession.  Jan 1, 1H wouldn't work  because it is actually showa 64
        String inEn = enjformat.format(aDate);

        cal.clear();
        cal.setTime(aDate);
        int gotYear = cal.get(Calendar.YEAR);
        int gotEra = cal.get(Calendar.ERA);
        
        int expectYear = 1;
        int expectEra = JapaneseCalendar.CURRENT_ERA;
        
        if((gotYear != expectYear) || (gotEra != expectEra)) {
            errln("Expected year " + expectYear + ", era " + expectEra +", but got year " + gotYear + " and era " + gotEra + ", == " + inEn);
        } else {
            logln("Got year " + gotYear + " and era " + gotEra + ", == " + inEn);
        }

        // Test parse with missing era (should default to current era, heisei)
        // Test parse with incomplete information
        logln("Testing parse w/ just year...");
        Calendar cal2 = new JapaneseCalendar(loc);
        SimpleDateFormat fmt = new SimpleDateFormat("y", loc);
        SimpleDateFormat fmt2 = new SimpleDateFormat("HH:mm:ss.S MMMM d, yyyy G", new ULocale("en_US@calendar=gregorian"));
        cal2.clear();
        String samplestr = "1";
        logln("Test Year: " + samplestr);
        try {
            aDate = fmt.parse(samplestr);
        } catch (ParseException pe) {
            errln("Error parsing " + samplestr);
        }
        ParsePosition pp = new ParsePosition(0);
        fmt.parse(samplestr, cal2, pp);
        logln("cal2 after 1 parse:");
        String str = fmt2.format(aDate);
        logln("as Gregorian Calendar: " + str);

        cal2.setTime(aDate);
        gotYear = cal2.get(Calendar.YEAR);
        gotEra = cal2.get(Calendar.ERA);
        expectYear = 1;
        expectEra = JapaneseCalendar.CURRENT_ERA;
        if((gotYear != 1) || (gotEra != expectEra)) {
            errln("parse "+ samplestr + " of 'y' as Japanese Calendar, expected year " + expectYear + 
                " and era " + expectEra + ", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")");
        } else {            
            logln(" year: " + gotYear + ", era: " + gotEra);
        }
    }

    public void Test5345parse() {
        // Test parse with incomplete information
        DateFormat fmt2= DateFormat.getDateInstance(); //DateFormat.LONG, Locale.US);
        JapaneseCalendar c = new JapaneseCalendar(TimeZone.getDefault(), new ULocale("en_US"));
        SimpleDateFormat fmt = (SimpleDateFormat)c.getDateTimeFormat(1,1,new ULocale("en_US@calendar=japanese"));
        fmt.applyPattern("G y");
        logln("fmt's locale = " + fmt.getLocale(ULocale.ACTUAL_LOCALE));
        //SimpleDateFormat fmt = new SimpleDateFormat("G y", new Locale("en_US@calendar=japanese"));
        long aDateLong = -3197117222000L; // 1868-09-08 00:00 Pacific Time (GMT-07:52:58)
        if (TimeZone.getDefaultTimeZoneType() == TimeZone.TIMEZONE_JDK) {
            // Java time zone implementation does not support LMTs
            aDateLong = -3197116800000L; // 1868-09-08 00:00 Pacific Time (GMT-08:00)
        }
        Date aDate = new Date(aDateLong);
        logln("aDate: " + aDate.toString() +", from " + aDateLong);
        String str;
        str = fmt2.format(aDate);
        logln("Test Date: " + str);
        str = fmt.format(aDate);
        logln("as Japanese Calendar: " + str);
        String expected = "Meiji 1";
        if(!str.equals(expected)) {
            errln("FAIL: Expected " + expected + " but got " + str);
        }
        Date otherDate;
        try {
            otherDate = fmt.parse(expected);
            if(!otherDate.equals(aDate)) { 
                String str3;
    //            ParsePosition pp;
                Date dd = fmt.parse(expected);
                str3 = fmt.format(otherDate);
                long oLong = otherDate.getTime();
                long aLong = otherDate.getTime();
                
                errln("FAIL: Parse incorrect of " + expected + ":  wanted " + aDate + " ("+aLong+"), but got " +  " " +
                    otherDate + " ("+oLong+") = " + str3 + " not " + dd.toString() );


            } else {
                logln("Parsed OK: " + expected);
            }
        } catch(java.text.ParseException pe) {
            errln("FAIL: ParseException: " + pe.toString());
            pe.printStackTrace();
        }
    }


    private void checkExpected(Calendar c, int expected[] ) {
        final String[] FIELD_NAME = {
            "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH",
            "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK",
            "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY",
            "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
            "DST_OFFSET", "YEAR_WOY", "DOW_LOCAL", "EXTENDED_YEAR",
            "JULIAN_DAY", "MILLISECONDS_IN_DAY",
        };

        for(int i= 0;i<expected.length;i += 2) {
            int fieldNum = expected[i+0];
            int expectedVal = expected[i+1];
            int actualVal = c.get(fieldNum);
            
            if(expectedVal == actualVal) {
                logln(FIELD_NAME[fieldNum]+": "+ actualVal);
            } else {
                errln("FAIL: "+FIELD_NAME[fieldNum]+": expected "+ expectedVal + " got " +  actualVal);
            }
        }
    }

    public void Test5345calendar() {
        logln("** testIncompleteCalendar()");
        // Test calendar with incomplete information
        JapaneseCalendar c = new JapaneseCalendar(TimeZone.getDefault());
        logln("test clear");
        c.clear();
 
        // Showa 45 = Gregorian 1970
        int expected0[] = {   Calendar.ERA, 234,
                              Calendar.YEAR, 45 };
        checkExpected(c, expected0);

        logln("test setting era");
        c.clear();
        c.set(Calendar.ERA, JapaneseCalendar.MEIJI);
        
        
        int expectedA[] = {   Calendar.ERA, JapaneseCalendar.MEIJI };
        checkExpected(c, expectedA);


        logln("test setting era and year and month and date");
        c.clear();
        c.set(Calendar.ERA, JapaneseCalendar.MEIJI);
        c.set(Calendar.YEAR, 1);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 1);


        int expectedC[] = {   Calendar.ERA, JapaneseCalendar.MEIJI -1};
        checkExpected(c, expectedC);


        logln("test setting  year and month and date THEN era");
        c.clear();
        c.set(Calendar.YEAR, 1);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 1);
        c.set(Calendar.ERA, JapaneseCalendar.MEIJI);
        
        
        checkExpected(c, expectedC);
        
        
        logln("test setting era and year");
        c.clear();
        c.set(Calendar.YEAR, 1);
        c.set(Calendar.ERA, JapaneseCalendar.MEIJI);


        int expectedB[] = { Calendar.ERA, JapaneseCalendar.MEIJI,
                            Calendar.YEAR, 1 };
        checkExpected(c, expectedB);

    }

    
    public void TestJapaneseYear3282() {
        Calendar c = Calendar.getInstance(ULocale.ENGLISH);
        c.set(2003,Calendar.SEPTEMBER,25);
        JapaneseCalendar jcal = new JapaneseCalendar();
        //jcal.setTime(new Date(1187906308151L));  alternate value
        jcal.setTime(c.getTime());
        logln("Now is: " + jcal.getTime());
        c.setTime(jcal.getTime());
        int nowYear = c.get(Calendar.YEAR);
        logln("Now year: "+nowYear);
        SimpleDateFormat jdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance(jcal,
                SimpleDateFormat.DEFAULT, Locale.getDefault());
        jdf.applyPattern("G yy/MM/dd");
        String text = jdf.format(jcal.getTime());
        logln("Now is: " + text + " (in Japan)");
        try {
            Date date = jdf.parse(text);
            logln("But is this not the date?: " + date);
            c.setTime(date);
            int thenYear = c.get(Calendar.YEAR);
            logln("Then year: "+thenYear);
            if(thenYear != nowYear) {
                errln("Nowyear "+nowYear +" is not thenyear "+thenYear);
            } else {
                logln("Nowyear "+nowYear +" == thenyear "+thenYear);
            }
        } catch (java.text.ParseException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Test limits of the Japanese calendar
     */
    public void TestLimits() {
        Calendar cal = Calendar.getInstance();
        cal.set(1988, Calendar.DECEMBER, 1);
        JapaneseCalendar jcal = new JapaneseCalendar();
        doLimitsTest(jcal, null, cal.getTime());
        doTheoreticalLimitsTest(jcal, true);
    }
}

