/*
 * Copyright 2011 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.dom.builder.shared;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.core.shared.impl.StringCase;
import com.google.gwt.dom.client.Style.BorderStyle;
import com.google.gwt.dom.client.Style.Cursor;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Float;
import com.google.gwt.dom.client.Style.FontStyle;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.dom.client.Style.ListStyleType;
import com.google.gwt.dom.client.Style.OutlineStyle;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.TableLayout;
import com.google.gwt.dom.client.Style.TextAlign;
import com.google.gwt.dom.client.Style.TextDecoration;
import com.google.gwt.dom.client.Style.TextJustify;
import com.google.gwt.dom.client.Style.TextOverflow;
import com.google.gwt.dom.client.Style.TextTransform;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.VerticalAlign;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.safecss.shared.SafeStylesUtils;
import com.google.gwt.safehtml.shared.SafeUri;

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

/**
 * Builds the style object.
 */
class HtmlStylesBuilder implements StylesBuilder {

  /**
   * A very fast map implemented using a {@link JavaScriptObject} when running
   * in production.
   */
  private static interface FastStringMap {
    /**
     * Get a value.
     * 
     * @return the value, or null if not in the map
     */
    String get(String key);

    /**
     * Set a value.
     */
    void put(String key, String value);
  }

  /**
   * JRE implementation of {@link FastStringMap}.
   */
  private static class FastStringMapJre implements FastStringMap {

    private final Map<String, String> map = new HashMap<String, String>();

    @Override
    public String get(String key) {
      return map.get(key);
    }

    @Override
    public void put(String key, String value) {
      map.put(key, value);
    }
  }

  /**
   * Native implementation of {@link FastStringMap}.
   * 
   * The native implementation sets and retrieves properties on a
   * {@link JavaScriptObject}, which avoids the dynamic casts associated with
   * the emulated version of {@link java.util.Map}.
   */
  private static class FastStringMapClient implements FastStringMap {

    private final JavaScriptObject map = JavaScriptObject.createObject();

    @Override
    public String get(String key) {
      return getImpl(map, key);
    }

    @Override
    public void put(String key, String value) {
      putImpl(map, key, value);
    }

    private native String getImpl(JavaScriptObject map, String key) /*-{
      return map[key] || null;
    }-*/;

    private native void putImpl(JavaScriptObject map, String key, String value) /*-{
      map[key] = value;
    }-*/;
  }

  /**
   * A map of camelCase style properties to their hyphenated equivalents.
   * 
   * The set of style property names is limited, and common ones are reused
   * frequently, so caching saves us from converting every style property name
   * from camelCase to hyphenated form.
   */
  private static FastStringMap camelCaseMap;

  /**
   * Regex to match a word in a camelCase phrase. A word starts with an
   * uppercase or lowercase letter, followed by zero or more non-uppercase
   * letters. For example, in the camelCase phrase backgroundUrl, the pattern
   * matches "background" and "Url".
   * 
   * This pattern is not used to validate the style property name.
   * {@link SafeStylesUtils} performs a more detailed check.
   */
  private static RegExp camelCaseWord;

  /**
   * Regex to match a word that starts with an uppercase letter.
   */
  private static RegExp caseWord;

  /**
   * Convert a camelCase or hyphenated string to a hyphenated string.
   * 
   * @param name the camelCase or hyphenated string to convert
   * @return the hyphenated string
   */
  // Visible for testing
  static String toHyphenatedForm(String name) {
    // Static initializers.
    if (camelCaseWord == null) {
      camelCaseMap = GWT.isClient() ? new FastStringMapClient() : new FastStringMapJre();
      camelCaseWord = RegExp.compile("([A-Za-z])([^A-Z]*)", "g");
      caseWord = RegExp.compile("[A-Z]([^A-Z]*)");
    }

    // Early exit if already in hyphenated form.
    if (name.contains("-")) {
      return name;
    }

    // Check for the name in the cache.
    String hyphenated = camelCaseMap.get(name);

    // Convert the name to hyphenated format if not in the cache.
    if (hyphenated == null) {
      hyphenated = "";
      MatchResult matches;
      while ((matches = camelCaseWord.exec(name)) != null) {
        String word = matches.getGroup(0);
        if (caseWord.exec(word) == null) {
          // The first letter is already lowercase, probably the first word.
          hyphenated += word;
        } else {
          // Hyphenate the first letter.
          hyphenated += "-" + StringCase.toLower(matches.getGroup(1));
          if (matches.getGroupCount() > 1) {
            hyphenated += matches.getGroup(2);
          }
        }
      }
      camelCaseMap.put(name, hyphenated);
    }

    return hyphenated;
  }

  private final HtmlBuilderImpl delegate;

  /**
   * Construct a new {@link HtmlStylesBuilder}.
   * 
   * @param delegate the delegate that builds the style
   */
  HtmlStylesBuilder(HtmlBuilderImpl delegate) {
    this.delegate = delegate;
  }

  @Override
  public StylesBuilder backgroundImage(SafeUri uri) {
    return delegate.styleProperty(SafeStylesUtils.forBackgroundImage(uri));
  }

  @Override
  public StylesBuilder borderStyle(BorderStyle value) {
    return delegate.styleProperty(SafeStylesUtils.forBorderStyle(value));
  }

  @Override
  public StylesBuilder borderWidth(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forBorderWidth(value, unit));
  }

  @Override
  public StylesBuilder bottom(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forBottom(value, unit));
  }

  @Override
  public StylesBuilder cursor(Cursor value) {
    return delegate.styleProperty(SafeStylesUtils.forCursor(value));
  }

  @Override
  public StylesBuilder display(Display value) {
    return delegate.styleProperty(SafeStylesUtils.forDisplay(value));
  }

  @Override
  public void endStyle() {
    delegate.endStyle();
  }

  @Override
  public StylesBuilder floatprop(Float value) {
    return delegate.styleProperty(SafeStylesUtils.forFloat(value));
  }

  @Override
  public StylesBuilder fontSize(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forFontSize(value, unit));
  }

  @Override
  public StylesBuilder fontStyle(FontStyle value) {
    return delegate.styleProperty(SafeStylesUtils.forFontStyle(value));
  }

  @Override
  public StylesBuilder fontWeight(FontWeight value) {
    return delegate.styleProperty(SafeStylesUtils.forFontWeight(value));
  }

  @Override
  public StylesBuilder height(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forHeight(value, unit));
  }

  @Override
  public StylesBuilder left(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forLeft(value, unit));
  }

  @Override
  public StylesBuilder lineHeight(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forLineHeight(value, unit));
  }

  @Override
  public StylesBuilder listStyleType(ListStyleType value) {
    return delegate.styleProperty(SafeStylesUtils.forListStyleType(value));
  }

  @Override
  public StylesBuilder margin(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forMargin(value, unit));
  }

  @Override
  public StylesBuilder marginBottom(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forMarginBottom(value, unit));
  }

  @Override
  public StylesBuilder marginLeft(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forMarginLeft(value, unit));
  }

  @Override
  public StylesBuilder marginRight(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forMarginRight(value, unit));
  }

  @Override
  public StylesBuilder marginTop(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forMarginTop(value, unit));
  }

  @Override
  public StylesBuilder opacity(double value) {
    return delegate.styleProperty(SafeStylesUtils.forOpacity(value));
  }

  @Override
  public StylesBuilder outlineStyle(OutlineStyle value) {
    return delegate.styleProperty(SafeStylesUtils.forOutlineStyle(value));
  }

  @Override
  public StylesBuilder outlineWidth(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forOutlineWidth(value, unit));
  }

  @Override
  public StylesBuilder overflow(Overflow value) {
    return delegate.styleProperty(SafeStylesUtils.forOverflow(value));
  }

  @Override
  public StylesBuilder overflowX(Overflow value) {
    return delegate.styleProperty(SafeStylesUtils.forOverflowX(value));
  }

  @Override
  public StylesBuilder overflowY(Overflow value) {
    return delegate.styleProperty(SafeStylesUtils.forOverflowY(value));
  }

  @Override
  public StylesBuilder padding(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forPadding(value, unit));
  }

  @Override
  public StylesBuilder paddingBottom(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forPaddingBottom(value, unit));
  }

  @Override
  public StylesBuilder paddingLeft(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forPaddingLeft(value, unit));
  }

  @Override
  public StylesBuilder paddingRight(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forPaddingRight(value, unit));
  }

  @Override
  public StylesBuilder paddingTop(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forPaddingTop(value, unit));
  }

  @Override
  public StylesBuilder position(Position value) {
    return delegate.styleProperty(SafeStylesUtils.forPosition(value));
  }

  @Override
  public StylesBuilder right(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forRight(value, unit));
  }

  @Override
  public StylesBuilder tableLayout(TableLayout value) {
    return delegate.styleProperty(SafeStylesUtils.forTableLayout(value));
  }

  @Override
  public StylesBuilder textAlign(TextAlign value) {
    return delegate.styleProperty(SafeStylesUtils.forTextAlign(value));
  }

  @Override
  public StylesBuilder textDecoration(TextDecoration value) {
    return delegate.styleProperty(SafeStylesUtils.forTextDecoration(value));
  }

  @Override
  public StylesBuilder textIndent(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forTextIndent(value, unit));
  }

  @Override
  public StylesBuilder textJustify(TextJustify value) {
    return delegate.styleProperty(SafeStylesUtils.forTextJustify(value));
  }

  @Override
  public StylesBuilder textOverflow(TextOverflow value) {
    return delegate.styleProperty(SafeStylesUtils.forTextOverflow(value));
  }

  @Override
  public StylesBuilder textTransform(TextTransform value) {
    return delegate.styleProperty(SafeStylesUtils.forTextTransform(value));
  }

  @Override
  public StylesBuilder top(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forTop(value, unit));
  }

  @Override
  public StylesBuilder trustedBackgroundColor(String value) {
    return delegate.styleProperty(SafeStylesUtils.forTrustedBackgroundColor(value));
  }

  @Override
  public StylesBuilder trustedBackgroundImage(String value) {
    return delegate.styleProperty(SafeStylesUtils.forTrustedBackgroundImage(value));
  }

  @Override
  public StylesBuilder trustedBorderColor(String value) {
    return delegate.styleProperty(SafeStylesUtils.forTrustedBorderColor(value));
  }

  @Override
  public StylesBuilder trustedColor(String value) {
    return delegate.styleProperty(SafeStylesUtils.forTrustedColor(value));
  }

  @Override
  public StylesBuilder trustedOutlineColor(String value) {
    return delegate.styleProperty(SafeStylesUtils.forTrustedOutlineColor(value));
  }

  @Override
  public StylesBuilder trustedProperty(String name, double value, Unit unit) {
    name = toHyphenatedForm(name);
    return delegate.styleProperty(SafeStylesUtils.fromTrustedNameAndValue(name, value, unit));
  }

  @Override
  public StylesBuilder trustedProperty(String name, String value) {
    name = toHyphenatedForm(name);
    return delegate.styleProperty(SafeStylesUtils.fromTrustedNameAndValue(name, value));
  }

  @Override
  public StylesBuilder verticalAlign(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forVerticalAlign(value, unit));
  }

  @Override
  public StylesBuilder verticalAlign(VerticalAlign value) {
    return delegate.styleProperty(SafeStylesUtils.forVerticalAlign(value));
  }

  @Override
  public StylesBuilder visibility(Visibility value) {
    return delegate.styleProperty(SafeStylesUtils.forVisibility(value));
  }

  @Override
  public StylesBuilder width(double value, Unit unit) {
    return delegate.styleProperty(SafeStylesUtils.forWidth(value, unit));
  }

  @Override
  public StylesBuilder zIndex(int value) {
    return delegate.styleProperty(SafeStylesUtils.forZIndex(value));
  }
}
