/***********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 1997-2004, International Business Machines Corporation
 * and others. All Rights Reserved.
 ***********************************************************************/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "dtfmapts.h"

#include "unicode/datefmt.h"
#include "unicode/smpdtfmt.h"
#include "unicode/decimfmt.h"
#include "unicode/choicfmt.h"
#include "unicode/msgfmt.h"


// This is an API test, not a unit test.  It doesn't test very many cases, and doesn't
// try to test the full functionality.  It just calls each function in the class and
// verifies that it works on a basic level.

void IntlTestDateFormatAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    if (exec) logln("TestSuite DateFormatAPI");
    switch (index) {
        case 0: name = "DateFormat API test"; 
                if (exec) {
                    logln("DateFormat API test---"); logln("");
                    UErrorCode status = U_ZERO_ERROR;
                    Locale::setDefault(Locale::getEnglish(), status);
                    if(U_FAILURE(status)) {
                        errln("ERROR: Could not set default locale, test may not give correct results");
                    }
                    testAPI(/*par*/);
                }
                break;

        case 1: name = "TestEquals"; 
                if (exec) {
                    logln("TestEquals---"); logln("");
                    TestEquals();
                }
                break;

        case 2: name = "TestNameHiding"; 
                if (exec) {
                    logln("TestNameHiding---"); logln("");
                    TestNameHiding();
                }
                break;

        default: name = ""; break;
    }
}

/**
 * Test that the equals method works correctly.
 */
void IntlTestDateFormatAPI::TestEquals(void)
{
    UErrorCode status = U_ZERO_ERROR;
    // Create two objects at different system times
    DateFormat *a = DateFormat::createInstance();
    UDate start = Calendar::getNow();
    while (Calendar::getNow() == start) ; // Wait for time to change
    DateFormat *b = DateFormat::createInstance();

    if (!(*a == *b))
        errln("FAIL: DateFormat objects created at different times are unequal.");

    if (b->getDynamicClassID() == SimpleDateFormat::getStaticClassID())
    {
        double ONE_YEAR = 365*24*60*60*1000.0;
        ((SimpleDateFormat*)b)->set2DigitYearStart(start + 50*ONE_YEAR, status);
        if (U_FAILURE(status))
            errln("FAIL: setTwoDigitStartDate failed.");
        else if (*a == *b)
            errln("FAIL: DateFormat objects with different two digit start dates are equal.");
    }
    delete a;
    delete b;
}

/**
 * This test checks various generic API methods in DateFormat to achieve 100%
 * API coverage.
 */
void IntlTestDateFormatAPI::testAPI(/* char* par */)
{
    UErrorCode status = U_ZERO_ERROR;

// ======= Test constructors

    logln("Testing DateFormat constructors");

    DateFormat *def = DateFormat::createInstance();
    DateFormat *fr = DateFormat::createTimeInstance(DateFormat::FULL, Locale::getFrench());
    DateFormat *it = DateFormat::createDateInstance(DateFormat::MEDIUM, Locale::getItalian());
    DateFormat *de = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG, Locale::getGerman());

// ======= Test equality

    logln("Testing equality operator");
    
    if( *fr == *it ) {
        errln("ERROR: == failed");
    }

// ======= Test various format() methods

    logln("Testing various format() methods");

    UDate d = 837039928046.0;
    Formattable fD(d, Formattable::kIsDate);

    UnicodeString res1, res2, res3;
    FieldPosition pos1(0), pos2(0);
    
    status = U_ZERO_ERROR;
    res1 = fr->format(d, res1, pos1, status);
    if(U_FAILURE(status)) {
        errln("ERROR: format() failed (French)");
    }
    logln( (UnicodeString) "" + d + " formatted to " + res1);

    res2 = it->format(d, res2, pos2);
    logln( (UnicodeString) "" + d + " formatted to " + res2);

    res3 = de->format(d, res3);
    logln( (UnicodeString) "" + d + " formatted to " + res3);

// ======= Test parse()

    logln("Testing parse()");

    UnicodeString text("02/03/76 2:50 AM, CST");
    Formattable result1;
    UDate result2, result3;
    ParsePosition pos(0), pos01(0);
    def->parseObject(text, result1, pos);
    if(result1.getType() != Formattable::kDate) {
        errln("ERROR: parseObject() failed for " + text);
    }
    logln(text + " parsed into " + result1.getDate());

    status = U_ZERO_ERROR;
    result2 = def->parse(text, status);
    if(U_FAILURE(status)) {
        errln("ERROR: parse() failed, stopping testing");
        return;
    }
    logln(text + " parsed into " + result2);

    result3 = def->parse(text, pos01);
    logln(text + " parsed into " + result3);


// ======= Test getters and setters

    logln("Testing getters and setters");

    int32_t count = 0;
    const Locale *locales = DateFormat::getAvailableLocales(count);
    logln((UnicodeString) "Got " + count + " locales" );
    for(int32_t i = 0; i < count; i++) {
        UnicodeString name;
        name = locales[i].getName();
        logln(name);
    }

    fr->setLenient(it->isLenient());
    if(fr->isLenient() != it->isLenient()) {
        errln("ERROR: setLenient() failed");
    }

    const Calendar *cal = def->getCalendar();
    Calendar *newCal = cal->clone();
    de->adoptCalendar(newCal);  
    it->setCalendar(*newCal);
    if( *(de->getCalendar()) != *(it->getCalendar())) {
        errln("ERROR: adopt or set Calendar() failed");
    }

    const NumberFormat *nf = def->getNumberFormat();
    NumberFormat *newNf = (NumberFormat*) nf->clone();
    de->adoptNumberFormat(newNf);   
    it->setNumberFormat(*newNf);
    if( *(de->getNumberFormat()) != *(it->getNumberFormat())) {
        errln("ERROR: adopt or set NumberFormat() failed");
    }

    const TimeZone& tz = def->getTimeZone();
    TimeZone *newTz = tz.clone();
    de->adoptTimeZone(newTz);   
    it->setTimeZone(*newTz);
    if( de->getTimeZone() != it->getTimeZone()) {
        errln("ERROR: adopt or set TimeZone() failed");
    }

// ======= Test getStaticClassID()

    logln("Testing getStaticClassID()");

    status = U_ZERO_ERROR;
    DateFormat *test = new SimpleDateFormat(status);
    if(U_FAILURE(status)) {
        errln("ERROR: Couldn't create a DateFormat");
    }

    if(test->getDynamicClassID() != SimpleDateFormat::getStaticClassID()) {
        errln("ERROR: getDynamicClassID() didn't return the expected value");
    }

    delete test;
    delete def;
    delete fr;
    delete it;
    delete de;
}

/**
 * Test hiding of parse() and format() APIs in the Format hierarchy.
 * We test the entire hierarchy, even though this test is located in
 * the DateFormat API test.
 */
void
IntlTestDateFormatAPI::TestNameHiding(void) {

    // N.B.: This test passes if it COMPILES, since it's a test of
    // compile-time name hiding.

    UErrorCode status = U_ZERO_ERROR;
    Formattable dateObj(0, Formattable::kIsDate);
    Formattable numObj(3.1415926535897932384626433832795);
    Formattable obj;
    UnicodeString str;
    FieldPosition fpos;
    ParsePosition ppos;

    // DateFormat calling Format API
    {
        logln("DateFormat");
        DateFormat *dateFmt = DateFormat::createInstance();
        if (dateFmt) {
            dateFmt->format(dateObj, str, status);
            dateFmt->format(dateObj, str, fpos, status);
            delete dateFmt;
        } else {
            errln("FAIL: Can't create DateFormat");
        }
    }

    // SimpleDateFormat calling Format & DateFormat API
    {
        logln("SimpleDateFormat");
        status = U_ZERO_ERROR;
        SimpleDateFormat sdf(status);
        // Format API
        sdf.format(dateObj, str, status);
        sdf.format(dateObj, str, fpos, status);
        // DateFormat API
        sdf.format((UDate)0, str, fpos);
        sdf.format((UDate)0, str);
        sdf.parse(str, status);
        sdf.parse(str, ppos);
    }

    // NumberFormat calling Format API
    {
        logln("NumberFormat");
        status = U_ZERO_ERROR;
        NumberFormat *fmt = NumberFormat::createInstance(status);
        if (fmt) {
            fmt->format(numObj, str, status);
            fmt->format(numObj, str, fpos, status);
            delete fmt;
        } else {
            errln("FAIL: Can't create NumberFormat()");
        }
    }

    // DecimalFormat calling Format & NumberFormat API
    {
        logln("DecimalFormat");
        status = U_ZERO_ERROR;
        DecimalFormat fmt(status);
        if(U_SUCCESS(status)) {
          // Format API
          fmt.format(numObj, str, status);
          fmt.format(numObj, str, fpos, status);
          // NumberFormat API
          fmt.format(2.71828, str);
          fmt.format((int32_t)1234567, str);
          fmt.format(1.41421, str, fpos);
          fmt.format((int32_t)9876543, str, fpos);
          fmt.parse(str, obj, ppos);
          fmt.parse(str, obj, status);
        } else {
          errln("FAIL: Couldn't instantiate DecimalFormat, error %s. Quitting test", u_errorName(status));
        }
    }

    // ChoiceFormat calling Format & NumberFormat API
    {
        logln("ChoiceFormat");
        status = U_ZERO_ERROR;
        ChoiceFormat fmt("0#foo|1#foos|2#foos", status);
        // Format API
        fmt.format(numObj, str, status);
        fmt.format(numObj, str, fpos, status);
        // NumberFormat API
        fmt.format(2.71828, str);
        fmt.format((int32_t)1234567, str);
        fmt.format(1.41421, str, fpos);
        fmt.format((int32_t)9876543, str, fpos);
        fmt.parse(str, obj, ppos);
        fmt.parse(str, obj, status);
    }

    // MessageFormat calling Format API
    {
        logln("MessageFormat");
        status = U_ZERO_ERROR;
        MessageFormat fmt("", status);
        // Format API
        // We use dateObj, which MessageFormat should reject.
        // We're testing name hiding, not the format method.
        fmt.format(dateObj, str, status);
        fmt.format(dateObj, str, fpos, status);
    }
}

#endif /* #if !UCONFIG_NO_FORMATTING */
