/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.i18n.rebind;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.i18n.client.CurrencyList;
import com.google.gwt.i18n.client.impl.CurrencyDataImpl;
import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

import org.apache.tapestry.util.text.LocalizedProperties;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.regex.Pattern;

/**
 * Generator used to generate a localized version of CurrencyList, which
 * contains the list of currencies (with names, symbols, and other information)
 * localized to the current locale.
 */
public class CurrencyListGenerator extends Generator {

  /**
   * Immutable collection of data about a currency in a locale, built from the
   * CurrencyData and CurrencyExtra properties files.
   */
  private static class CurrencyInfo {

    private static final Pattern SPLIT_VERTICALBAR = Pattern.compile("\\|");

    private final String code;

    private final String displayName;

    private final int flags;

    private final boolean obsolete;

    private final String portableSymbol;

    private final String symbol;

    /**
     * Create an instance.
     * 
     * currencyData format:
     * 
     * <pre>
     *       display name|symbol|decimal digits|not-used-flag
     * </pre>
     * 
     * <ul>
     * <li>If a symbol is not supplied, the currency code will be used
     * <li>If # of decimal digits is omitted, 2 is used
     * <li>If a currency is not generally used, not-used-flag=1
     * <li>Trailing empty fields can be omitted
     * <li>If null, use currencyCode as the display name
     * </ul>
     * 
     * extraData format:
     * 
     * <pre>
     *       portable symbol|flags|currency symbol override
     *     flags are space separated list of:
     *       At most one of the following:
     *         SymPrefix     The currency symbol goes before the number,
     *                       regardless of the normal position for this locale.
     *         SymSuffix     The currency symbol goes after the number,
     *                       regardless of the normal position for this locale.
     *
     *       At most one of the following:
     *         ForceSpace    Always add a space between the currency symbol
     *                       and the number.
     *         ForceNoSpace  Never add a space between the currency symbol
     *                       and the number.
     * </pre>
     * 
     * @param currencyCode ISO4217 currency code
     * @param currencyData entry from a CurrencyData properties file
     * @param extraData entry from a CurrencyExtra properties file
     * @throws NumberFormatException
     */
    public CurrencyInfo(String currencyCode, String currencyData,
        String extraData) throws NumberFormatException {
      code = currencyCode;
      if (currencyData == null) {
        currencyData = currencyCode;
      }
      String[] currencySplit = SPLIT_VERTICALBAR.split(currencyData);
      String currencyDisplay = currencySplit[0];
      String currencySymbol = null;
      if (currencySplit.length > 1 && currencySplit[1].length() > 0) {
        currencySymbol = currencySplit[1];
      }
      int currencyFractionDigits = 2;
      if (currencySplit.length > 2 && currencySplit[2].length() > 0) {
        currencyFractionDigits = Integer.valueOf(currencySplit[2]);
      }
      boolean currencyObsolete = false;
      if (currencySplit.length > 3 && currencySplit[3].length() > 0) {
        currencyObsolete = Integer.valueOf(currencySplit[3]) != 0;
      }
      int currencyFlags = currencyFractionDigits;
      if (currencyObsolete) {
        currencyFlags |= CurrencyDataImpl.DEPRECATED_FLAG;
      }
      String currencyPortableSymbol = "";
      if (extraData != null) {
        // CurrencyExtra contains up to 3 fields separated by |
        // 0 - portable currency symbol
        // 1 - space-separated flags regarding currency symbol
        // positioning/spacing
        // 2 - override of CLDR-derived currency symbol
        String[] extraSplit = SPLIT_VERTICALBAR.split(extraData);
        currencyPortableSymbol = extraSplit[0];
        if (extraSplit.length > 1) {
          if (extraSplit[1].contains("SymPrefix")) {
            currencyFlags |= CurrencyDataImpl.POS_FIXED_FLAG;
          } else if (extraSplit[1].contains("SymSuffix")) {
            currencyFlags |= CurrencyDataImpl.POS_FIXED_FLAG
                | CurrencyDataImpl.POS_SUFFIX_FLAG;
          }
          if (extraSplit[1].contains("ForceSpace")) {
            currencyFlags |= CurrencyDataImpl.SPACING_FIXED_FLAG
                | CurrencyDataImpl.SPACE_FORCED_FLAG;
          } else if (extraSplit[1].contains("ForceNoSpace")) {
            currencyFlags |= CurrencyDataImpl.SPACING_FIXED_FLAG;
          }
        }
        // If a non-empty override is supplied, use it for the currency
        // symbol.
        if (extraSplit.length > 2 && extraSplit[2].length() > 0) {
          currencySymbol = extraSplit[2];
        }
        // If we don't have a currency symbol yet, use the portable symbol if
        // supplied.
        if (currencySymbol == null && currencyPortableSymbol.length() > 0) {
          currencySymbol = currencyPortableSymbol;
        }
      }
      // If all else fails, use the currency code as the symbol.
      if (currencySymbol == null) {
        currencySymbol = currencyCode;
      }
      displayName = currencyDisplay;
      symbol = currencySymbol;
      flags = currencyFlags;
      portableSymbol = currencyPortableSymbol;
      obsolete = currencyObsolete;
    }

    public String getDisplayName() {
      return displayName;
    }

    public int getFlags() {
      return flags;
    }

    public String getJava() {
      StringBuilder buf = new StringBuilder();
      buf.append("new CurrencyDataImpl(\"").append(quote(code)).append("\", \"");
      buf.append(quote(symbol)).append("\", ").append(flags);
      if (portableSymbol.length() > 0) {
        buf.append(", \"").append(quote(portableSymbol)).append('\"');
      }
      return buf.append(')').toString();
    }

    public String getJson() {
      StringBuilder buf = new StringBuilder();
      buf.append("[ \"").append(quote(code)).append("\", \"");
      buf.append(quote(symbol)).append("\", ").append(flags);
      if (portableSymbol.length() > 0) {
        buf.append(", \"").append(quote(portableSymbol)).append('\"');
      }
      return buf.append(']').toString();
    }

    public String getSymbol() {
      return symbol;
    }

    public boolean isObsolete() {
      return obsolete;
    }
  }

  private static final String CURRENCY_DATA = CurrencyDataImpl.class.getCanonicalName();

  /**
   * Prefix for properties files containing CLDR-derived currency data for each
   * locale.
   */
  private static final String CURRENCY_DATA_PREFIX =
      "com/google/gwt/i18n/client/impl/cldr/CurrencyData";

  /**
   * Prefix for properties files containing additional flags about currencies
   * each locale, which are not present in CLDR.
   */
  private static final String CURRENCY_EXTRA_PREFIX =
      "com/google/gwt/i18n/client/constants/CurrencyExtra";

  private static final String CURRENCY_LIST = CurrencyList.class.getCanonicalName();

  private static final String HASHMAP = HashMap.class.getCanonicalName();

  private static final String JAVASCRIPTOBJECT = JavaScriptObject.class.getCanonicalName();

  /**
   * Prefix for properties files containing number formatting constants for each
   * locale. We use this only to get the default currency for our current
   * locale.
   */
  private static final String NUMBER_CONSTANTS_PREFIX =
      "com/google/gwt/i18n/client/constants/NumberConstantsImpl";

  /**
   * Backslash-escape any double quotes in the supplied string.
   * 
   * @param str string to quote
   * @return string with double quotes backslash-escaped.
   */
  private static String quote(String str) {
    return str.replace("\"", "\\\"");
  }

  /**
   * Generate an implementation for the given type.
   * 
   * @param logger error logger
   * @param context generator context
   * @param typeName target type name
   * @return generated class name
   * @throws UnableToCompleteException
   */
  @Override
  public final String generate(TreeLogger logger, GeneratorContext context,
      String typeName) throws UnableToCompleteException {
    assert CURRENCY_LIST.equals(typeName);
    TypeOracle typeOracle = context.getTypeOracle();

    PropertyOracle propertyOracle = context.getPropertyOracle();
    LocaleUtils localeUtils = LocaleUtils.getInstance(logger, propertyOracle,
        context);
    GwtLocale locale = localeUtils.getCompileLocale();
    Set<GwtLocale> runtimeLocales = localeUtils.getRuntimeLocales();

    JClassType targetClass;
    try {
      targetClass = typeOracle.getType(typeName);
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, "No such type", e);
      throw new UnableToCompleteException();
    }
    if (runtimeLocales.isEmpty()) {
      return generateLocaleTree(logger, context, targetClass, locale);
    }
    CachedGeneratorContext cachedContext = new CachedGeneratorContext(context);
    return generateRuntimeSelection(logger, cachedContext, targetClass, locale,
        runtimeLocales);
  }

  /**
   * Generate an implementation class for the requested locale, including all
   * parent classes along the inheritance chain. The data will be kept at the
   * location in the inheritance chain where it was defined in properties files.
   * 
   * @param logger
   * @param context
   * @param targetClass
   * @param locale
   * @return generated class name for the requested locale
   */
  private String generateLocaleTree(TreeLogger logger, GeneratorContext context,
      JClassType targetClass, GwtLocale locale) {
    String superClassName = CURRENCY_LIST;
    List<GwtLocale> searchList = locale.getCompleteSearchList();

    /**
     * Map of currency code -> CurrencyInfo for that code.
     */
    Map<String, CurrencyInfo> allCurrencyData = new HashMap<String, CurrencyInfo>();

    LocalizedProperties currencyExtra = null;
    /*
     * The searchList is guaranteed to be ordered such that subclasses always
     * precede superclasses. Therefore, we iterate backwards to ensure that
     * superclasses are always generated first.
     */
    String lastDefaultCurrencyCode = null;
    for (int i = searchList.size(); i-- > 0;) {
      GwtLocale search = searchList.get(i);
      LocalizedProperties newExtra = getProperties(CURRENCY_EXTRA_PREFIX,
          search);
      if (newExtra != null) {
        currencyExtra = newExtra;
      }
      Map<String, String> currencyData = getCurrencyData(search);
      Set<String> keySet = currencyData.keySet();
      String[] currencies = new String[keySet.size()];
      keySet.toArray(currencies);
      Arrays.sort(currencies);

      // Go ahead and populate the data map.
      for (String currencyCode : currencies) {
        String extraData = currencyExtra == null ? null
            : currencyExtra.getProperty(currencyCode);
        allCurrencyData.put(currencyCode, new CurrencyInfo(currencyCode,
            currencyData.get(currencyCode), extraData));
      }

      String defCurrencyCode = getDefaultCurrency(search);
      // If this locale specifies a particular locale, or the one that is
      // inherited has been changed in this locale, re-specify the default
      // currency so the method will be generated.
      if (defCurrencyCode == null && keySet.contains(lastDefaultCurrencyCode)) {
        defCurrencyCode = lastDefaultCurrencyCode;
      }
      if (!currencyData.isEmpty() || defCurrencyCode != null) {
        String newClass =
            generateOneLocale(logger, context, targetClass, search,
                superClassName, currencies, allCurrencyData, defCurrencyCode);
        superClassName = newClass;
        lastDefaultCurrencyCode = defCurrencyCode;
      }
    }
    return superClassName;
  }

  /**
   * Generate the implementation for a single locale, overriding from its parent
   * only data that has changed in this locale.
   * 
   * @param logger
   * @param context
   * @param targetClass
   * @param locale
   * @param superClassName
   * @param currencies the set of currencies defined in this locale
   * @param allCurrencyData map of currency code -> unparsed CurrencyInfo for
   *        that code
   * @param defCurrencyCode default currency code for this locale
   * @return fully-qualified class name generated
   */
  private String generateOneLocale(TreeLogger logger, GeneratorContext context,
      JClassType targetClass, GwtLocale locale, String superClassName,
      String[] currencies, Map<String, CurrencyInfo> allCurrencyData,
      String defCurrencyCode) {
    String packageName = targetClass.getPackage().getName();
    String className = targetClass.getName().replace('.', '_') + "_"
        + locale.getAsString();
    PrintWriter pw = context.tryCreate(logger, packageName, className);
    if (pw != null) {
      ClassSourceFileComposerFactory factory =
          new ClassSourceFileComposerFactory(packageName, className);
      factory.setSuperclass(superClassName);
      factory.addImport(CURRENCY_DATA);
      factory.addImport(JAVASCRIPTOBJECT);
      factory.addImport(HASHMAP);
      SourceWriter writer = factory.createSourceWriter(context, pw);
      if (defCurrencyCode != null) {
        CurrencyInfo currencyInfo = allCurrencyData.get(defCurrencyCode);
        if (currencyInfo == null) {
          // Synthesize a null info if the specified default wasn't found.
          currencyInfo = new CurrencyInfo(defCurrencyCode, null, null);
          allCurrencyData.put(defCurrencyCode, currencyInfo);
        }
        writer.println();
        writer.println("@Override");
        writer.println("protected CurrencyData getDefaultJava() {");
        writer.println("  return " + currencyInfo.getJava() + ";");
        writer.println("}");
        writer.println();
        writer.println("@Override");
        writer.println("protected native CurrencyData getDefaultNative() /*-{");
        writer.println("  return " + currencyInfo.getJson() + ";");
        writer.println("}-*/;");
      }
      if (currencies.length > 0) {
        writeCurrencyMethodJava(writer, currencies, allCurrencyData);
        writeCurrencyMethodNative(writer, currencies, allCurrencyData);
        writeNamesMethodJava(writer, currencies, allCurrencyData);
        writeNamesMethodNative(writer, currencies, allCurrencyData);
      }
      writer.commit(logger);
    }
    return packageName + "." + className;
  }

  /**
   * Generate a class which can select between alternate implementations at
   * runtime based on the runtime locale.
   * 
   * @param logger TreeLogger instance for log messages
   * @param context GeneratorContext for generating source files
   * @param targetClass class to generate
   * @param compileLocale the compile-time locale we are generating for
   * @param locales set of all locales to generate
   * @return fully-qualified class name that was generated
   */
  private String generateRuntimeSelection(TreeLogger logger,
      GeneratorContext context, JClassType targetClass, GwtLocale compileLocale,
      Set<GwtLocale> locales) {
    String packageName = targetClass.getPackage().getName();
    String className =
        targetClass.getName().replace('.', '_') + "_"
            + compileLocale.getAsString() + "_runtimeSelection";
    PrintWriter pw = context.tryCreate(logger, packageName, className);
    if (pw != null) {
      ClassSourceFileComposerFactory factory =
          new ClassSourceFileComposerFactory(packageName, className);
      factory.setSuperclass(targetClass.getQualifiedSourceName());
      factory.addImport(CURRENCY_DATA);
      factory.addImport(JAVASCRIPTOBJECT);
      factory.addImport(HASHMAP);
      factory.addImport("com.google.gwt.i18n.client.LocaleInfo");
      SourceWriter writer = factory.createSourceWriter(context, pw);
      writer.println("private CurrencyList instance;");
      writer.println();
      writer.println("@Override");
      writer.println("protected CurrencyData getDefaultJava() {");
      writer.println("  ensureInstance();");
      writer.println("  return instance.getDefaultJava();");
      writer.println("}");
      writer.println();
      writer.println("@Override");
      writer.println("protected CurrencyData getDefaultNative() {");
      writer.println("  ensureInstance();");
      writer.println("  return instance.getDefaultNative();");
      writer.println("}");
      writer.println();
      writer.println("@Override");
      writer.println("protected HashMap<String, CurrencyData> loadCurrencyMapJava() {");
      writer.println("  ensureInstance();");
      writer.println("  return instance.loadCurrencyMapJava();");
      writer.println("}");
      writer.println();
      writer.println("@Override");
      writer.println("protected JavaScriptObject loadCurrencyMapNative() {");
      writer.println("  ensureInstance();");
      writer.println("  return instance.loadCurrencyMapNative();");
      writer.println("}");
      writer.println();
      writer.println("@Override");
      writer.println("protected HashMap<String, String> loadNamesMapJava() {");
      writer.println("  ensureInstance();");
      writer.println("  return instance.loadNamesMapJava();");
      writer.println("}");
      writer.println();
      writer.println("@Override");
      writer.println("protected JavaScriptObject loadNamesMapNative() {");
      writer.println("  ensureInstance();");
      writer.println("  return instance.loadNamesMapNative();");
      writer.println("}");
      writer.println();
      writer.println("private void ensureInstance() {");
      writer.indent();
      writer.println("if (instance != null) {");
      writer.println("  return;");
      writer.println("}");
      boolean fetchedLocale = false;
      Map<String, Set<GwtLocale>> localeMap = new TreeMap<String,
          Set<GwtLocale>>();
      String compileLocaleClass =
          processChildLocale(logger, context, targetClass, localeMap,
              compileLocale);
      if (compileLocaleClass == null) {
        // already gave warning, just use default implementation
        return null;
      }
      for (GwtLocale runtimeLocale : locales) {
        processChildLocale(logger, context, targetClass, localeMap,
            runtimeLocale);
      }
      for (Entry<String, Set<GwtLocale>> entry : localeMap.entrySet()) {
        if (!fetchedLocale) {
          writer.println("String runtimeLocale = LocaleInfo.getCurrentLocale().getLocaleName();");
          fetchedLocale = true;
        }
        boolean firstLocale = true;
        String generatedClass = entry.getKey();
        if (compileLocaleClass.equals(generatedClass)) {
          // The catch-all will handle this
          continue;
        }
        writer.print("if (");
        for (GwtLocale locale : entry.getValue()) {
          if (firstLocale) {
            firstLocale = false;
          } else {
            writer.println();
            writer.print("    || ");
          }
          writer.print("\"" + locale.toString() + "\".equals(runtimeLocale)");
        }
        writer.println(") {");
        writer.println("  instance = new " + generatedClass + "();");
        writer.println("  return;");
        writer.println("}");
      }
      writer.println("instance = new " + compileLocaleClass + "();");
      writer.outdent();
      writer.println("}");
      writer.commit(logger);
    }
    return packageName + "." + className;
  }

  /**
   * Return a map of currency data for the requested locale, or null if there is
   * not one (not that inheritance is not handled here).
   * <p/>
   * The keys are ISO4217 currency codes. The format of the map values is:
   * 
   * <pre>
   * display name|symbol|decimal digits|not-used-flag
   * </pre>
   * 
   * If a symbol is not supplied, the currency code will be used If # of decimal
   * digits is omitted, 2 is used If a currency is not generally used,
   * not-used-flag=1 Trailing empty fields can be omitted
   * 
   * @param locale
   * @return currency data map
   */
  @SuppressWarnings("unchecked")
  private Map<String, String> getCurrencyData(GwtLocale locale) {
    LocalizedProperties currencyData = getProperties(CURRENCY_DATA_PREFIX,
        locale);
    if (currencyData == null) {
      return Collections.emptyMap();
    }
    return currencyData.getPropertyMap();
  }

  /**
   * Returns the default currency code for the requested locale.
   * 
   * @param locale
   * @return ISO4217 currency code
   */
  private String getDefaultCurrency(GwtLocale locale) {
    String defCurrencyCode = null;
    LocalizedProperties numberConstants = getProperties(NUMBER_CONSTANTS_PREFIX, locale);
    if (numberConstants != null) {
      defCurrencyCode = numberConstants.getProperty("defCurrencyCode");
    }
    if (defCurrencyCode == null && locale.isDefault()) {
      defCurrencyCode = "USD";
    }
    return defCurrencyCode;
  }

  /**
   * Load a properties file for a given locale. Note that locale inheritance is
   * the responsibility of the caller.
   * 
   * @param prefix classpath prefix of properties file
   * @param locale locale to load
   * @return LocalizedProperties instance containing properties file or null if
   *         not found.
   */
  private LocalizedProperties getProperties(String prefix, GwtLocale locale) {
    String propFile = prefix;
    if (!locale.isDefault()) {
      propFile += "_" + locale.getAsString();
    }
    propFile += ".properties";
    InputStream str = null;
    ClassLoader classLoader = getClass().getClassLoader();
    LocalizedProperties props = new LocalizedProperties();
    try {
      str = classLoader.getResourceAsStream(propFile);
      if (str != null) {
        props.load(str, "UTF-8");
        return props;
      }
    } catch (UnsupportedEncodingException e) {
      // UTF-8 should always be defined
      return null;
    } catch (IOException e) {
      return null;
    } finally {
      if (str != null) {
        try {
          str.close();
        } catch (IOException e) {
        }
      }
    }
    return null;
  }

  /**
   * Generate an implementation for a runtime locale, to be referenced from the
   * generated runtime selection code.
   * 
   * @param logger
   * @param context
   * @param targetClass
   * @param localeMap
   * @param locale
   * @return class name of the generated class, or null if failed
   */
  private String processChildLocale(TreeLogger logger, GeneratorContext context,
      JClassType targetClass, Map<String, Set<GwtLocale>> localeMap,
      GwtLocale locale) {
    String generatedClass = generateLocaleTree(logger, context, targetClass,
        locale);
    if (generatedClass == null) {
      logger.log(TreeLogger.ERROR, "Failed to generate "
          + targetClass.getQualifiedSourceName() + " in locale "
          + locale.toString());
      // skip failed locale
      return null;
    }
    Set<GwtLocale> locales = localeMap.get(generatedClass);
    if (locales == null) {
      locales = new HashSet<GwtLocale>();
      localeMap.put(generatedClass, locales);
    }
    locales.add(locale);
    return generatedClass;
  }

  /**
   * Writes a loadCurrencyMapJava method for the current locale, based on its
   * currency data and its superclass (if any). As currencies are included in
   * this method, their names are added to {@code nameMap} for later use.
   * 
   * If no new currency data is added for this locale over its superclass, the
   * method is omitted entirely.
   * 
   * @param allCurrencyData map of currency codes to currency data for the
   *          current locale, including all inherited currencies data
   * @param className name of the class we are generating
   * @param writer SourceWriter instance to use for writing the class
   * @param currencies array of valid currency names in the order they should be
   *          listed
   */
  private void writeCurrencyMethodJava(SourceWriter writer,
      String[] currencies, Map<String, CurrencyInfo> allCurrencyData) {
    boolean needHeader = true;
    for (String currencyCode : currencies) {
      // TODO(jat): only emit new data where it differs from superclass!
      CurrencyInfo currencyInfo = allCurrencyData.get(currencyCode);
      if (needHeader) {
        needHeader = false;
        writer.println();
        writer.println("@Override");
        writer.println("protected HashMap<String, CurrencyData> loadCurrencyMapJava() {");
        writer.indent();
        writer.println("HashMap<String, CurrencyData> result = super.loadCurrencyMapJava();");
      }
      writer.println("// " + currencyInfo.getDisplayName());
      writer.println("result.put(\"" + quote(currencyCode) + "\", "
          + currencyInfo.getJava() + ");");
    }
    if (!needHeader) {
      writer.println("return result;");
      writer.outdent();
      writer.println("}");
    }
  }

  /**
   * Writes a loadCurrencyMapNative method for the current locale, based on its
   * currency data and its superclass (if any). As currencies are included in
   * this method, their names are added to {@code nameMap} for later use.
   * 
   * If no new currency data is added for this locale over its superclass, the
   * method is omitted entirely.
   * 
   * @param allCurrencyData map of currency codes to currency data for the
   *          current locale, including all inherited currencies data
   * @param className name of the class we are generating
   * @param writer SourceWriter instance to use for writing the class
   * @param currencies array of valid currency names in the order they should be
   *          listed
   */
  private void writeCurrencyMethodNative(SourceWriter writer,
      String[] currencies, Map<String, CurrencyInfo> allCurrencyData) {
    boolean needHeader = true;
    for (String currencyCode : currencies) {
      // TODO(jat): only emit new data where it differs from superclass!
      CurrencyInfo currencyInfo = allCurrencyData.get(currencyCode);
      if (needHeader) {
        needHeader = false;
        writer.println();
        writer.println("@Override");
        writer.println("protected JavaScriptObject loadCurrencyMapNative() {");
        writer.indent();
        writer.println("return overrideMap(super.loadCurrencyMapNative(), loadMyCurrencyMapOverridesNative());");
        writer.outdent();
        writer.println("}");
        writer.println();
        writer.println("private native JavaScriptObject loadMyCurrencyMapOverridesNative() /*-{");
        writer.indent();
        writer.println("return {");
        writer.indent();
      }
      writer.println("// " + currencyInfo.getDisplayName());
      writer.println("\"" + quote(currencyCode) + "\": "
          + currencyInfo.getJson() + ",");
    }
    if (!needHeader) {
      writer.outdent();
      writer.println("};");
      writer.outdent();
      writer.println("}-*/;");
    }
  }

  /**
   * Writes a loadNamesMapJava method for the current locale, based on its the
   * supplied names map and its superclass (if any).
   * 
   * If no new names are added for this locale over its superclass, the method
   * is omitted entirely.
   * 
   * @param className name of the class we are generating
   * @param writer SourceWriter instance to use for writing the class
   * @param currencies array of valid currency names in the order they should be
   *          listed
   */
  private void writeNamesMethodJava(SourceWriter writer, String[] currencies,
      Map<String, CurrencyInfo> allCurrencyData) {
    boolean needHeader = true;
    for (String currencyCode : currencies) {
      // TODO(jat): only emit new data where it differs from superclass!
      CurrencyInfo currencyInfo = allCurrencyData.get(currencyCode);
      String displayName = currencyInfo.getDisplayName();
      if (displayName != null && !currencyCode.equals(displayName)) {
        if (needHeader) {
          needHeader = false;
          writer.println();
          writer.println("@Override");
          writer.println("protected HashMap<String, String> loadNamesMapJava() {");
          writer.indent();
          writer.println("HashMap<String, String> result = super.loadNamesMapJava();");
        }
        writer.println("result.put(\"" + quote(currencyCode) + "\", \""
            + quote(displayName) + "\");");
      }
    }
    if (!needHeader) {
      writer.println("return result;");
      writer.outdent();
      writer.println("}");
    }
  }

  /**
   * Writes a loadNamesMapNative method for the current locale, based on its the
   * supplied names map and its superclass (if any).
   * 
   * If no new names are added for this locale over its superclass, the method
   * is omitted entirely.
   * 
   * @param className name of the class we are generating
   * @param writer SourceWriter instance to use for writing the class
   * @param currencies array of valid currency names in the order they should be
   *          listed
   */
  private void writeNamesMethodNative(SourceWriter writer, String[] currencies,
      Map<String, CurrencyInfo> allCurrencyData) {
    boolean needHeader = true;
    for (String currencyCode : currencies) {
      // TODO(jat): only emit new data where it differs from superclass!
      CurrencyInfo currencyInfo = allCurrencyData.get(currencyCode);
      String displayName = currencyInfo.getDisplayName();
      if (displayName != null && !currencyCode.equals(displayName)) {
        if (needHeader) {
          needHeader = false;
          writer.println();
          writer.println("@Override");
          writer.println("protected JavaScriptObject loadNamesMapNative() {");
          writer.indent();
          writer.println("return overrideMap(super.loadNamesMapNative(), loadMyNamesMapOverridesNative());");
          writer.outdent();
          writer.println("}");
          writer.println();
          writer.println("private native JavaScriptObject loadMyNamesMapOverridesNative() /*-{");
          writer.indent();
          writer.println("return {");
          writer.indent();
        }
        writer.println("\"" + quote(currencyCode) + "\": \""
            + quote(displayName) + "\",");
      }
    }
    if (!needHeader) {
      writer.outdent();
      writer.println("};");
      writer.outdent();
      writer.println("}-*/;");
    }
  }
}
