/*
 *******************************************************************************
 * Copyright (C) 2005-2007, 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.util.Calendar;
import com.ibm.icu.util.IndianCalendar;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;

/**
 * Tests for the <code>IndianCalendar</code> class.
 */
public class IndianTest extends CalendarTest 
{
    public static void main(String args[]) throws Exception {
        new IndianTest().run(args);
    }
    // Months in indian calendar are 0-based. Here taking 1-based names:
    public static final int CHAITRA = IndianCalendar.CHAITRA + 1; 
    public static final int VAISAKHA = IndianCalendar.VAISAKHA + 1;
    public static final int JYAISTHA = IndianCalendar.JYAISTHA + 1;
    public static final int ASADHA = IndianCalendar.ASADHA + 1;
    public static final int SRAVANA = IndianCalendar.SRAVANA + 1 ;
    public static final int BHADRA = IndianCalendar.BHADRA + 1 ;
    public static final int  ASVINA = IndianCalendar.ASVINA  + 1 ;
    public static final int KARTIKA = IndianCalendar.KARTIKA + 1 ;
    public static final int AGRAHAYANA = IndianCalendar.AGRAHAYANA + 1 ;
    public static final int PAUSA = IndianCalendar.PAUSA + 1 ;
    public static final int MAGHA = IndianCalendar.MAGHA + 1 ;
    public static final int PHALGUNA = IndianCalendar.PHALGUNA + 1 ;

    /** Constants to save typing. */
    /* Test dates generated from:
     * http://www.fourmilab.ch/documents/calendar/ 
    
    /** A huge list of test cases to make sure that computeTime and computeFields
     * work properly for a wide range of data in the Indian 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.
            //                      Indian
            //          Julian Day  Era  Year   Month Day    WkDay Hour Min Sec
           new TestCase(1770641.5,  0,    57,    ASVINA,       10,  SUN,   0,  0,  0),
           new TestCase(1892731.5,  0,   391,    PAUSA,        18,  WED,   0,  0,  0),
           new TestCase(1931579.5,  0,   498,    VAISAKHA,     30,  MON,   0,  0,  0),
           new TestCase(1974851.5,  0,   616,    KARTIKA,      19,  SAT,   0,  0,  0),
           new TestCase(2091164.5,  0,   935,    VAISAKHA,      5,  SUN,   0,  0,  0),
           new TestCase(2121509.5,  0,  1018,    JYAISTHA,      3,  SUN,   0,  0,  0),
           new TestCase(2155779.5,  0,  1112,    CHAITRA,       2,  FRI,   0,  0,  0),
           new TestCase(2174029.5,  0,  1161,    PHALGUNA,     20,  SAT,   0,  0,  0),
           new TestCase(2191584.5,  0,  1210,    CHAITRA,      13,  FRI,   0,  0,  0),
           new TestCase(2195261.5,  0,  1220,    VAISAKHA,      7,  SUN,   0,  0,  0),
           new TestCase(2229274.5,  0,  1313,    JYAISTHA,     22,  SUN,   0,  0,  0),
           new TestCase(2245580.5,  0,  1357,    MAGHA,        14,  WED,   0,  0,  0),
           new TestCase(2266100.5,  0,  1414,    CHAITRA,      20,  SAT,   0,  0,  0),
           new TestCase(2288542.5,  0,  1475,    BHADRA,       28,  SAT,   0,  0,  0),
           new TestCase(2290901.5,  0,  1481,    PHALGUNA,     15,  SAT,   0,  0,  0),
           new TestCase(2323140.5,  0,  1570,    JYAISTHA,     20,  WED,   0,  0,  0),
           new TestCase(2334551.5,  0,  1601,    BHADRA,       16,  THU,   0,  0,  0),
           new TestCase(2334581.5,  0,  1601,    ASVINA,       15,  SAT,   0,  0,  0),
           new TestCase(2334610.5,  0,  1601,    KARTIKA,      14,  SUN,   0,  0,  0),
           new TestCase(2334639.5,  0,  1601,    AGRAHAYANA,   13,  MON,   0,  0,  0),
           new TestCase(2334668.5,  0,  1601,    PAUSA,        12,  TUE,   0,  0,  0),
           new TestCase(2334698.5,  0,  1601,    MAGHA,        12,  THU,   0,  0,  0),
           new TestCase(2334728.5,  0,  1601,    PHALGUNA,     12,  SAT,   0,  0,  0),
           new TestCase(2334757.5,  0,  1602,    CHAITRA,      11,  SUN,   0,  0,  0),
           new TestCase(2334787.5,  0,  1602,    VAISAKHA,     10,  TUE,   0,  0,  0),
           new TestCase(2334816.5,  0,  1602,    JYAISTHA,      8,  WED,   0,  0,  0),
           new TestCase(2334846.5,  0,  1602,    ASADHA,        7,  FRI,   0,  0,  0),
           new TestCase(2334848.5,  0,  1602,    ASADHA,        9,  SUN,   0,  0,  0),
           new TestCase(2348020.5,  0,  1638,    SRAVANA,       2,  FRI,   0,  0,  0),
           new TestCase(2334934.5,  0,  1602,    ASVINA,        2,  TUE,   0,  0,  0),
           new TestCase(2366978.5,  0,  1690,    JYAISTHA,     29,  SUN,   0,  0,  0),
           new TestCase(2385648.5,  0,  1741,    SRAVANA,      11,  MON,   0,  0,  0),
           new TestCase(2392825.5,  0,  1761,    CHAITRA,       6,  WED,   0,  0,  0),
           new TestCase(2416223.5,  0,  1825,    CHAITRA,      29,  SUN,   0,  0,  0),
           new TestCase(2425848.5,  0,  1851,    BHADRA,        3,  SUN,   0,  0,  0),
           new TestCase(2430266.5,  0,  1863,    ASVINA,        7,  MON,   0,  0,  0),
           new TestCase(2430833.5,  0,  1865,    CHAITRA,      29,  MON,   0,  0,  0),
           new TestCase(2431004.5,  0,  1865,    ASVINA,       15,  THU,   0,  0,  0),
           new TestCase(2448698.5,  0,  1913,    PHALGUNA,     27,  TUE,   0,  0,  0),
           new TestCase(2450138.5,  0,  1917,    PHALGUNA,      6,  SUN,   0,  0,  0),
           new TestCase(2465737.5,  0,  1960,    KARTIKA,      19,  WED,   0,  0,  0),
           new TestCase(2486076.5,  0,  2016,    ASADHA,       27,  SUN,   0,  0,  0),
        };
        
        IndianCalendar testCalendar = new IndianCalendar();
        testCalendar.setLenient(true);
        doTestCases(tests, testCalendar);
    }

    public void TestBasic() {
        IndianCalendar cal = new IndianCalendar();
        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 TestCoverage() {

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

        {
            // new IndianCalendar(ULocale)
            IndianCalendar cal = new IndianCalendar(ULocale.getDefault());
            if(cal == null){
                errln("could not create IndianCalendar with ULocale");
            }
        }
        
        {
            // new IndianCalendar(Locale)
            IndianCalendar cal = new IndianCalendar(Locale.getDefault());
            if(cal == null){
                errln("could not create IndianCalendar with Locale");
            }
        }
        
        {                                                                                       
            // new IndianCalendar(TimeZone, Locale)                                             
            IndianCalendar cal = new IndianCalendar(TimeZone.getDefault(),Locale.getDefault()); 
            if(cal == null){                                                                    
                errln("could not create IndianCalendar with TimeZone, Locale");                 
            }                                                                                   
        }                                                                                       
                                                                                                
        {                                                                                       
            // new IndianCalendar(TimeZone, ULocale)                                            
            IndianCalendar cal = new IndianCalendar(TimeZone.getDefault(),ULocale.getDefault());
            if(cal == null){                                                                    
                errln("could not create IndianCalendar with TimeZone, ULocale");                
            }                                                                                   
        }                                                                                       
        
        {
            // new IndianCalendar(Date)
            IndianCalendar cal = new IndianCalendar(new Date());
            if(cal == null){
                errln("could not create IndianCalendar with Date");
            }
        }
        {
            // new IndianCalendar(int year, int month, int date)
            IndianCalendar cal = new IndianCalendar(1917, IndianCalendar.CHAITRA, 1);
            if(cal == null){
                errln("could not create IndianCalendar with year,month,date");
            }
        }
        {
            // new IndianCalendar(int year, int month, int date, int hour, int minute, int second)
            IndianCalendar cal = new IndianCalendar(1917, IndianCalendar.CHAITRA, 1, 1, 1, 1);
            if(cal == null){
                errln("could not create IndianCalendar with year,month,date,hour,minute,second");
            }
        }
    
        {
            // data
            IndianCalendar cal = new IndianCalendar(-1039, 9, 21);
            String[] calendarLocales = {
                "bn_IN", "gu_IN", "hi_IN", "kn_IN", "ml_IN", "or_IN", "pa_IN", "ta_IN", "te_IN"
            };

            String[] formatLocales = {
                "en", "fr", "bn", "gu", "hi", "kn", "ml", "or", "pa", "ta", "te"
            };

            for (int i = 0; i < calendarLocales.length; ++i) {
                String calLocName = calendarLocales[i];
                Locale calLocale = LocaleUtility.getLocaleFromName(calLocName);
                cal = new IndianCalendar(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 TestYear() {
        // Gregorian Calendar
        Calendar gCal= new GregorianCalendar();
        Date gToday=gCal.getTime();
        gCal.add(GregorianCalendar.MONTH,2);
        Date gFuture=gCal.getTime();
        DateFormat gDF = DateFormat.getDateInstance(gCal,DateFormat.FULL);
        logln("gregorian calendar: " + gDF.format(gToday) +
              " + 2 months = " + gDF.format(gFuture));

        // Indian Calendar
        IndianCalendar iCal= new IndianCalendar();
        Date iToday=iCal.getTime();
        iCal.add(IndianCalendar.MONTH,2);
        Date iFuture=iCal.getTime();
        DateFormat iDF = DateFormat.getDateInstance(iCal,DateFormat.FULL);
        logln("Indian calendar: " + iDF.format(iToday) +
              " + 2 months = " + iDF.format(iFuture));

    }
}
