/*
 * Copyright 2008 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.client;

import com.google.gwt.core.client.JavaScriptObject;

/**
 * All HTML element interfaces derive from this class.
 */
public class Element extends Node {

  /**
   * Assert that the given {@link Node} is an {@link Element} and automatically
   * typecast it.
   */
  public static Element as(JavaScriptObject o) {
    assert is(o);
    return (Element) o;
  }

  /**
   * Assert that the given {@link Node} is an {@link Element} and automatically
   * typecast it.
   */
  public static Element as(Node node) {
    assert is(node);
    return (Element) node;
  }

  /**
   * Determines whether the given {@link JavaScriptObject} can be cast to an
   * {@link Element}. A <code>null</code> object will cause this method to
   * return <code>false</code>.
   */
  public static boolean is(JavaScriptObject o) {
    if (Node.is(o)) {
      return is((Node) o);
    }
    return false;
  }

  /**
   * Determine whether the given {@link Node} can be cast to an {@link Element}.
   * A <code>null</code> node will cause this method to return
   * <code>false</code>.
   */
  public static boolean is(Node node) {
    return (node != null) && (node.getNodeType() == Node.ELEMENT_NODE);
  }

  protected Element() {
  }

  /**
   * Adds a name to this element's class property. If the name is already
   * present, this method has no effect.
   * 
   * @param className the class name to be added
   * @see #setClassName(String)
   */
  public final void addClassName(String className) {
    assert (className != null) : "Unexpectedly null class name";

    className = className.trim();
    assert (className.length() != 0) : "Unexpectedly empty class name";

    // Get the current style string.
    String oldClassName = getClassName();
    int idx = oldClassName.indexOf(className);

    // Calculate matching index.
    while (idx != -1) {
      if (idx == 0 || oldClassName.charAt(idx - 1) == ' ') {
        int last = idx + className.length();
        int lastPos = oldClassName.length();
        if ((last == lastPos)
            || ((last < lastPos) && (oldClassName.charAt(last) == ' '))) {
          break;
        }
      }
      idx = oldClassName.indexOf(className, idx + 1);
    }

    // Only add the style if it's not already present.
    if (idx == -1) {
      if (oldClassName.length() > 0) {
        oldClassName += " ";
      }
      setClassName(oldClassName + className);
    }
  }

  /**
   * Removes keyboard focus from this element.
   */
  public final native void blur() /*-{
    this.blur();
  }-*/;

  /**
   * Dispatched the given event with this element as its target. The event will
   * go through all phases of the browser's normal event dispatch mechanism.
   * 
   * Note: Because the browser's normal dispatch mechanism is used, exceptions
   * thrown from within handlers triggered by this method cannot be caught by
   * wrapping this method in a try/catch block. Such exceptions will be caught
   * by the
   * {@link com.google.gwt.core.client.GWT#setUncaughtExceptionHandler(com.google.gwt.core.client.GWT.UncaughtExceptionHandler) uncaught exception handler}
   * as usual.
   * 
   * @param evt the event to be dispatched
   */
  public final void dispatchEvent(NativeEvent evt) {
    DOMImpl.impl.dispatchEvent(this, evt);
  }

  /**
   * Gives keyboard focus to this element.
   */
  public final native void focus() /*-{
    this.focus();
  }-*/;

  /**
   * Gets an element's absolute bottom coordinate in the document's coordinate
   * system.
   */
  public final int getAbsoluteBottom() {
    return getAbsoluteTop() + getOffsetHeight();
  }

  /**
   * Gets an element's absolute left coordinate in the document's coordinate
   * system.
   */
  public final int getAbsoluteLeft() {
    return DOMImpl.impl.getAbsoluteLeft(this);
  }

  /**
   * Gets an element's absolute right coordinate in the document's coordinate
   * system.
   */
  public final int getAbsoluteRight() {
    return getAbsoluteLeft() + getOffsetWidth();
  }

  /**
   * Gets an element's absolute top coordinate in the document's coordinate
   * system.
   */
  public final int getAbsoluteTop() {
    return DOMImpl.impl.getAbsoluteTop(this);
  }

  /**
   * Retrieves an attribute value by name.  Attribute support can be
   * inconsistent across various browsers.  Consider using the accessors in
   * {@link Element} and its specific subclasses to retrieve attributes and
   * properties.
   * 
   * @param name The name of the attribute to retrieve
   * @return The Attr value as a string, or the empty string if that attribute
   *         does not have a specified or default value
   */
  public final String getAttribute(String name) {
    return DOMImpl.impl.getAttribute(this, name);
  }

  /**
   * The class attribute of the element. This attribute has been renamed due to
   * conflicts with the "class" keyword exposed by many languages.
   * 
   * @see <a
   *      href="http://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#adef-class">W3C
   *      HTML Specification</a>
   */
  public final native String getClassName() /*-{
     return this.className;
   }-*/;

  /**
   * Returns the inner height of an element in pixels, including padding but not
   * the horizontal scrollbar height, border, or margin.
   * 
   * @return the element's client height
   */
  public final native int getClientHeight() /*-{
    return this.clientHeight;
  }-*/;

  /**
   * Returns the inner width of an element in pixels, including padding but not
   * the vertical scrollbar width, border, or margin.
   * 
   * @return the element's client width
   */
  public final native int getClientWidth() /*-{
    return this.clientWidth;
  }-*/;

  /**
   * Specifies the base direction of directionally neutral text and the
   * directionality of tables.
   */
  public final native String getDir() /*-{
     return this.dir;
   }-*/;

  /**
   * Returns a NodeList of all descendant Elements with a given tag name, in the
   * order in which they are encountered in a preorder traversal of this Element
   * tree.
   * 
   * @param name The name of the tag to match on. The special value "*" matches
   *          all tags
   * @return A list of matching Element nodes
   */
  public final native NodeList<Element> getElementsByTagName(String name) /*-{
     return this.getElementsByTagName(name);
   }-*/;

  /**
   * The first child of element this element. If there is no such element, this
   * returns null.
   */
  public final Element getFirstChildElement() {
    return DOMImpl.impl.getFirstChildElement(this);
  }

  /**
   * The element's identifier.
   * 
   * @see <a
   *      href="http://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#adef-id">W3C
   *      HTML Specification</a>
   */
  public final native String getId() /*-{
     return this.id;
   }-*/;

  /**
   * All of the markup and content within a given element.
   */
  public final String getInnerHTML() {
    return DOMImpl.impl.getInnerHTML(this);
  }

  /**
   * The text between the start and end tags of the object.
   */
  public final String getInnerText() {
    return DOMImpl.impl.getInnerText(this);
  }

  /**
   * Language code defined in RFC 1766.
   */
  public final native String getLang() /*-{
     return this.lang;
   }-*/;

  /**
   * The element immediately following this element. If there is no such
   * element, this returns null.
   */
  public final Element getNextSiblingElement() {
    return DOMImpl.impl.getNextSiblingElement(this);
  }

  /**
   * The height of an element relative to the layout.
   */
  public final native int getOffsetHeight() /*-{
     return this.offsetHeight || 0;
   }-*/;

  /**
   * The number of pixels that the upper left corner of the current element is
   * offset to the left within the offsetParent node.
   */
  public final native int getOffsetLeft() /*-{
     return this.offsetLeft || 0;
   }-*/;

  /**
   * Returns a reference to the object which is the closest (nearest in the
   * containment hierarchy) positioned containing element.
   */
  public final native Element getOffsetParent() /*-{
     return this.offsetParent;
   }-*/;

  /**
   * The number of pixels that the upper top corner of the current element is
   * offset to the top within the offsetParent node.
   */
  public final native int getOffsetTop() /*-{
     return this.offsetTop || 0;
   }-*/;

  /**
   * The width of an element relative to the layout.
   */
  public final native int getOffsetWidth() /*-{
     return this.offsetWidth || 0;
   }-*/;

  /**
   * Gets a boolean property from this element.
   * 
   * @param name the name of the property to be retrieved
   * @return the property value
   */
  public final native boolean getPropertyBoolean(String name) /*-{
     return !!this[name];
   }-*/;

  /**
   * Gets a double property from this element.
   * 
   * @param name the name of the property to be retrieved
   * @return the property value
   */
  public final native double getPropertyDouble(String name) /*-{
     return parseFloat(this[name]) || 0.0;
   }-*/;

  /**
   * Gets an integer property from this element.
   * 
   * @param name the name of the property to be retrieved
   * @return the property value
   */
  public final native int getPropertyInt(String name) /*-{
     return parseInt(this[name]) || 0;
   }-*/;

  /**
   * Gets a JSO property from this element.
   *
   * @param name the name of the property to be retrieved
   * @return the property value
   */
  public final native JavaScriptObject getPropertyJSO(String name) /*-{
    return this[name] || null;
  }-*/;

  /**
   * Gets an object property from this element.
   *
   * @param name the name of the property to be retrieved
   * @return the property value
   */
  public final native Object getPropertyObject(String name) /*-{
    return this[name] || null;
  }-*/;

  /**
   * Gets a property from this element.
   * 
   * @param name the name of the property to be retrieved
   * @return the property value
   */
  public final native String getPropertyString(String name) /*-{
     return (this[name] == null) ? null : String(this[name]);
   }-*/;

  /**
   * The height of the scroll view of an element.
   */
  public final native int getScrollHeight() /*-{
     return this.scrollHeight || 0;
   }-*/;

  /**
   * The number of pixels that an element's content is scrolled from the left.
   * 
   * <p>
   * If the element is in RTL mode, this method will return a negative value of
   * the number of pixels scrolled from the right.
   * </p>
   */
  public final int getScrollLeft() {
    return DOMImpl.impl.getScrollLeft(this);
  }

  /**
   * The number of pixels that an element's content is scrolled from the top.
   */
  public final native int getScrollTop() /*-{
     return this.scrollTop || 0;
   }-*/;

  /**
   * The width of the scroll view of an element.
   */
  public final native int getScrollWidth() /*-{
     return this.scrollWidth || 0;
   }-*/;

  /**
   * Gets a string representation of this element (as outer HTML).
   * 
   * We do not override {@link #toString()} because it is final in
   * {@link com.google.gwt.core.client.JavaScriptObject}.
   * 
   * @return the string representation of this element
   */
  public final String getString() {
    return DOMImpl.impl.toString(this);
  }

  /**
   * Gets this element's {@link Style} object.
   */
  public final native Style getStyle() /*-{
     return this.style;
   }-*/;

  /**
   * The index that represents the element's position in the tabbing order.
   * 
   * @see <a href="http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#adef-tabindex">W3C HTML Specification</a>
   */
  public final int getTabIndex() {
    return DOMImpl.impl.getTabIndex(this);
  }

  /**
   * Gets the element's full tag name, including the namespace-prefix if
   * present.
   * 
   * @return the element's tag name
   */
  public final String getTagName() {
    return DOMImpl.impl.getTagName(this);
  }

  /**
   * The element's advisory title.
   */
  public final native String getTitle() /*-{
     return this.title;
   }-*/;

  /**
   * Determines whether an element has an attribute with a given name.
   *
   * <p>
   * Note that IE, prior to version 8, will return false-positives for names
   * that collide with element properties (e.g., style, width, and so forth).
   * </p>
   * 
   * @param name the name of the attribute
   * @return <code>true</code> if this element has the specified attribute
   */
  public final boolean hasAttribute(String name) {
    return DOMImpl.impl.hasAttribute(this, name);
  }

  /**
   * Determines whether this element has the given tag name.
   * 
   * @param tagName the tag name, including namespace-prefix (if present)
   * @return <code>true</code> if the element has the given tag name
   */
  public final boolean hasTagName(String tagName) {
    assert tagName != null : "tagName must not be null";
    return tagName.equals(getTagName());
  }

  /**
   * Removes an attribute by name.
   */
  public final native void removeAttribute(String name) /*-{
     this.removeAttribute(name);
   }-*/;

  /**
   * Removes a name from this element's class property. If the name is not
   * present, this method has no effect.
   * 
   * @param className the class name to be added
   * @see #setClassName(String)
   */
  public final void removeClassName(String className) {
    assert (className != null) : "Unexpectedly null class name";

    className = className.trim();
    assert (className.length() != 0) : "Unexpectedly empty class name";

    // Get the current style string.
    String oldStyle = getClassName();
    int idx = oldStyle.indexOf(className);

    // Calculate matching index.
    while (idx != -1) {
      if (idx == 0 || oldStyle.charAt(idx - 1) == ' ') {
        int last = idx + className.length();
        int lastPos = oldStyle.length();
        if ((last == lastPos)
            || ((last < lastPos) && (oldStyle.charAt(last) == ' '))) {
          break;
        }
      }
      idx = oldStyle.indexOf(className, idx + 1);
    }

    // Don't try to remove the style if it's not there.
    if (idx != -1) {
      // Get the leading and trailing parts, without the removed name.
      String begin = oldStyle.substring(0, idx).trim();
      String end = oldStyle.substring(idx + className.length()).trim();

      // Some contortions to make sure we don't leave extra spaces.
      String newClassName;
      if (begin.length() == 0) {
        newClassName = end;
      } else if (end.length() == 0) {
        newClassName = begin;
      } else {
        newClassName = begin + " " + end;
      }

      setClassName(newClassName);
    }
  }

  /**
   * Replace one class name with another.
   *
   * @param oldClassName the class name to be replaced
   * @param newClassName the class name to replace it
   */
  public final void replaceClassName(String oldClassName, String newClassName) {
    removeClassName(oldClassName);
    addClassName(newClassName);
  }

  /**
   * Scrolls this element into view.
   * 
   * <p>
   * This method crawls up the DOM hierarchy, adjusting the scrollLeft and
   * scrollTop properties of each scrollable element to ensure that the
   * specified element is completely in view. It adjusts each scroll position by
   * the minimum amount necessary.
   * </p>
   */
  public final void scrollIntoView() {
    DOMImpl.impl.scrollIntoView(this);
  }

  /**
   * Adds a new attribute. If an attribute with that name is already present in
   * the element, its value is changed to be that of the value parameter.
   * 
   * @param name The name of the attribute to create or alter
   * @param value Value to set in string form
   */
  public final native void setAttribute(String name, String value) /*-{
     this.setAttribute(name, value);
   }-*/;

  /**
   * The class attribute of the element. This attribute has been renamed due to
   * conflicts with the "class" keyword exposed by many languages.
   * 
   * @see <a
   *      href="http://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#adef-class">W3C
   *      HTML Specification</a>
   */
  public final native void setClassName(String className) /*-{
     this.className = className;
   }-*/;

  /**
   * Specifies the base direction of directionally neutral text and the
   * directionality of tables.
   */
  public final native void setDir(String dir) /*-{
     this.dir = dir;
   }-*/;

  /**
   * The element's identifier.
   * 
   * @see <a
   *      href="http://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#adef-id">W3C
   *      HTML Specification</a>
   */
  public final native void setId(String id) /*-{
     this.id = id;
   }-*/;

  /**
   * All of the markup and content within a given element.
   */
  public final native void setInnerHTML(String html) /*-{
     this.innerHTML = html || '';
   }-*/;

  /**
   * The text between the start and end tags of the object.
   */
  public final void setInnerText(String text) {
    DOMImpl.impl.setInnerText(this, text);
  }

  /**
   * Language code defined in RFC 1766.
   */
  public final native void setLang(String lang) /*-{
     this.lang = lang;
   }-*/;

  /**
   * Sets a boolean property on this element.
   * 
   * @param name the name of the property to be set
   * @param value the new property value
   */
  public final native void setPropertyBoolean(String name, boolean value) /*-{
     this[name] = value;
   }-*/;

  /**
   * Sets a double property on this element.
   * 
   * @param name the name of the property to be set
   * @param value the new property value
   */
  public final native void setPropertyDouble(String name, double value) /*-{
     this[name] = value;
   }-*/;

  /**
   * Sets an integer property on this element.
   * 
   * @param name the name of the property to be set
   * @param value the new property value
   */
  public final native void setPropertyInt(String name, int value) /*-{
     this[name] = value;
   }-*/;

  /**
   * Sets a JSO property on this element.
   *
   * @param name the name of the property to be set
   * @param value the new property value
   */
  public final native void setPropertyJSO(String name, JavaScriptObject value) /*-{
    this[name] = value;
  }-*/;

  /**
   * Sets an object property on this element.
   *
   * @param name the name of the property to be set
   * @param value the new property value
   */
  public final native void setPropertyObject(String name, Object value) /*-{
    this[name] = value;
  }-*/;

  /**
   * Sets a property on this element.
   * 
   * @param name the name of the property to be set
   * @param value the new property value
   */
  public final native void setPropertyString(String name, String value) /*-{
     this[name] = value;
   }-*/;

  /**
   * The number of pixels that an element's content is scrolled to the left.
   */
  public final void setScrollLeft(int scrollLeft) {
    DOMImpl.impl.setScrollLeft(this, scrollLeft);
  }

  /**
   * The number of pixels that an element's content is scrolled to the top.
   */
  public final native void setScrollTop(int scrollTop) /*-{
     this.scrollTop = scrollTop;
   }-*/;

  /**
   * The index that represents the element's position in the tabbing order.
   * 
   * @see <a href="http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#adef-tabindex">W3C HTML Specification</a>
   */
  public final native void setTabIndex(int tabIndex) /*-{
    this.tabIndex = tabIndex;
  }-*/;

  /**
   * The element's advisory title.
   */
  public final native void setTitle(String title) /*-{
     // Setting the title to null results in the string "null" being displayed
     // on some browsers.
     this.title = title || '';
   }-*/;
}
