/*
 * Copyright 2010 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.uibinder.elementparsers;

import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.i18n.client.CurrencyData;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.uibinder.rebind.UiBinderWriter;
import com.google.gwt.uibinder.rebind.XMLElement;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Parses {@link com.google.gwt.user.client.ui.DateLabel} widgets.
 */
public class NumberLabelParser implements ElementParser {

  static final String AT_MOST_ONE_SPECIFIED_FORMAT = "May have only one of format, predefinedFormat and customFormat.";
  static final String AT_MOST_ONE_SPECIFIED_CURRENCY = "May have only one of currencyData and customCode.";
  static final String NO_CURRENCY_WITH_FORMAT = "May not specify both a NumberFormat and a currency code.";
  static final String NO_CURRENCY_WITHOUT_SPECIFIED_FORMAT = "May not specify a currency code if no format is given.";
  static final String NO_CURRENCY_WITH_PREDEFINED_FORMAT = "May not specify a currency code with a predefined format (except the CURRENCY format)";
  static final String UNKNOWN_PREDEFINED_FORMAT = "Unknown predefined format: %s";

  private static final Map<String, String> predefinedFormats;

  static {
    String prefix = NumberFormat.class.getCanonicalName();
    Map<String, String> formats = new HashMap<String, String>(4);
    formats.put("DECIMAL", prefix + ".getDecimalFormat()");
    formats.put("PERCENT", prefix + ".getPercentFormat()");
    formats.put("SCIENTIFIC", prefix + ".getScientificFormat()");
    // CURRENCY is special-cased in consumeFormat.
    predefinedFormats = Collections.unmodifiableMap(formats);
  }

  public void parse(XMLElement elem, String fieldName, JClassType type,
      UiBinderWriter writer) throws UnableToCompleteException {
    if (hasNumberFormatConstructor(writer.getOracle(), type)) {
      String format = consumeFormat(elem, writer);

      if (format != null) {
        writer.setFieldInitializerAsConstructor(fieldName, type, format);
      }
    }
  }

  private String consumeCurrency(XMLElement elem, UiBinderWriter writer)
      throws UnableToCompleteException {
    String currencyData = elem.consumeAttribute("currencyData",
        writer.getOracle().findType(CurrencyData.class.getCanonicalName()));
    String currencyCode = elem.consumeStringAttribute("currencyCode");

    if (currencyData != null && currencyCode != null) {
      writer.die(elem, AT_MOST_ONE_SPECIFIED_CURRENCY);
    }
    return currencyData != null ? currencyData : currencyCode;
  }

  private String consumeFormat(XMLElement elem, UiBinderWriter writer)
      throws UnableToCompleteException {
    String format = elem.consumeAttribute("format",
        writer.getOracle().findType(NumberFormat.class.getCanonicalName()));
    String predefinedFormat = elem.consumeRawAttribute("predefinedFormat");
    String customFormat = elem.consumeStringAttribute("customFormat");

    if (format != null) {
      if (predefinedFormat != null || customFormat != null) {
        writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT);
      }
      if (hasCurrency(elem)) {
        writer.die(elem, NO_CURRENCY_WITH_FORMAT);
      }
      return format;
    }
    if (predefinedFormat != null) {
      if (customFormat != null) {
        writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT);
      }
      if ("CURRENCY".equals(predefinedFormat)) {
        String currency = consumeCurrency(elem, writer);
        return NumberFormat.class.getCanonicalName() + ".getCurrencyFormat("
            + (currency != null ? currency : "") + ")";
      }
      if (hasCurrency(elem)) {
        writer.die(elem, NO_CURRENCY_WITH_PREDEFINED_FORMAT);
      }
      String f = predefinedFormats.get(predefinedFormat);
      if (f == null) {
        writer.die(elem, UNKNOWN_PREDEFINED_FORMAT, predefinedFormat);
      }
      return f;
    }
    if (customFormat != null) {
      String currency = consumeCurrency(elem, writer);
      return NumberFormat.class.getCanonicalName() + ".getFormat(" + customFormat
          + (currency != null ? ", " + currency : "") + ")";
    }
    if (hasCurrency(elem)) {
      writer.die(elem, NO_CURRENCY_WITHOUT_SPECIFIED_FORMAT);
    }
    return null;
  }

  private boolean hasCurrency(XMLElement elem) {
    return elem.hasAttribute("currencyData")
        || elem.hasAttribute("currencyCode");
  }

  private boolean hasNumberFormatConstructor(TypeOracle typeOracle,
      JClassType type) {
    JType numberFormatType = typeOracle.findType(NumberFormat.class.getName());
    return type.findConstructor(new JType[] {numberFormatType}) != null;
  }
}
