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

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.EthiopicCalendar;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;

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

    /** Constants to save typing. */
    public static final int MESKEREM = EthiopicCalendar.MESKEREM;
    public static final int TEKEMT   = EthiopicCalendar.TEKEMT;
    public static final int HEDAR    = EthiopicCalendar.HEDAR;
    public static final int TAHSAS   = EthiopicCalendar.TAHSAS;
    public static final int TER      = EthiopicCalendar.TER;
    public static final int YEKATIT  = EthiopicCalendar.YEKATIT;
    public static final int MEGABIT  = EthiopicCalendar.MEGABIT;
    public static final int MIAZIA   = EthiopicCalendar.MIAZIA;
    public static final int GENBOT   = EthiopicCalendar.GENBOT;
    public static final int SENE     = EthiopicCalendar.SENE;
    public static final int HAMLE    = EthiopicCalendar.HAMLE;
    public static final int NEHASSE  = EthiopicCalendar.NEHASSE;
    public static final int PAGUMEN  = EthiopicCalendar.PAGUMEN;

    /* DY[20050507]  I don't know what this is for yet: 
       public void TestRoll() {
       int[][] tests = new int[][] {
       //       input                roll by          output
       //  year  month     day     field amount    year  month     day
    
       {   0001, QIDAH,     2,     MONTH,   1,     0001, HIJJAH,    2 },   // non-leap years
       {   0001, QIDAH,     2,     MONTH,   2,     0001, MUHARRAM,  2 },
       {   0001, QIDAH,     2,     MONTH,  -1,     0001, SHAWWAL,   2 },
       {   0001, MUHARRAM,  2,     MONTH,  12,     0001, MUHARRAM,  2 },
       {   0001, MUHARRAM,  2,     MONTH,  13,     0001, SAFAR,     2 },

       {   0001, HIJJAH,    1,     DATE,   30,     0001, HIJJAH,    2 },   // 29-day month
       {   0002, HIJJAH,    1,     DATE,   31,     0002, HIJJAH,    2 },   // 30-day month

       // Try some rolls that require other fields to be adjusted
       {   0001, MUHARRAM, 30,     MONTH,   1,     0001, SAFAR,    29 },
       {   0002, HIJJAH,   30,     YEAR,   -1,     0001, HIJJAH,   29 },
       };
       
       EthiopicCalendar cal = newCivil();

       doRollAdd(ROLL, cal, tests);
       }
    */

    /* Test dates from:
     * "The Amharic Letters of Emperor Theodore of Ethiopia to Queen Victoria and
     * Her Special Envoy", David Appleyard, Girma Selasse Asfaw, Oxford University Press, 
     * June 1 1979, ISBN: 0856726605, Longwood Pr Ltd
     *  
     * Ethiopic       Gregorian    JD
     * 20/02/1855     29/10/1862  2401443
     * 29/10/1857     05/07/1865  2402423
     * 22/05/1858     29/01/1866  2402631
     * 10/08/1858     17/04/1866  2402709
     * 28/04/1859     05/01/1867  2402972
     * 05/05/1860     13/01/1868  2403345
     * 
     * --------------------------------------------------
     * 
     * From the Calendrica applet:  http://emr.cs.iit.edu/home/reingold/calendar-book/Calendrica.html
     * 
     * Ethiopic       Gregorian    JD
     * 07/05/-8       01/01/0000  1721060
     * 08/05/-7       01/01/0001  1721426
     * 06/13/-1       27/08/0007  1723855
     * 
     * 01/01/0000     28/08/0007  1723856
     * 01/01/0001     27/08/0008  1724221
     * 01/01/0002     27/08/0009  1724586
     * 01/01/0003     27/08/0010  1724951
     * 01/01/0004     28/08/0011  1724537
     * 05/13/0000     26/08/0008  1724220
     * 05/13/0001     26/08/0009  1724585
     * 05/13/0002     26/08/0010  1724950
     * 05/13/0003     26/08/0011  1725315
     * 06/13/0003     27/08/0011  1725316  first ethiopian leap year
     * 05/13/0004     26/08/0012  1725561
     * 
     * 06/02/1575     13/10/1582  2299159
     * 07/02/1575     14/10/1582  2299160  Julian 04/10/1582
     * 08/02/1575     15/10/1582  2299161
     * 09/02/1575     16/10/1582  2299162
     * 
     * 23/04/1892     01/01/1900  2415021
     * 23/04/1997     01/01/2005  2453372
     * 05/13/2000     10/09/2008  2454720
     */
    
    /** A huge list of test cases to make sure that computeTime and computeFields
     * work properly for a wide range of data in the civil calendar.
     */
    public void TestCases()
    {
        final TestCase[] tests = {
            //
            // The months in this table are 1-based rather than 0-based,
            // because it's easier to edit that way.
            //                      Ethiopic
            //          Julian Day  Era  Year  Month Day  WkDay Hour Min Sec
            //
            // Dates from "Emporer Theodore..."

            new TestCase(2401442.5,  1,  1855,    2,  20,  WED,   0,  0,  0), // Gregorian: 29/10/1862
            new TestCase(2402422.5,  1,  1857,   10,  29,  WED,   0,  0,  0), // Gregorian: 05/07/1865
            new TestCase(2402630.5,  1,  1858,    5,  22,  MON,   0,  0,  0), // Gregorian: 29/01/1866
            new TestCase(2402708.5,  1,  1858,    8,  10,  TUE,   0,  0,  0), // Gregorian: 17/04/1866
            new TestCase(2402971.5,  1,  1859,    4,  28,  SAT,   0,  0,  0), // Gregorian: 05/01/1867
            new TestCase(2403344.5,  1,  1860,    5,   5,  MON,   0,  0,  0), // Gregorian: 13/01/1868
                        
            // Miscellaneous:
            /* Skip these tests until JD bug fixed in the Gregorian calendar:
             * http://www.jtcsv.com/cgibin/icu-bugs/incoming?id=4406;page=2;user=guest
             */
            new TestCase(1721059.5,  0,     9,    5,   7,  SAT,   0,  0,  0), // Gregorian: 01/01/0000
            new TestCase(1721425.5,  0,     8,    5,   8,  MON,   0,  0,  0), // Gregorian: 01/01/0001
            new TestCase(1723854.5,  0,     2,   13,   6,  MON,   0,  0,  0), // Gregorian: 27/08/0007

            new TestCase(1723855.5,  0,     1,    1,   1,  TUE,   0,  0,  0), // Gregorian: 28/08/0007
            new TestCase(1724220.5,  1,     1,    1,   1,  WED,   0,  0,  0), // Gregorian: 27/08/0008
            new TestCase(1724585.5,  1,     2,    1,   1,  THU,   0,  0,  0), // Gregorian: 27/08/0009
            new TestCase(1724950.5,  1,     3,    1,   1,  FRI,   0,  0,  0), // Gregorian: 27/08/0010

            // new TestCase(1724536.5,  1,     4,    1,   1,  SUN,   0,  0,  0), // Gregorian: 28/08/0011
            new TestCase(1725316.5,  1,     4,    1,   1,  SUN,   0,  0,  0), // Gregorian: 28/08/0011 - dlf
            new TestCase(1724219.5,  0,     1,   13,   5,  TUE,   0,  0,  0), // Gregorian: 26/08/0008
            new TestCase(1724584.5,  1,     1,   13,   5,  WED,   0,  0,  0), // Gregorian: 26/08/0009
            new TestCase(1724949.5,  1,     2,   13,   5,  THU,   0,  0,  0), // Gregorian: 26/08/0010
            new TestCase(1725314.5,  1,     3,   13,   5,  FRI,   0,  0,  0), // Gregorian: 26/08/0011
            new TestCase(1725315.5,  1,     3,   13,   6,  SAT,   0,  0,  0), // Gregorian: 27/08/0011 - first ethiopic leap year
            // new TestCase(1725560.5,  1,     4,   13,   5,  SUN,   0,  0,  0), // Gregorian: 26/08/0012 - dlf
            new TestCase(1725680.5,  1,     4,   13,   5,  SUN,   0,  0,  0), // Gregorian: 26/08/0012
            new TestCase(2299158.5,  1,  1575,    2,   6,  WED,   0,  0,  0), // Gregorian: 13/10/1582  
            new TestCase(2299159.5,  1,  1575,    2,   7,  THU,   0,  0,  0), // Gregorian: 14/10/1582  Julian 04/10/1582

            new TestCase(2299160.5,  1,  1575,    2,   8,  FRI,   0,  0,  0), // Gregorian: 15/10/1582
            new TestCase(2299161.5,  1,  1575,    2,   9,  SAT,   0,  0,  0), // Gregorian: 16/10/1582

            new TestCase(2415020.5,  1,  1892,    4,  23,  MON,   0,  0,  0), // Gregorian: 01/01/1900
            new TestCase(2453371.5,  1,  1997,    4,  23,  SAT,   0,  0,  0), // Gregorian: 01/01/2005
            new TestCase(2454719.5,  1,  2000,   13,   5,  WED,   0,  0,  0), // Gregorian: 10/09/2008
        };

        EthiopicCalendar testCalendar = new EthiopicCalendar();
        testCalendar.setLenient(true);
        doTestCases(tests, testCalendar);
    }

    // basic check to see that we print out eras ok
    // eventually should modify to use locale strings and formatter appropriate to coptic calendar
    public void TestEraStart() {
        SimpleDateFormat fmt = new SimpleDateFormat("EEE MMM dd, yyyy GG");
        EthiopicCalendar cal = new EthiopicCalendar(1, 0, 1);
        assertEquals("Ethiopic Date", "Wed Jan 01, 0001 AD", fmt.format(cal));
        cal.set(Calendar.ERA, 0);
        cal.set(Calendar.YEAR, 1);
        assertEquals("Ethiopic Date", "Tue Jan 01, 0001 BC", fmt.format(cal));

        // The gregorian calendar gets off by two days when
        // the date gets low, unless the gregorian changeover is set to 
        // very early.  The funny thing is, it's ok for dates in the year
        // 283, but not in the year 7, and it claims to be ok until the year 4.
        // should track down when the dates start to differ...
        
        GregorianCalendar gc = new GregorianCalendar();
        gc.setGregorianChange(new Date(Long.MIN_VALUE)); // act like proleptic Gregorian
        gc.setTime(cal.getTime());
        assertEquals("Gregorian Date", "Tue Aug 28, 0007 AD", fmt.format(gc));
    }

    public void TestBasic() {
        EthiopicCalendar cal = new EthiopicCalendar();
        cal.clear();
        cal.set(1000, 0, 30);
        logln("1000/0/30-> " +
              cal.get(YEAR) + "/" +
              cal.get(MONTH) + "/" + 
              cal.get(DATE));
        cal.clear();
        cal.set(1, 0, 30);
        logln("1/0/30 -> " +
              cal.get(YEAR) + "/" +
              cal.get(MONTH) + "/" + 
              cal.get(DATE));
    }
    
    public void TestJD(){
        int jd = EthiopicCalendar.EthiopicToJD(1567,8,9);
        Integer[] l = EthiopicCalendar.getDateFromJD(jd);
        if (l[0].intValue() == 1567 &&
            l[1].intValue() == 8 &&
            l[2].intValue() == 9){
            logln("EthiopicCalendar.getDateFromJD tested");
        } else {
            errln("EthiopicCalendar.getDateFromJD failed");
        }
    }

    /**
     * Test limits of the Coptic calendar
     */
    public void TestLimits() {
        Calendar cal = Calendar.getInstance();
        cal.set(2007, Calendar.JANUARY, 1);
        EthiopicCalendar ethiopic = new EthiopicCalendar();
        doLimitsTest(ethiopic, null, cal.getTime());
        doTheoreticalLimitsTest(ethiopic, true);
    }

    
    public void TestCoverage() {

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

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

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

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

        {
            // new EthiopicCalendar(int year, int month, int date)
            EthiopicCalendar cal = new EthiopicCalendar(1997, EthiopicCalendar.MESKEREM, 1);
            if(cal == null){
                errln("could not create EthiopicCalendar with year,month,date");
            }
        }

        {
            // new EthiopicCalendar(int year, int month, int date, int hour, int minute, int second)
            EthiopicCalendar cal = new EthiopicCalendar(1997, EthiopicCalendar.MESKEREM, 1, 1, 1, 1);
            if(cal == null){
                errln("could not create EthiopicCalendar with year,month,date,hour,minute,second");
            }
        }

        {
            // setCivil/isCivil
            // operations on non-civil calendar
            EthiopicCalendar cal = newAmeteAlemEraCalendar();
            cal.setAmeteAlemEra(false);
            if (cal.isAmeteAlemEra()) {
                errln("EthiopicCalendar calendar is old system");
            }

            Date now = new Date();
            cal.setTime(now);

            Date then = cal.getTime();
            if (!now.equals(then)) {
                errln("get/set time failed with non-civil EthiopicCalendar calendar");
            }

            logln(then.toString());

            cal.add(Calendar.MONTH, 1);
            cal.add(Calendar.DAY_OF_MONTH, 1);
            cal.add(Calendar.YEAR, 1);

            logln(cal.getTime().toString());
        }
    
        {
            // data
            EthiopicCalendar cal = new EthiopicCalendar(1997, EthiopicCalendar.MESKEREM, 1);
            Date time = cal.getTime();

            String[] calendarLocales = {
                "am_ET", "gez_ET", "ti_ET"
            };

            String[] formatLocales = {
                "en", "am", "gez", "ti"
            };
            for (int i = 0; i < calendarLocales.length; ++i) {
                String calLocName = calendarLocales[i];
                Locale calLocale = LocaleUtility.getLocaleFromName(calLocName);
                cal = new EthiopicCalendar(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));
                }
            }
        }
    }
    
    private static EthiopicCalendar newAmeteAlemEraCalendar() {
        EthiopicCalendar alemawiCalendar = new EthiopicCalendar();
        alemawiCalendar.setAmeteAlemEra(true);
        return alemawiCalendar;
    }
}
