/*
 * 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.user.client.ui;

import com.google.gwt.dom.client.Element;
import com.google.gwt.i18n.client.BidiUtils;
import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.i18n.shared.BidiFormatter;
import com.google.gwt.i18n.shared.DirectionEstimator;
import com.google.gwt.i18n.shared.HasDirectionEstimator;
import com.google.gwt.i18n.shared.WordCountDirectionEstimator;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.annotations.IsSafeHtml;
import com.google.gwt.safehtml.shared.annotations.SuppressIsSafeHtmlCastCheck;

/**
 * A helper class for displaying bidi (i.e. potentially opposite-direction) text 
 * or HTML in an element.
 * Note: this class assumes that callers perform all their text/html and
 * direction manipulations through it alone.
 */
public class DirectionalTextHelper implements HasDirectionEstimator {

  /**
   * A default direction estimator instance.
   */
  public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR =
      WordCountDirectionEstimator.get();

  /**
   * The DirectionEstimator object.
   */
  private DirectionEstimator directionEstimator;

  /**
   * The target element.
   */
  private final Element element;

  /**
   * The initial direction of the element.
   */
  private Direction initialElementDir;

  /**
   * Whether direction was explicitly set on the last {@code setTextOrHtml}
   * call. If so, {@link #setDirectionEstimator} will refrain from modifying the
   * direction until {@link #setTextOrHtml} is called without specifying an
   * explicit direction.
   */
  private boolean isDirectionExplicitlySet;

  /**
   * Whether the element is inline (e.g. a &lt;span&gt; element, but not a block
   * element like &lt;div&gt;).
   * This is needed because direction is handled differently for inline elements
   * and for non-inline elements.
   */
  private final boolean isElementInline;

  /**
   * Whether the element contains a nested &lt;span&gt; element used to
   * indicate the content's direction.
   * <p>
   * The element itself is used for this purpose when it is a block element
   * (i.e. !isElementInline), but doing so on an inline element often results in
   * garbling what follows it. Thus, when the element is inline, a nested
   * &lt;span&gt; must be used to carry the content's direction, with an LRM or
   * RLM character afterwards to prevent the garbling.
   */
  private boolean isSpanWrapped;

  /**
   * The direction of the element's content.
   * Note: this may not match the direction attribute of the element itself.
   * See
   * {@link #setText(String, com.google.gwt.i18n.client.HasDirection.Direction, boolean)
   * setText(String, Direction, boolean)}
   * for details.
   */
  private Direction textDir;

  /**
   * @param element The widget's element holding text.
   * @param isElementInline Whether the element is an inline element.
   */
  public DirectionalTextHelper(Element element, boolean isElementInline) {
    this.element = element;
    this.isElementInline = isElementInline;
    isSpanWrapped = false;
    this.initialElementDir = BidiUtils.getDirectionOnElement(element);
    textDir = initialElementDir;
    // setDirectionEstimator shouldn't refresh appearance of initial empty text.
    isDirectionExplicitlySet = true;
  }

  public DirectionEstimator getDirectionEstimator() {
    return directionEstimator;
  }

  public Direction getTextDirection() {
    return textDir;
  }

  /**
   * Get the inner text of the element, taking the inner span wrap into
   * consideration, if needed.
   *
   * @return the text
   */
  public String getText() {
    return getTextOrHtml(false /* isHtml */);
  }

  /**
   * Get the inner html of the element, taking the inner span wrap into
   * consideration, if needed.
   *
   * @return the html
   */
  public String getHtml() {
    return getTextOrHtml(true /* isHtml */);
  }

  /**
   * Get the inner text or html of the element, taking the inner span wrap into consideration, if
   * needed. Prefer using {@link #getText} or {@link #getHtml} instead of this method.
   * 
   * @param isHtml true to get the inner html, false to get the inner text
   * @return the text or html
   */
  public String getTextOrHtml(boolean isHtml) {
    Element elem = isSpanWrapped ? element.getFirstChildElement() : element;
    return isHtml ? elem.getInnerHTML() : elem.getInnerText();
  }

  /**
   * Provides implementation for HasDirection's method setDirection (normally
   * deprecated), dealing with backwards compatibility issues.
   * @deprecated
   */
  @Deprecated
  @SuppressIsSafeHtmlCastCheck
  public void setDirection(Direction direction) {
    BidiUtils.setDirectionOnElement(element, direction);
    initialElementDir = direction;

    /*
     * For backwards compatibility, assure there's no span wrap, and update the
     * content direction.
     */
    setInnerTextOrHtml(getHtml(), true); // TODO: mXSS?
    isSpanWrapped = false;
    textDir = initialElementDir;
    isDirectionExplicitlySet = true;
  }

  /**
   * See note at
   * {@link #setDirectionEstimator(com.google.gwt.i18n.shared.DirectionEstimator)}.
   */
  public void setDirectionEstimator(boolean enabled) {
    setDirectionEstimator(enabled ? DEFAULT_DIRECTION_ESTIMATOR : null);
  }

  /**
   * Note: if the element already has non-empty content, this will update
   * its direction according to the new estimator's result. This may cause
   * flicker, and thus should be avoided; DirectionEstimator should be set
   * before the element has any content.
   */
  @SuppressIsSafeHtmlCastCheck
  public void setDirectionEstimator(DirectionEstimator directionEstimator) {
    this.directionEstimator = directionEstimator;
    /* 
     * Refresh appearance unless direction was explicitly set on last
     * setTextOrHtml call.
     */
    if (!isDirectionExplicitlySet) {
      setHtml(getHtml()); // TODO: mXSS
    }
  }

  /**
   * Sets the element's content to the given value (plain text).
   * If direction estimation is off, the direction is verified to match the
   * element's initial direction. Otherwise, the direction is affected as
   * described at
   * {@link #setText(String, com.google.gwt.i18n.client.HasDirection.Direction)
   * setText(String, Direction)}.
   *
   * @param content the element's new content
   */
  @SuppressIsSafeHtmlCastCheck
  public void setText(String content) {
    setTextOrHtml(content, false /* isHtml */);
  }

  /**
   * Sets the element's content to the given value (html).
   * If direction estimation is off, the direction is verified to match the
   * element's initial direction. Otherwise, the direction is affected as
   * described at
   * {@link #setHtml(String, com.google.gwt.i18n.client.HasDirection.Direction)
   * setHtml(String, Direction)}.
   *
   * @param content the element's new content
   */
  public void setHtml(SafeHtml content) {
    setHtml(content.asString());
  }

  /**
   * Sets the element's content to the given value (html).
   * If direction estimation is off, the direction is verified to match the
   * element's initial direction. Otherwise, the direction is affected as
   * described at
   * {@link #setHtml(String, com.google.gwt.i18n.client.HasDirection.Direction)
   * setHtml(String, Direction)}.
   *
   * @param content the element's new content
   */
  public void setHtml(@IsSafeHtml String content) {
    setTextOrHtml(content, true /* isHtml */);
  }

  /**
   * Sets the element's content to the given value (either plain text or HTML).
   * Prefer using {@link #setText(String) setText} or {@link #setHtml(String) setHtml} instead of
   * this method.
   *
   * @param content the element's new content
   * @param isHtml whether the content is HTML
   */
  public void setTextOrHtml(@IsSafeHtml String content, boolean isHtml) {
    if (directionEstimator == null) {
      isSpanWrapped = false;
      setInnerTextOrHtml(content, isHtml);

      /*
       * Preserves the initial direction of the element. This is different from
       * passing the direction parameter explicitly as DEFAULT, which forces the
       * element to inherit the direction from its parent.
       */
      if (textDir != initialElementDir) {
        textDir = initialElementDir;
        BidiUtils.setDirectionOnElement(element, initialElementDir);
      }
    } else {
      setTextOrHtml(content, directionEstimator.estimateDirection(content,
          isHtml), isHtml);
    }
    isDirectionExplicitlySet = false;
  }

  /**
   * Sets the element's content to the given value (plain text), applying the
   * given direction.
   * <p>
   * Implementation details:
   * <ul>
   * <li> If the element is a block element, sets its dir attribute according
   * to the given direction.
   * <li> Otherwise (i.e. the element is inline), the direction is set using a
   * nested &lt;span dir=...&gt; element which holds the content of the element.
   * This nested span may be followed by a zero-width Unicode direction
   * character (LRM or RLM). This manipulation is necessary to prevent garbling
   * in case the direction of the element is opposite to the direction of its
   * context. See {@link com.google.gwt.i18n.shared.BidiFormatter} for more
   * details.
   * </ul>
   *
   * @param content the element's new content
   * @param dir the content's direction
   */
  @SuppressIsSafeHtmlCastCheck
  public void setText(String content, Direction dir) {
    setTextOrHtml(content, dir, false /* isHtml */);
  }

  /**
   * Sets the element's content to the given value (html), applying the given
   * direction.
   * <p>
   * Implementation details:
   * <ul>
   * <li> If the element is a block element, sets its dir attribute according
   * to the given direction.
   * <li> Otherwise (i.e. the element is inline), the direction is set using a
   * nested &lt;span dir=...&gt; element which holds the content of the element.
   * This nested span may be followed by a zero-width Unicode direction
   * character (LRM or RLM). This manipulation is necessary to prevent garbling
   * in case the direction of the element is opposite to the direction of its
   * context. See {@link com.google.gwt.i18n.shared.BidiFormatter} for more
   * details.
   * </ul>
   *
   * @param content the element's new content
   * @param dir the content's direction
   */
  public void setHtml(SafeHtml content, Direction dir) {
    setHtml(content.asString(), dir);
  }

  /**
   * Sets the element's content to the given value (html), applying the given
   * direction.
   * <p>
   * Implementation details:
   * <ul>
   * <li> If the element is a block element, sets its dir attribute according
   * to the given direction.
   * <li> Otherwise (i.e. the element is inline), the direction is set using a
   * nested &lt;span dir=...&gt; element which holds the content of the element.
   * This nested span may be followed by a zero-width Unicode direction
   * character (LRM or RLM). This manipulation is necessary to prevent garbling
   * in case the direction of the element is opposite to the direction of its
   * context. See {@link com.google.gwt.i18n.shared.BidiFormatter} for more
   * details.
   * </ul>
   *
   * @param content the element's new content
   * @param dir the content's direction
   */
  public void setHtml(@IsSafeHtml String content, Direction dir) {
    setTextOrHtml(content, dir, true /* isHtml */);
  }

  /**
   * Sets the element's content to the given value (either plain text or HTML),
   * applying the given direction. Prefer using
   * {@link #setText(String, com.google.gwt.i18n.client.HasDirection.Direction) setText} or
   * {@link #setHtml(String, com.google.gwt.i18n.client.HasDirection.Direction) setHtml}
   * instead of this method.
   *
   * @param content the element's new content
   * @param dir the content's direction
   * @param isHtml whether the content is HTML
   */
  public void setTextOrHtml(@IsSafeHtml String content, Direction dir, boolean isHtml) {
    textDir = dir;
    // Set the text and the direction.
    if (isElementInline) {
      isSpanWrapped = true;
      element.setInnerHTML(BidiFormatter.getInstanceForCurrentLocale(
          true /* alwaysSpan */).spanWrapWithKnownDir(dir, content, isHtml));
    } else {
      isSpanWrapped = false;
      BidiUtils.setDirectionOnElement(element, dir);
      setInnerTextOrHtml(content, isHtml);
    }
    isDirectionExplicitlySet = true;
  }

  private void setInnerTextOrHtml(@IsSafeHtml String content, boolean isHtml) {
    if (isHtml) {
      element.setInnerHTML(content);
    } else {
      element.setInnerText(content);
    }
  }
}
