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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

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

/**
 * Design time implementation of {@link DesignTimeUtils}.
 */
public class DesignTimeUtilsImpl implements DesignTimeUtils {
  private final Map<Element, String> elementPaths = new HashMap<Element, String>();
  private final Map<String, String> attributes = new HashMap<String, String>();

  public void addDeclarations(IndentedWriter w) {
    // handler
    w.write("public static interface DTObjectHandler {");
    w.write("  void handle(String path, Object object);");
    w.write("}");
    w.write("public DTObjectHandler dtObjectHandler;");
    // attributes
    w.write("public final java.util.Map dtAttributes = new java.util.HashMap();");
    w.write("private void dtPutAttribute(String key, Object...values) {");
    w.write("  if (values.length == 1) {");
    w.write("    dtAttributes.put(key, values[0]);");
    w.write("  } else {");
    w.write("    dtAttributes.put(key, java.util.Arrays.asList(values));");
    w.write("  }");
    w.write("}");
  }

  public String getImplName(String implName) {
    return implName + "_designTime" + System.currentTimeMillis();
  }

  public String getPath(Element element) {
    return elementPaths.get(element);
  }

  public String getTemplateContent(String path) {
    return System.getProperty("gwt.UiBinder.designTime " + path);
  }

  public void handleUIObject(Statements writer, XMLElement elem,
      String fieldName) {
    writer.addStatement(
        "if (dtObjectHandler != null) dtObjectHandler.handle(\"%s\", %s);",
        elem.getDesignTimePath(), fieldName);
  }

  public void putAttribute(XMLElement elem, String name, String value) {
    String path = elem.getDesignTimePath();
    String key = path + " " + name;
    attributes.put(key, value);
  }

  public void putAttribute(XMLElement elem, String name, String[] values) {
    if (values.length == 0) {
      return;
    }
    StringBuilder sb = new StringBuilder();
    for (String value : values) {
      if (sb.length() != 0) {
        sb.append(", ");
      }
      sb.append(value);
    }
    sb.insert(0, "new String[] {");
    sb.append("}");
    putAttribute(elem, name, sb.toString());
  }

  public void rememberPathForElements(Document doc) {
    rememberPathForElements(doc.getDocumentElement(), "0");
  }

  public void writeAttributes(Statements writer) {
    for (Map.Entry<String, String> entry : attributes.entrySet()) {
      String key = entry.getKey();
      String value = entry.getValue();
      writer.addStatement("dtPutAttribute(\"%s\", %s);", key, value);
    }
    attributes.clear();
  }

  /**
   * @return remembered attributes, used during tests only.
   */
  Map<String, String> getAttributes() {
    return attributes;
  }

  /**
   * Recursive implementation of {@link #rememberPathForElements(Document)}.
   */
  private void rememberPathForElements(Element element, String path) {
    elementPaths.put(element, path);
    NodeList childNodes = element.getChildNodes();
    int elementIndex = 0;
    for (int i = 0; i < childNodes.getLength(); ++i) {
      Node childNode = childNodes.item(i);
      if (childNode.getNodeType() == Node.ELEMENT_NODE) {
        Element childElement = (Element) childNode;
        rememberPathForElements(childElement, path + "/" + elementIndex++);
      }
    }
  }
}