/* Currency.java -- Representation of a currency
   Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util;

import gnu.java.locale.LocaleHelper;

import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;

import java.util.spi.CurrencyNameProvider;

/**
 * Representation of a currency for a particular locale.  Each currency
 * is identified by its ISO 4217 code, and only one instance of this
 * class exists per currency.  As a result, instances are created
 * via the <code>getInstance()</code> methods rather than by using
 * a constructor.
 *
 * @see java.util.Locale
 * @author Guilhem Lavaux  (guilhem.lavaux@free.fr)
 * @author Dalibor Topic (robilad@kaffe.org)
 * @author Bryce McKinlay (mckinlay@redhat.com)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.4
 */
public final class Currency 
  implements Serializable
{
  /**
   * For compatability with Sun's JDK
   */
  static final long serialVersionUID = -158308464356906721L;

  /**
   * The set of properties which map a currency to
   * the currency information such as the ISO 4217
   * currency code and the number of decimal points.
   *
   * @see #getCurrencyCode()
   * @serial ignored.
   */
  private static transient Properties properties;

  /**
   * The ISO 4217 currency code associated with this
   * particular instance.
   *
   * @see #getCurrencyCode()
   * @serial the ISO 4217 currency code
   */
  private String currencyCode;

  /**
   * The number of fraction digits associated with this
   * particular instance.
   *
   * @see #getDefaultFractionDigits()
   * @serial the number of fraction digits
   */
  private transient int fractionDigits;
  
  /**
   * A cached map of country codes
   * instances to international currency code
   * <code>String</code>s.  Seperating this
   * from the <code>Currency</code> instances
   * ensures we have a common lookup between
   * the two <code>getInstance()</code> methods.
   *
   * @see #getInstance(java.util.Locale)
   * @serial ignored.
   */
  private static transient Map countryMap;

  /**
   * A cache of <code>Currency</code> instances to
   * ensure the singleton nature of this class.  The key
   * is the international currency code.
   *
   * @see #getInstance(java.util.Locale)
   * @see #getInstance(java.lang.String) 
   * @see #readResolve()
   * @serial ignored.
   */
  private static transient Map cache;

  /**
   * Instantiates the cache and reads in the properties.
   */
  static
  {
    /* Create a hash map for the locale mappings */
    countryMap = new HashMap();
    /* Create a hash map for the cache */
    cache = new HashMap();
    /* Create the properties object */
    properties = new Properties();
    /* Try and load the properties from our iso4217.properties resource */
    try 
      {
        properties.load(Currency.class.getResourceAsStream("iso4217.properties"));
      }
    catch (IOException exception)
      {
        throw new InternalError("Failed to load currency resource: " + exception);
      }
  }

  /**
   * Default constructor for deserialization
   */
  private Currency()
  {
  }

  /**
   * Constructor to create a <code>Currency</code> object
   * for a particular <code>Locale</code>.
   * All components of the given locale, other than the
   * country code, are ignored.  The results of calling this
   * method may vary over time, as the currency associated with
   * a particular country changes.  For countries without
   * a given currency (e.g. Antarctica), the result is null. 
   *
   * @param loc the locale for the new currency, or null if
   *        there is no country code specified or a currency
   *        for this country.
   */
  private Currency(Locale loc)
  {
    String countryCode;
    String currencyKey;
    String fractionDigitsKey;
    int commaPosition;

    /* Retrieve the country code from the locale */
    countryCode = loc.getCountry();
    /* If there is no country code, return */
    if (countryCode.equals(""))
      {
        throw new
	  IllegalArgumentException("Invalid (empty) country code for locale:"
			  	   + loc);
      }
    /* Construct the key for the currency */
    currencyKey = countryCode + ".currency";
    /* Construct the key for the fraction digits */
    fractionDigitsKey = countryCode + ".fractionDigits";
    /* Retrieve the currency */
    currencyCode = properties.getProperty(currencyKey);
    /* Return if the currency code is null */
    if (currencyCode == null)
      {
        return;
      }
    /* Split off the first currency code (we only use the first for now) */
    commaPosition = currencyCode.indexOf(",");
    if (commaPosition != -1)
      {
        currencyCode = currencyCode.substring(0, commaPosition);
      }
    /* Retrieve the fraction digits */
    fractionDigits = Integer.parseInt(properties.getProperty(fractionDigitsKey));
  }

  /**
   * Constructor for the "XXX" special case.  This allows
   * a Currency to be constructed from an assumed good
   * currency code.
   *
   * @param code the code to use.
   */  
  private Currency(String code)
  {
    currencyCode = code;
    fractionDigits = -1; /* Pseudo currency */
  }

  /**
   * Returns the ISO4217 currency code of this currency.
   *
   * @return a <code>String</code> containing currency code.
   */
  public String getCurrencyCode()
  {
    return currencyCode;
  }

  /**
   * Returns the number of digits which occur after the decimal point
   * for this particular currency.  For example, currencies such
   * as the U.S. dollar, the Euro and the Great British pound have two
   * digits following the decimal point to indicate the value which exists
   * in the associated lower-valued coinage (cents in the case of the first
   * two, pennies in the latter).  Some currencies such as the Japanese
   * Yen have no digits after the decimal point.  In the case of pseudo
   * currencies, such as IMF Special Drawing Rights, -1 is returned.
   *
   * @return the number of digits after the decimal separator for this currency.
   */   
  public int getDefaultFractionDigits()
  {
    return fractionDigits;
  }
    
  /**
   * Builds a new currency instance for this locale.
   * All components of the given locale, other than the
   * country code, are ignored.  The results of calling this
   * method may vary over time, as the currency associated with
   * a particular country changes.  For countries without
   * a given currency (e.g. Antarctica), the result is null. 
   *
   * @param locale a <code>Locale</code> instance.
   * @return a new <code>Currency</code> instance.
   * @throws NullPointerException if the locale or its
   *         country code is null.
   * @throws IllegalArgumentException if the country of
   *         the given locale is not a supported ISO3166 code.
   */ 
  public static Currency getInstance(Locale locale)
  {
    /**
     * The new instance must be the only available instance
     * for the currency it supports.  We ensure this happens,
     * while maintaining a suitable performance level, by
     * creating the appropriate object on the first call to
     * this method, and returning the cached instance on
     * later calls.
     */
    Currency newCurrency;

    String country = locale.getCountry();
    if (locale == null || country == null)
      {
	throw new
	  NullPointerException("The locale or its country is null.");
      }
    
    /* Check that country of locale given is valid. */
    if (country.length() != 2)
      throw new IllegalArgumentException();
    
    /* Attempt to get the currency from the cache */
    String code = (String) countryMap.get(country);
    if (code == null)
      {
        /* Create the currency for this locale */
        newCurrency = new Currency(locale);
        /* 
         * If the currency code is null, then creation failed
         * and we return null.
         */
	code = newCurrency.getCurrencyCode();
        if (code == null)
          {
            return null;
          }
        else 
          {
            /* Cache it */
            countryMap.put(country, code);
	    cache.put(code, newCurrency);
          }
      }
    else
      {
	newCurrency = (Currency) cache.get(code);
      }
    /* Return the instance */
    return newCurrency;
  }

  /**
   * Builds the currency corresponding to the specified currency code.
   *
   * @param currencyCode a string representing a currency code.
   * @return a new <code>Currency</code> instance.
   * @throws NullPointerException if currencyCode is null.
   * @throws IllegalArgumentException if the supplied currency code
   *         is not a supported ISO 4217 code.
   */
  public static Currency getInstance(String currencyCode)
  {
    Locale[] allLocales;

    /* 
     * Throw a null pointer exception explicitly if currencyCode is null.
     * One is not thrown otherwise.  It results in an
     * IllegalArgumentException. 
     */
    if (currencyCode == null)
      {
        throw new NullPointerException("The supplied currency code is null.");
      }
    /* Nasty special case to allow an erroneous currency... blame Sun */
    if (currencyCode.equals("XXX"))
      return new Currency("XXX");
    Currency newCurrency = (Currency) cache.get(currencyCode);
    if (newCurrency == null)
      {
	/* Get all locales */
	allLocales = Locale.getAvailableLocales();
	/* Loop through each locale, looking for the code */
	for (int i = 0;i < allLocales.length; i++)
	  {
	    try
	      {
		Currency testCurrency = getInstance (allLocales[i]);
		if (testCurrency != null &&
		    testCurrency.getCurrencyCode().equals(currencyCode))
		  {
		    return testCurrency;
		  }
	      }
	    catch (IllegalArgumentException exception)
	      {
		/* Ignore locales without valid countries */
	      }
	  }
	/* 
	 * If we get this far, the code is not supported by any of
	 * our locales.
	 */
	throw new IllegalArgumentException("The currency code, " + currencyCode +
					   ", is not supported.");
      }
    else
      {
	return newCurrency;
      }
  }

  /**
   * This method returns the symbol which precedes or follows a
   * value in this particular currency in the default locale.
   * In cases where there is no such symbol for the currency,
   * the ISO 4217 currency code is returned.
   *
   * @return the currency symbol, or the ISO 4217 currency code if
   *         one doesn't exist.
   */
  public String getSymbol()
  {
    return getSymbol(Locale.getDefault());
  }

  /**
   * <p>
   * This method returns the symbol which precedes or follows a
   * value in this particular currency.  The returned value is
   * the symbol used to denote the currency in the specified locale.
   * </p>
   * <p>
   * For example, a supplied locale may specify a different symbol
   * for the currency, due to conflicts with its own currency.
   * This would be the case with the American currency, the dollar.
   * Locales that also use a dollar-based currency (e.g. Canada, Australia)
   * need to differentiate the American dollar using 'US$' rather than '$'.
   * So, supplying one of these locales to <code>getSymbol()</code> would
   * return this value, rather than the standard '$'.
   * </p>
   * <p>
   * In cases where there is no such symbol for a particular currency,
   * the ISO 4217 currency code is returned.
   * </p>
   *
   * @param locale the locale to express the symbol in.
   * @return the currency symbol, or the ISO 4217 currency code if
   *         one doesn't exist.
   * @throws NullPointerException if the locale is null.
   */
  public String getSymbol(Locale locale)
  {
    String property = "currenciesSymbol." + currencyCode;
    try
      {
        return ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
					locale).getString(property);
      }
    catch (MissingResourceException exception)
      {
	/* This means runtime support for the locale
	 * is not available, so we check providers. */
      }
    for (CurrencyNameProvider p :
	   ServiceLoader.load(CurrencyNameProvider.class))
      {
	for (Locale loc : p.getAvailableLocales())
	  {
	    if (loc.equals(locale))
	      {
		String localizedString = p.getSymbol(currencyCode,
						     locale);
		if (localizedString != null)
		  return localizedString;
		break;
	      }
	  }
      }
    if (locale.equals(Locale.ROOT)) // Base case
      return currencyCode;
    return getSymbol(LocaleHelper.getFallbackLocale(locale));
  }

  /**
   * Returns the international ISO4217 currency code of this currency.
   *
   * @return a <code>String</code> containing the ISO4217 currency code.
   */
  public String toString()
  {
    return getCurrencyCode();
  }

  /**
   * Resolves the deserialized object to the singleton instance for its
   * particular currency.  The currency code of the deserialized instance
   * is used to return the correct instance.
   *
   * @return the singleton instance for the currency specified by the
   *         currency code of the deserialized object.  This replaces
   *         the deserialized object as the returned object from
   *         deserialization.
   * @throws ObjectStreamException if a problem occurs with deserializing
   *         the object.
   */
  private Object readResolve()
    throws ObjectStreamException
  {
    return getInstance(currencyCode);
  }

}
