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

#include "unicode/utypes.h"
#include "unicode/unistr.h"
#include "unicode/numfmt.h"
#include "unicode/dcfmtsym.h"
#include "unicode/decimfmt.h"
#include "unicode/locid.h"
#include "unicode/uclean.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern "C" void capi();
void cppapi();

static void
showCurrencyFormatting(UBool useICU26API);

int main(int argc, char **argv) {
    printf("%s output is in UTF-8\n", argv[0]);

    printf("C++ API\n");
    cppapi();

    printf("C API\n");
    capi();

    showCurrencyFormatting(FALSE);
    showCurrencyFormatting(TRUE);

    u_cleanup();    // Release any additional storage held by ICU.  

    printf("Exiting successfully\n");
    return 0;
}

/**
 * Sample code for the C++ API to NumberFormat.
 */
void cppapi() {
    Locale us("en", "US");
    UErrorCode status = U_ZERO_ERROR;
    
    // Create a number formatter for the US locale
    NumberFormat *fmt = NumberFormat::createInstance(us, status);
    check(status, "NumberFormat::createInstance");

    // Parse a string.  The string uses the digits '0' through '9'
    // and the decimal separator '.', standard in the US locale
    UnicodeString str("9876543210.123");
    Formattable result;
    fmt->parse(str, result, status);
    check(status, "NumberFormat::parse");

    printf("NumberFormat::parse(\""); // Display the result
    uprintf(str);
    printf("\") => ");
    uprintf(formattableToString(result));
    printf("\n");

    // Take the number parsed above, and use the formatter to
    // format it.
    str.remove(); // format() will APPEND to this string
    fmt->format(result, str, status);
    check(status, "NumberFormat::format");

    printf("NumberFormat::format("); // Display the result
    uprintf(formattableToString(result));
    printf(") => \"");
    uprintf(str);
    printf("\"\n");

    delete fmt; // Release the storage used by the formatter
    
}

// currency formatting ----------------------------------------------------- ***

/*
 * Set a currency on a NumberFormat with pre-ICU 2.6 APIs.
 * This is a "hack" that will not work properly for all cases because
 * only ICU 2.6 introduced a more complete framework and data for this.
 *
 * @param nf The NumberFormat on which to set the currency; takes effect on
 *           currency-formatting NumberFormat instances.
 *           This must actually be a DecimalFormat instance.
 *           The display style of the output is controlled by nf (its pattern,
 *           usually from the display locale ID used to create this instance)
 *           while the currency symbol and number of decimals are set for
 *           the currency.
 * @param currency The 3-letter ISO 4217 currency code, NUL-terminated.
 * @param errorCode ICU error code, must pass U_SUCCESS() on input.
 */
static void
setNumberFormatCurrency_2_4(NumberFormat &nf, const char *currency, UErrorCode &errorCode) {
    // argument checking
    if(U_FAILURE(errorCode)) {
        return;
    }
    if(currency==NULL || strlen(currency)!=3) {
        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    // check that the formatter is a DecimalFormat instance
    // necessary because we will cast to the DecimalFormat subclass to set
    // the currency symbol
    DecimalFormat *dnf=dynamic_cast<DecimalFormat *>(&nf);
    if(dnf==NULL) {
        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    // map the currency code to a locale ID
    // only the currencies in this array are supported
    // it would be possible to map to a locale ID, instantiate a currency
    // formatter for that and copy its values, but that would be slower,
    // and we have to hardcode something here anyway
    static const struct {
        // ISO currency ID
        const char *currency;

        // fractionDigits==minimumFractionDigits==maximumFractionDigits
        // for these currencies
        int32_t fractionDigits;

        /*
         * Set the rounding increment to 0 if it is implied with the number of
         * fraction digits. Setting an explicit rounding increment makes
         * number formatting slower.
         * In other words, set it to something other than 0 only for unusual
         * cases like "nickel rounding" (0.05) when the increment differs from
         * 10^(-maximumFractionDigits).
         */
        double roundingIncrement;

        // Unicode string with the desired currency display symbol or name
        UChar symbol[16];
    } currencyMap[]={
        { "USD", 2, 0.0, { 0x24, 0 } },
        { "GBP", 2, 0.0, { 0xa3, 0 } },
        { "EUR", 2, 0.0, { 0x20ac, 0 } },
        { "JPY", 0, 0.0, { 0xa5, 0 } }
    };

    int32_t i;

    for(i=0; i<UPRV_LENGTHOF(currencyMap); ++i) {
        if(strcmp(currency, currencyMap[i].currency)==0) {
            break;
        }
    }
    if(i==UPRV_LENGTHOF(currencyMap)) {
        // a more specific error code would be useful in a real application
        errorCode=U_UNSUPPORTED_ERROR;
        return;
    }

    // set the currency-related data into the caller's formatter

    nf.setMinimumFractionDigits(currencyMap[i].fractionDigits);
    nf.setMaximumFractionDigits(currencyMap[i].fractionDigits);

    dnf->setRoundingIncrement(currencyMap[i].roundingIncrement);

    DecimalFormatSymbols symbols(*dnf->getDecimalFormatSymbols());
    symbols.setSymbol(DecimalFormatSymbols::kCurrencySymbol, currencyMap[i].symbol);
    dnf->setDecimalFormatSymbols(symbols); // do not adopt symbols: Jitterbug 2889
}

/*
 * Set a currency on a NumberFormat with ICU 2.6 APIs.
 *
 * @param nf The NumberFormat on which to set the currency; takes effect on
 *           currency-formatting NumberFormat instances.
 *           The display style of the output is controlled by nf (its pattern,
 *           usually from the display locale ID used to create this instance)
 *           while the currency symbol and number of decimals are set for
 *           the currency.
 * @param currency The 3-letter ISO 4217 currency code, NUL-terminated.
 * @param errorCode ICU error code, must pass U_SUCCESS() on input.
 */
static void
setNumberFormatCurrency_2_6(NumberFormat &nf, const char *currency, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) {
        return;
    }
    if(currency==NULL || strlen(currency)!=3) {
        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    // invariant-character conversion to UChars (see utypes.h and putil.h)
    UChar uCurrency[4];
    u_charsToUChars(currency, uCurrency, 4);

    // set the currency
    // in ICU 3.0 this API (which was @draft ICU 2.6) gained a UErrorCode& argument
#if (U_ICU_VERSION_MAJOR_NUM < 3)
    nf.setCurrency(uCurrency);
#else
    nf.setCurrency(uCurrency, errorCode);
#endif
}

static const char *const
sampleLocaleIDs[]={
    // use locale IDs complete with country code to be sure to
    // pick up number/currency format patterns
    "en_US", "en_GB", "de_DE", "ja_JP", "fr_FR", "hi_IN"
};

static const char *const
sampleCurrencies[]={
    "USD", "GBP", "EUR", "JPY"
};

static void
showCurrencyFormatting(UBool useICU26API) {
    NumberFormat *nf;
    int32_t i, j;

    UnicodeString output;

    UErrorCode errorCode;

    // TODO: Using printf() here assumes that the runtime encoding is ASCII-friendly
    // and can therefore be mixed with UTF-8

    for(i=0; i<UPRV_LENGTHOF(sampleLocaleIDs); ++i) {
        printf("show currency formatting (method for %s) in the locale \"%s\"\n",
                useICU26API ? "ICU 2.6" : "before ICU 2.6",
                sampleLocaleIDs[i]);

        // get a currency formatter for this locale ID
        errorCode=U_ZERO_ERROR;
        nf=NumberFormat::createCurrencyInstance(sampleLocaleIDs[i], errorCode);
        if(U_FAILURE(errorCode)) {
            printf("NumberFormat::createCurrencyInstance(%s) failed - %s\n",
                    sampleLocaleIDs[i], u_errorName(errorCode));
            continue;
        }

        for(j=0; j<UPRV_LENGTHOF(sampleCurrencies); ++j) {
            printf("  - format currency \"%s\": ", sampleCurrencies[j]);

            // set the actual currency to be formatted
            if(useICU26API) {
                setNumberFormatCurrency_2_6(*nf, sampleCurrencies[j], errorCode);
            } else {
                setNumberFormatCurrency_2_4(*nf, sampleCurrencies[j], errorCode);
            }
            if(U_FAILURE(errorCode)) {
                printf("setNumberFormatCurrency(%s) failed - %s\n",
                        sampleCurrencies[j], u_errorName(errorCode));
                continue;
            }

            // output=formatted currency value
            output.remove();
            nf->format(12345678.93, output);
            output+=(UChar)0x0a; // '\n'
            uprintf(output);
        }
    }
}
