// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 1997-2010, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "pptest.h"

#include "unicode/numfmt.h"
#include "unicode/decimfmt.h"
 
// *****************************************************************************
// class ParsePositionTest
// *****************************************************************************

#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;

void ParsePositionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    // if (exec) logln((UnicodeString)"TestSuite ParsePositionTest");
    switch (index) {
        CASE(0, TestParsePosition)
        CASE(1, TestFieldPosition)
        CASE(2, TestFieldPosition_example)
        CASE(3, Test4109023)

        default: name = ""; break;
    }
}

UBool 
ParsePositionTest::failure(UErrorCode status, const char* msg, UBool possibleDataError)
{
    if(U_FAILURE(status)) {
        if (possibleDataError) {
            dataerrln(UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status));
        } else {
            errln(UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status));
        }
        return true;
    }

    return false;
}
 
void ParsePositionTest::TestParsePosition() 
{
    ParsePosition pp1(0);
    if (pp1.getIndex() == 0) {
        logln("PP constructor() tested.");
    }else{
        errln("*** PP getIndex or constructor() result");
    }

    {
        int to = 5;
        ParsePosition pp2( to );
        if (pp2.getIndex() == 5) {
            logln("PP getIndex and constructor(int32_t) tested.");
        }else{
            errln("*** PP getIndex or constructor(int32_t) result");
        }
        pp2.setIndex( 3 );
        if (pp2.getIndex() == 3) {
            logln("PP setIndex tested.");
        }else{
            errln("*** PP getIndex or setIndex result");
        }
    }

    ParsePosition pp2(3), pp3(5);
    //pp2 = new ParsePosition( 3 );
    //pp3 = new ParsePosition( 5 );
    ParsePosition pp4(5);
    if ( pp2 != pp3) {
        logln("PP not equals tested.");
    }else{
        errln("*** PP not equals fails");
    }
    if (pp3 == pp4) {
        logln("PP equals tested.");
    }else{
        errln(UnicodeString("*** PP equals fails (") + pp3.getIndex() + " != " + pp4.getIndex() + ")");
    }

    ParsePosition pp5;
    pp5 = pp4;
    if (pp4 == pp5) {
        logln("PP operator= tested.");
    }else{
        errln("*** PP operator= operator== or operator != result");
    }

    ParsePosition *ppp = pp5.clone();
    if(ppp == &pp5 || *ppp != pp5) {
        errln("ParsePosition.clone() failed");
    }
    delete ppp;
}

void ParsePositionTest::TestFieldPosition() 
{
    FieldPosition fp( 7 );

    if (fp.getField() == 7) {
        logln("FP constructor(int) and getField tested.");
    }else{
        errln("*** FP constructor(int) or getField");
    }

    FieldPosition fpc(fp);
    if (fpc.getField() == 7) {
        logln("FP Constructor(FP&) passed");
    } else {
        errln("*** FP Constructor(FP&)");
    }

    FieldPosition fph( 3 );
    if ( fph.getField() != 3) 
        errln("*** FP getField or heap constr.");

    UBool err1 = false;
    UBool err2 = false;
    UBool err3 = false;
//        for (long i = -50; i < 50; i++ ) {
//            fp.setField( i+8 );
//            fp.setBeginIndex( i+6 );
//            fp.setEndIndex( i+7 );
//            if (fp.getField() != i+8)  err1 = true;
//            if (fp.getBeginIndex() != i+6) err2 = true;
//            if (fp.getEndIndex() != i+7) err3 = true;
//        }
    if (!err1) {
        logln("FP setField and getField tested.");
    }else{
        errln("*** FP setField or getField");
    }
    if (!err2) {
        logln("FP setBeginIndex and getBeginIndex tested.");
    }else{
        errln("*** FP setBeginIndex or getBeginIndex");
    }
    if (!err3) {
        logln("FP setEndIndex and getEndIndex tested.");
    }else{
        errln("*** FP setEndIndex or getEndIndex");
    }

    logln("");

    FieldPosition *pfp = fp.clone();
    if(pfp == &fp || *pfp != fp) {
        errln("FieldPosition.clone() failed");
    }
    delete pfp;
}

void ParsePositionTest::TestFieldPosition_example() 
{
    //***** no error detection yet !!!!!!!
    //***** this test is for compiler checks and visual verification only.
    double doubleNum[] = { 
        123456789.0, 
        -12345678.9, 
        1234567.89, 
        -123456.789,
        12345.6789, 
        -1234.56789, 
        123.456789, 
        -12.3456789, 
        1.23456789};
    int dNumSize = 9;

    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nf = NumberFormat::createInstance(status);
    if (failure(status, "NumberFormat::createInstance", true)){
        delete nf;
        return;
    }

    DecimalFormat *fmt = dynamic_cast<DecimalFormat *>(nf);
    if(fmt == nullptr) {
        errln("NumberFormat::createInstance returned unexpected class type");
        return;
    }
    fmt->setDecimalSeparatorAlwaysShown(true);

    const int tempLen = 20;
    UnicodeString temp;

    for (int i=0; i < dNumSize; i++) {
        temp.remove();
        //temp = new StringBuffer(); // Get new buffer

        FieldPosition pos(NumberFormat::INTEGER_FIELD);
        UnicodeString buf;// = new StringBuffer();
        //char fmtText[tempLen];
        //ToCharString(fmt->format(doubleNum[i], buf, pos), fmtText);
        UnicodeString res;
        res = fmt->format(doubleNum[i], buf, pos);
        int tempOffset = (tempLen <= (tempLen - pos.getEndIndex())) ?
            tempLen : (tempLen - pos.getEndIndex());
        for (int j=0; j<tempOffset; j++) 
            temp += UnicodeString("="/*'='*/); // initialize
        logln("FP " + temp + res);
    }

    logln("");
    delete nf;
}

/* @bug 4109023
 * Need to override ParsePosition.equals and FieldPosition.equals.
 */
void ParsePositionTest::Test4109023()
{
    ParsePosition p(3);
    ParsePosition p2(3);
    if (p != p2)
        errln("Error : ParsePosition.equals() failed");
    FieldPosition fp(2);
    FieldPosition fp2(2);
    if (fp != fp2)
        errln("Error : FieldPosition.equals() failed");
}

#endif /* #if !UCONFIG_NO_FORMATTING */
