/*
 * 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.core.ext.typeinfo.TypeOracleException;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.TimeZone;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.uibinder.rebind.UiBinderWriter;
import com.google.gwt.uibinder.rebind.XMLElement;

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

  static final String AT_MOST_ONE_SPECIFIED_FORMAT = "May have at most one of format, predefinedFormat and customFormat.";
  static final String AT_MOST_ONE_SPECIFIED_TIME_ZONE = "May have at most one of timezone and timezoneOffset.";
  static final String NO_TIMEZONE_WITHOUT_SPECIFIED_FORMAT = "May not specify a time zone if no format is given.";

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

      if (format != null) {
        String timeZone = (supportsTimeZone ? consumeTimeZone(elem, writer)
            : null);

        writer.setFieldInitializerAsConstructor(fieldName, type, makeArgs(
            format, timeZone));
      } else if (supportsTimeZone && hasTimeZone(elem)) {
        writer.die(elem, NO_TIMEZONE_WITHOUT_SPECIFIED_FORMAT);
      }
    }
  }

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

    if (format != null) {
      if (predefinedFormat != null || customFormat != null) {
        writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT);
      }
      return format;
    }
    if (predefinedFormat != null) {
      if (customFormat != null) {
        writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT);
      }
      return makeGetFormat(predefinedFormat);
    }
    if (customFormat != null) {
      return makeGetFormat(customFormat);
    }
    return null;
  }

  private String consumeTimeZone(XMLElement elem, UiBinderWriter writer)
      throws UnableToCompleteException {
    String timeZone = elem.consumeAttribute("timezone",
        writer.getOracle().findType(TimeZone.class.getCanonicalName()));
    String timeZoneOffset = elem.consumeAttribute("timezoneOffset",
        getIntType(writer.getOracle()));
    if (timeZone != null && timeZoneOffset != null) {
      writer.die(elem, AT_MOST_ONE_SPECIFIED_TIME_ZONE);
    }
    if (timeZone != null) {
      return timeZone;
    }
    if (timeZoneOffset != null) {
      return TimeZone.class.getCanonicalName() + ".createTimeZone("
          + timeZoneOffset + ")";
    }
    return null;
  }

  private JType getIntType(TypeOracle oracle) {
    try {
      return oracle.parse("int");
    } catch (TypeOracleException e) {
      throw new RuntimeException(e);
    }
  }

  private boolean hasDateTimeFormatAndTimeZoneConstructor(
      TypeOracle typeOracle, JClassType type) {
    JType dateTimeFormatType = typeOracle.findType(DateTimeFormat.class.getName());
    JType timeZoneType = typeOracle.findType(TimeZone.class.getName());
    return type.findConstructor(new JType[] {dateTimeFormatType, timeZoneType}) != null;
  }

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

  private boolean hasTimeZone(XMLElement elem) {
    return elem.hasAttribute("timezone") || elem.hasAttribute("timezoneOffset");
  }

  private String[] makeArgs(String format, String timeZone) {
    if (timeZone == null) {
      return new String[] {format};
    }
    return new String[] {format, timeZone};
  }

  private String makeGetFormat(String format) {
    return DateTimeFormat.class.getCanonicalName() + ".getFormat(" + format
        + ")";
  }
}
