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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "dcfmapts.h"

#include "unicode/decimfmt.h"
#include "unicode/dcfmtsym.h"
#include "unicode/parseerr.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 IntlTestDecimalFormatAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    if (exec) logln((UnicodeString)"TestSuite DecimalFormatAPI");
    switch (index) {
        case 0: name = "DecimalFormat API test"; 
                if (exec) {
                    logln((UnicodeString)"DecimalFormat API test---"); logln((UnicodeString)"");
                    UErrorCode status = U_ZERO_ERROR;
                    Locale::setDefault(Locale::getEnglish(), status);
                    if(U_FAILURE(status)) {
                        errln((UnicodeString)"ERROR: Could not set default locale, test may not give correct results");
                    }
                    testAPI(/*par*/);
                }
                break;
        case 1: name = "Rounding test";
            if(exec) {
               logln((UnicodeString)"DecimalFormat Rounding test---");
               testRounding(/*par*/);
            }
            break;

        default: name = ""; break;
    }
}

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

// ======= Test constructors

    logln((UnicodeString)"Testing DecimalFormat constructors");

    DecimalFormat def(status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: Could not create DecimalFormat (default)");
        return;
    }

    status = U_ZERO_ERROR;
    const UnicodeString pattern("#,##0.# FF");
    DecimalFormat pat(pattern, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern)");
        return;
    }

    status = U_ZERO_ERROR;
    DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getFrench(), status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (French)");
        return;
    }

    status = U_ZERO_ERROR;
    DecimalFormat cust1(pattern, symbols, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
    }

    status = U_ZERO_ERROR;
    DecimalFormat cust2(pattern, *symbols, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols)");
    }

    DecimalFormat copy(pat);

// ======= Test clone(), assignment, and equality

    logln((UnicodeString)"Testing clone(), assignment and equality operators");

    if( ! (copy == pat) || copy != pat) {
        errln((UnicodeString)"ERROR: Copy constructor or == failed");
    }

    copy = cust1;
    if(copy != cust1) {
        errln((UnicodeString)"ERROR: Assignment (or !=) failed");
    }

    Format *clone = def.clone();
    if( ! (*clone == def) ) {
        errln((UnicodeString)"ERROR: Clone() failed");
    }
    delete clone;

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

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

    double d = -10456.0037;
    int32_t l = 100000000;
    Formattable fD(d);
    Formattable fL(l);

    UnicodeString res1, res2, res3, res4;
    FieldPosition pos1(0), pos2(0), pos3(0), pos4(0);
    
    res1 = def.format(d, res1, pos1);
    logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1);

    res2 = pat.format(l, res2, pos2);
    logln((UnicodeString) "" + (int32_t) l + " formatted to " + res2);

    status = U_ZERO_ERROR;
    res3 = cust1.format(fD, res3, pos3, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: format(Formattable [double]) failed");
    }
    logln((UnicodeString) "" + (int32_t) fD.getDouble() + " formatted to " + res3);

    status = U_ZERO_ERROR;
    res4 = cust2.format(fL, res4, pos4, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: format(Formattable [long]) failed");
    }
    logln((UnicodeString) "" + fL.getLong() + " formatted to " + res4);

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

    logln((UnicodeString)"Testing parse()");

    UnicodeString text("-10,456.0037");
    Formattable result1, result2;
    ParsePosition pos(0);
    UnicodeString patt("#,##0.#");
    status = U_ZERO_ERROR;
    pat.applyPattern(patt, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: applyPattern() failed");
    }
    pat.parse(text, result1, pos);
    if(result1.getType() != Formattable::kDouble && result1.getDouble() != d) {
        errln((UnicodeString)"ERROR: Roundtrip failed (via parse()) for " + text);
    }
    logln(text + " parsed into " + (int32_t) result1.getDouble());

    status = U_ZERO_ERROR;
    pat.parse(text, result2, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: parse() failed");
    }
    if(result2.getType() != Formattable::kDouble && result2.getDouble() != d) {
        errln((UnicodeString)"ERROR: Roundtrip failed (via parse()) for " + text);
    }
    logln(text + " parsed into " + (int32_t) result2.getDouble());

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

    logln((UnicodeString)"Testing getters and setters");

    const DecimalFormatSymbols *syms = pat.getDecimalFormatSymbols();
    DecimalFormatSymbols *newSyms = new DecimalFormatSymbols(*syms);
    def.setDecimalFormatSymbols(*newSyms);
    def.adoptDecimalFormatSymbols(newSyms); // don't use newSyms after this
    if( *(pat.getDecimalFormatSymbols()) != *(def.getDecimalFormatSymbols())) {
        errln((UnicodeString)"ERROR: adopt or set DecimalFormatSymbols() failed");
    }

    UnicodeString posPrefix;
    pat.setPositivePrefix("+");
    posPrefix = pat.getPositivePrefix(posPrefix);
    logln((UnicodeString)"Positive prefix (should be +): " + posPrefix);
    if(posPrefix != "+") {
        errln((UnicodeString)"ERROR: setPositivePrefix() failed");
    }

    UnicodeString negPrefix;
    pat.setNegativePrefix("-");
    negPrefix = pat.getNegativePrefix(negPrefix);
    logln((UnicodeString)"Negative prefix (should be -): " + negPrefix);
    if(negPrefix != "-") {
        errln((UnicodeString)"ERROR: setNegativePrefix() failed");
    }

    UnicodeString posSuffix;
    pat.setPositiveSuffix("_");
    posSuffix = pat.getPositiveSuffix(posSuffix);
    logln((UnicodeString)"Positive suffix (should be _): " + posSuffix);
    if(posSuffix != "_") {
        errln((UnicodeString)"ERROR: setPositiveSuffix() failed");
    }

    UnicodeString negSuffix;
    pat.setNegativeSuffix("~");
    negSuffix = pat.getNegativeSuffix(negSuffix);
    logln((UnicodeString)"Negative suffix (should be ~): " + negSuffix);
    if(negSuffix != "~") {
        errln((UnicodeString)"ERROR: setNegativeSuffix() failed");
    }

    int32_t multiplier = 0;
    pat.setMultiplier(8);
    multiplier = pat.getMultiplier();
    logln((UnicodeString)"Multiplier (should be 8): " + multiplier);
    if(multiplier != 8) {
        errln((UnicodeString)"ERROR: setMultiplier() failed");
    }

    int32_t groupingSize = 0;
    pat.setGroupingSize(2);
    groupingSize = pat.getGroupingSize();
    logln((UnicodeString)"Grouping size (should be 2): " + (int32_t) groupingSize);
    if(groupingSize != 2) {
        errln((UnicodeString)"ERROR: setGroupingSize() failed");
    }

    pat.setDecimalSeparatorAlwaysShown(TRUE);
    UBool tf = pat.isDecimalSeparatorAlwaysShown();
    logln((UnicodeString)"DecimalSeparatorIsAlwaysShown (should be TRUE) is " + (UnicodeString) (tf ? "TRUE" : "FALSE"));
    if(tf != TRUE) {
        errln((UnicodeString)"ERROR: setDecimalSeparatorAlwaysShown() failed");
    }
    // Added by Ken Liu testing set/isExponentSignAlwaysShown
    pat.setExponentSignAlwaysShown(TRUE);
    UBool esas = pat.isExponentSignAlwaysShown();
    logln((UnicodeString)"ExponentSignAlwaysShown (should be TRUE) is " + (UnicodeString) (esas ? "TRUE" : "FALSE"));
    if(esas != TRUE) {
        errln((UnicodeString)"ERROR: ExponentSignAlwaysShown() failed");
    }

    // Added by Ken Liu testing set/isScientificNotation
    pat.setScientificNotation(TRUE);
    UBool sn = pat.isScientificNotation();
    logln((UnicodeString)"isScientificNotation (should be TRUE) is " + (UnicodeString) (sn ? "TRUE" : "FALSE"));
    if(sn != TRUE) {
        errln((UnicodeString)"ERROR: setScientificNotation() failed");
    }
    
    // Added by Ken Liu testing set/getMinimumExponentDigits
    int8_t MinimumExponentDigits = 0;
    pat.setMinimumExponentDigits(2);
    MinimumExponentDigits = pat.getMinimumExponentDigits();
    logln((UnicodeString)"MinimumExponentDigits (should be 2) is " + (int8_t) MinimumExponentDigits);
    if(MinimumExponentDigits != 2) {
        errln((UnicodeString)"ERROR: setMinimumExponentDigits() failed");
    }

    // Added by Ken Liu testing set/getRoundingIncrement
    double RoundingIncrement = 0.0;
    pat.setRoundingIncrement(2.0);
    RoundingIncrement = pat.getRoundingIncrement();
    logln((UnicodeString)"RoundingIncrement (should be 2.0) is " + (double) RoundingIncrement);
    if(RoundingIncrement != 2.0) {
        errln((UnicodeString)"ERROR: setRoundingIncrement() failed");
    }
    //end of Ken's Adding

    UnicodeString funkyPat;
    funkyPat = pat.toPattern(funkyPat);
    logln((UnicodeString)"Pattern is " + funkyPat);

    UnicodeString locPat;
    locPat = pat.toLocalizedPattern(locPat);
    logln((UnicodeString)"Localized pattern is " + locPat);

// ======= Test applyPattern()

    logln((UnicodeString)"Testing applyPattern()");

    UnicodeString p1("#,##0.0#;(#,##0.0#)");
    logln((UnicodeString)"Applying pattern " + p1);
    status = U_ZERO_ERROR;
    pat.applyPattern(p1, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: applyPattern() failed with " + (int32_t) status);
    }
    UnicodeString s2;
    s2 = pat.toPattern(s2);
    logln((UnicodeString)"Extracted pattern is " + s2);
    if(s2 != p1) {
        errln((UnicodeString)"ERROR: toPattern() result did not match pattern applied");
    }

    if(pat.getSecondaryGroupingSize() != 0) {
        errln("FAIL: Secondary Grouping Size should be 0, not %d\n", pat.getSecondaryGroupingSize());
    }

    if(pat.getGroupingSize() != 3) {
        errln("FAIL: Primary Grouping Size should be 3, not %d\n", pat.getGroupingSize());
    }

    UnicodeString p2("#,##,##0.0# FF;(#,##,##0.0# FF)");
    logln((UnicodeString)"Applying pattern " + p2);
    status = U_ZERO_ERROR;
    pat.applyLocalizedPattern(p2, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: applyPattern() failed with " + (int32_t) status);
    }
    UnicodeString s3;
    s3 = pat.toLocalizedPattern(s3);
    logln((UnicodeString)"Extracted pattern is " + s3);
    if(s3 != p2) {
        errln((UnicodeString)"ERROR: toLocalizedPattern() result did not match pattern applied");
    }

    status = U_ZERO_ERROR;
    UParseError pe;
    pat.applyLocalizedPattern(p2, pe, status);
    if(U_FAILURE(status)) {
        errln((UnicodeString)"ERROR: applyPattern((with ParseError)) failed with " + (int32_t) status);
    }
    UnicodeString s4;
    s4 = pat.toLocalizedPattern(s3);
    logln((UnicodeString)"Extracted pattern is " + s4);
    if(s4 != p2) {
        errln((UnicodeString)"ERROR: toLocalizedPattern(with ParseErr) result did not match pattern applied");
    }

    if(pat.getSecondaryGroupingSize() != 2) {
        errln("FAIL: Secondary Grouping Size should be 2, not %d\n", pat.getSecondaryGroupingSize());
    }

    if(pat.getGroupingSize() != 3) {
        errln("FAIL: Primary Grouping Size should be 3, not %d\n", pat.getGroupingSize());
    }

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

    logln((UnicodeString)"Testing getStaticClassID()");

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

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

    delete test;
}

void IntlTestDecimalFormatAPI::testRounding(/*char *par*/)
{
    UErrorCode status = U_ZERO_ERROR;
    double Roundingnumber = 2.55;
    double Roundingnumber1 = -2.55;
                      //+2.55 results   -2.55 results
    double result[]={   3.0,            -2.0,    //  kRoundCeiling  0,
                        2.0,            -3.0,    //  kRoundFloor    1,
                        2.0,            -2.0,    //  kRoundDown     2,
                        3.0,            -3.0,    //  kRoundUp       3,
                        3.0,            -3.0,    //  kRoundHalfEven 4,
                        3.0,            -3.0,    //  kRoundHalfDown 5,
                        3.0,            -3.0     //  kRoundHalfUp   6 
    };
    DecimalFormat pat(status);
    if(U_FAILURE(status)) {
      errln((UnicodeString)"ERROR: Could not create DecimalFormat (default)");
      return;
    }
    uint16_t mode;
    uint16_t i=0;
    UnicodeString message;
    UnicodeString resultStr;
    for(mode=0;mode < 7;mode++){
        pat.setRoundingMode((DecimalFormat::ERoundingMode)mode);
        if(pat.getRoundingMode() != (DecimalFormat::ERoundingMode)mode){
            errln((UnicodeString)"SetRoundingMode or GetRoundingMode failed for mode=" + mode);
        }


        //for +2.55 with RoundingIncrement=1.0
        pat.setRoundingIncrement(1.0);
        pat.format(Roundingnumber, resultStr);
        message= (UnicodeString)"round(" + (double)Roundingnumber + UnicodeString(",") + mode + UnicodeString(",FALSE) with RoundingIncrement=1.0==>");
        verify(message, resultStr, result[i++]);
        message.remove();
        resultStr.remove();

        //for -2.55 with RoundingIncrement=1.0
        pat.format(Roundingnumber1, resultStr);
        message= (UnicodeString)"round(" + (double)Roundingnumber1 + UnicodeString(",") + mode + UnicodeString(",FALSE) with RoundingIncrement=1.0==>");
        verify(message, resultStr, result[i++]);
        message.remove();
        resultStr.remove();
    }

}
void IntlTestDecimalFormatAPI::verify(const UnicodeString& message, const UnicodeString& got, double expected){
    logln((UnicodeString)message + got + (UnicodeString)" Expected : " + expected);
    UnicodeString expectedStr("");
    expectedStr=expectedStr + expected;
    if(got != expectedStr ) {
            errln((UnicodeString)"ERROR: Round() failed:  " + message + got + (UnicodeString)"  Expected : " + expectedStr);
        }
}

#endif /* #if !UCONFIG_NO_FORMATTING */
