/**
 *******************************************************************************
 * Copyright (C) 2001-2002, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/Currency.java,v $
 * $Date: 2002/08/13 23:43:27 $
 * $Revision: 1.4 $
 *
 *******************************************************************************
 */
package com.ibm.icu.util;

import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import java.io.Serializable;
import com.ibm.icu.impl.ICULocaleData;
import com.ibm.icu.text.DecimalFormatSymbols;

/**
 * A class encapsulating a currency, as defined by ISO 4217.  A
 * <tt>Currency</tt> object can be created given a <tt>Locale</tt> or
 * given an ISO 4217 code.  Once created, the <tt>Currency</tt> object
 * can return various data necessary to its proper display:
 *
 * <ul><li>A display symbol, for a specific locale
 * <li>The number of fraction digits to display
 * <li>A rounding increment
 * </ul>
 *
 * The <tt>DecimalFormat</tt> class uses these data to display
 * currencies.
 *
 * <p>Note: This class deliberately resembles
 * <tt>java.util.Currency</tt> but it has a completely independent
 * implementation, and adds features not present in the JDK.
 * @author Alan Liu
 * @since ICU 2.2
 */
public class Currency implements Serializable {

    /**
     * ISO 4217 3-letter code.
     */
    private String isoCode;

    /**
     * Returns a currency object for the default currency in the given
     * locale.
     */
    public static Currency getInstance(Locale locale) {
        // Look up the CurrencyElements resource for this locale.
        // It contains: [0] = currency symbol, e.g. "$";
        // [1] = intl. currency symbol, e.g. "USD";
        // [2] = monetary decimal separator, e.g. ".".
        ResourceBundle rb = ICULocaleData.getLocaleElements(locale);
        String[] currencyElements = rb.getStringArray("CurrencyElements");
        return getInstance(currencyElements[1]);
    }

    /**
     * Returns a currency object given an ISO 4217 3-letter code.
     */
    public static Currency getInstance(String theISOCode) {
        return new Currency(theISOCode);
    }

    /**
     * Returns the ISO 4217 3-letter code for this currency object.
     */
    public String getCurrencyCode() {
        return isoCode;
    }

    /**
     * Returns the display string for this currency object in the
     * given locale.  For example, the display string for the USD
     * currency object in the en_US locale is "$".
     */
    public String getSymbol(Locale locale) {
        // Look up the Currencies resource for the given locale.  The
        // Currencies locale looks like this in the original C
        // resource file:
        //|en {
        //|  Currencies { 
        //|    USD { "$" }
        //|    CHF { "sFr" }
        //|    //...
        //|  }
        //|}
        ResourceBundle rb = ICULocaleData.getLocaleElements(locale);
        // We can't cast this to String[][]; the cast has to happen later
        try {
            Object[][] currencies = (Object[][]) rb.getObject("Currencies");
            // Do a linear search
            for (int i=0; i<currencies.length; ++i) {
                if (isoCode.equals((String) currencies[i][0])) {
                    return (String) currencies[i][1];
                }
            }
        }
        catch (MissingResourceException e) {}

        try {
            // Since the Currencies resource is not fully populated yet,
            // check to see if we can find what we want in the CurrencyElements
            // resource.
            String[] currencyElements = rb.getStringArray("CurrencyElements");
            if (currencyElements[1].equals(isoCode)) {
                return currencyElements[0];
            }
        }
        catch (MissingResourceException e2) {}

        // If we fail to find a match, use the full ISO code
        return isoCode;
    }

    /**
     * Returns the number of the number of fraction digits that should
     * be displayed for this currency.
     * @return a non-negative number of fraction digits to be
     * displayed
     */
    public int getDefaultFractionDigits() {
        return (findData())[0].intValue();
    }

    /**
     * Returns the rounding increment for this currency, or 0.0 if no
     * rounding is done by this currency.
     * @return the non-negative rounding increment, or 0.0 if none
     */
    public double getRoundingIncrement() {
        Integer[] data = findData();

        int data1 = data[1].intValue(); // rounding increment

        // If there is no rounding return 0.0 to indicate no rounding.
        // This is the high-runner case, by far.
        if (data1 == 0) {
            return 0.0;
        }

        int data0 = data[0].intValue(); // fraction digits

        // If the meta data is invalid, return 0.0 to indicate no rounding.
        if (data0 < 0 || data0 >= POW10.length) {
            return 0.0;
        }

        // Return data[1] / 10^(data[0]).  The only actual rounding data,
        // as of this writing, is CHF { 2, 25 }.
        return (double) data1 / POW10[data0];
    }

    /**
     * Returns the ISO 4217 code for this currency.
     */
    public String toString() {
        return isoCode;
    }

    /**
     * Constructs a currency object for the given ISO 4217 3-letter
     * code.  This constructor assumes that the code is valid.
     */
    private Currency(String theISOCode) {
        isoCode = theISOCode;
    }

    /**
     * Internal function to look up currency data.  Result is an array of
     * two Integers.  The first is the fraction digits.  The second is the
     * rounding increment, or 0 if none.  The rounding increment is in
     * units of 10^(-fraction_digits).
     */
    private Integer[] findData() {

        try {
            // Get CurrencyMeta resource out of root locale file.  [This may
            // move out of the root locale file later; if it does, update this
            // code.]
            ResourceBundle root = ICULocaleData.getLocaleElements("");

            Object[][] currencyMeta = (Object[][]) root.getObject("CurrencyMeta");

            Integer[] i = null;
            int defaultPos = -1;

            // Do a linear search for isoCode.  At the same time,
            // record the position of the DEFAULT meta data.  If the
            // meta data becomes large, make this faster.
            for (int j=0; j<currencyMeta.length; ++j) {
                Object[] row = currencyMeta[j];
                String s = (String) row[0];
                int c = isoCode.compareToIgnoreCase(s);
                if (c == 0) {
                    i = (Integer[]) row[1];
                    break;
                }
                if ("DEFAULT".equalsIgnoreCase(s)) {
                    defaultPos = j;
                }
                if (c < 0 && defaultPos >= 0) {
                    break;
                }
            }

            if (i == null && defaultPos >= 0) {
                i = (Integer[]) currencyMeta[defaultPos][1];
            }

            if (i != null && i.length >= 2) {
                return i;
            }
        }
        catch (MissingResourceException e) {}

        // Config/build error; return hard-coded defaults
        return LAST_RESORT_DATA;
    }

    // Default currency meta data of last resort.  We try to use the
    // defaults encoded in the meta data resource bundle.  If there is a
    // configuration/build error and these are not available, we use these
    // hard-coded defaults (which should be identical).
    private static final Integer[] LAST_RESORT_DATA =
        new Integer[] { new Integer(2), new Integer(0) };

    // POW10[i] = 10^i
    private static final int[] POW10 = { 1, 10, 100, 1000, 10000, 100000,
                                1000000, 10000000, 100000000, 1000000000 };
}

//eof
