/*
 * 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.editor.rebind.model;

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.TypeOracle;
import com.google.gwt.editor.client.CompositeEditor;
import com.google.gwt.editor.client.HasEditorDelegate;
import com.google.gwt.editor.client.HasEditorErrors;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.editor.client.ValueAwareEditor;


/**
 * Describes how an Editor is related to bean properties. This type contains
 * answers to questions asked by the generator code.
 */
public class EditorData {
  /**
   * Used to construct EditorData objects.
   */
  public static class Builder {
    private EditorAccess access;
    private EditorData data = new EditorData();
    private final TreeLogger logger;
    private EditorData parent;

    public Builder(TreeLogger logger) {
      this.logger = logger;
    }

    public Builder access(EditorAccess access) throws UnableToCompleteException {
      this.access = access;
      data.declaredPath = access.getPath();
      data.editorType = access.getEditorType();
      data.editedType = EditorModel.calculateEditedType(logger, data.editorType);
      data.simpleExpression = access.getExpresson();

      TypeOracle oracle = data.editorType.getOracle();
      JClassType leafType = oracle.findType(LeafValueEditor.class.getName());
      data.isLeaf = leafType.isAssignableFrom(data.editorType);

      JClassType composedType = oracle.findType(CompositeEditor.class.getName());
      data.isCompositeEditor = composedType.isAssignableFrom(data.editorType);

      JClassType hasDelegateType = oracle.findType(HasEditorDelegate.class.getName());
      JClassType hasEditorErrorsType = oracle.findType(HasEditorErrors.class.getName());
      data.isDelegateRequired = hasDelegateType.isAssignableFrom(data.editorType)
          || hasEditorErrorsType.isAssignableFrom(data.editorType)
          || !ModelUtils.isValueType(oracle, data.editedType);

      JClassType valueAwareType = oracle.findType(ValueAwareEditor.class.getName());
      data.isValueAware = valueAwareType.isAssignableFrom(data.editorType);

      return this;
    }

    public Builder beanOwnerExpression(String value) {
      data.beanOwnerExpression = value;
      return this;
    }

    public Builder beanOwnerGuard(String value) {
      data.beanOwnerGuard = value;
      return this;
    }

    public EditorData build() throws UnableToCompleteException {
      if (data == null) {
        throw new IllegalStateException();
      }
      try {
        data.editorExpression = (parent == null ? ""
            : (parent.getExpression() + "."))
            + access.getExpresson();
        data.path = (parent == null ? "" : (parent.getPath() + "."))
            + access.getPath();

        if (data.isCompositeEditor) {
          TreeLogger compositeLogger = logger.branch(TreeLogger.DEBUG,
              "Examining composite editor at " + data.path);
          JClassType subEditorType = EditorModel.calculateCompositeTypes(data.editorType)[1];
          data.composedData = new Builder(compositeLogger).access(
              EditorAccess.root(subEditorType)).parent(data).build();
        }
        return data;
      } finally {
        data = null;
      }
    }

    public Builder getterName(String value) {
      data.getterName = value;
      return this;
    }

    public Builder parent(EditorData value) {
      parent = value;
      return this;
    }

    public Builder propertyOwnerType(JClassType ownerType) {
      data.propertyOwnerType = ownerType;
      return this;
    }

    public Builder setterName(String value) {
      data.setterName = value;
      return this;
    }
  }

  private String beanOwnerExpression = "";
  private String beanOwnerGuard = "true";
  private EditorData composedData;
  private String declaredPath;
  private JClassType editedType;
  private JClassType editorType;
  private String editorExpression;
  private String getterName;
  private boolean isLeaf;
  private boolean isCompositeEditor;
  private boolean isDelegateRequired;
  private boolean isValueAware;
  private String path;
  private JClassType propertyOwnerType;
  private String setterName;
  private String simpleExpression;

  private EditorData() {
  }

  public String getBeanOwnerExpression() {
    return beanOwnerExpression;
  }

  public String getBeanOwnerGuard(String ownerExpression) {
    return String.format(beanOwnerGuard, ownerExpression);
  }

  public EditorData getComposedData() {
    return composedData;
  }

  /**
   * Gets the path specified by the {@code @Path} annotation or inferred via
   * convention.
   */
  public String getDeclaredPath() {
    return declaredPath;
  }

  public JClassType getEditedType() {
    return editedType;
  }

  public JClassType getEditorType() {
    return editorType;
  }

  /**
   * Returns a complete expression to retrieve the editor.
   */
  public String getExpression() {
    return editorExpression;
  }

  public String getGetterName() {
    return getterName;
  }

  /**
   * Returns the complete path of the editor, relative to the root object.
   */
  public String getPath() {
    return path;
  }

  public String getPropertyName() {
    return getPath().substring(getPath().lastIndexOf('.') + 1);
  }

  /**
   * Mainly useful for nested properties where there may not be an editor for
   * the enclosing instance (e.g. <code>person.manager.name</code>).
   */
  public JClassType getPropertyOwnerType() {
    return propertyOwnerType;
  }

  public String getSetterName() {
    return setterName;
  }

  /**
   * Returns an expression relative to the enclosing Editor to retrieve the
   * editor.
   */
  public String getSimpleExpression() {
    return simpleExpression;
  }

  /**
   * Indicates if the Editor is a {@link ComposedEditor .
   */
  public boolean isCompositeEditor() {
    return isCompositeEditor;
  }

  /**
   * Returns <code>true</code> if the editor "reaches through" an interstitial
   * property.
   */
  public boolean isDeclaredPathNested() {
    return declaredPath.contains(".");
  }

  /**
   * Returns <code>true<code> if the editor requires an EditorDelegate.
   */
  public boolean isDelegateRequired() {
    return isDelegateRequired;
  }

  /**
   * Indicates if the Editor extends {@link LeafValueEditor}.
   */
  public boolean isLeafValueEditor() {
    return isLeaf;
  }

  /**
   * Indicates if the Editor extends {@link ValueAwareEditor}.
   */
  public boolean isValueAwareEditor() {
    return isValueAware;
  }

  /**
   * For debugging use only.
   */
  @Override
  public String toString() {
    return getPath() + " = " + getEditorType();
  }
}