/*
 * 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;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.junit.DoNotRunWith;
import com.google.gwt.junit.Platform;
import com.google.gwt.junit.client.GWTTestCase;

import java.util.Locale;

/**
 * Element tests (many stolen from DOMTest).
 */
public class ElementTest extends GWTTestCase {

  @Override
  public String getModuleName() {
    return "com.google.gwt.dom.DOMTest";
  }

  public void testAddClassName() {
    DivElement div = Document.get().createDivElement();
    div.setClassName("foo");

    assertTrue(div.addClassName("bar"));
    assertEquals("foo bar", div.getClassName());

    assertTrue(div.addClassName("baz"));
    assertEquals("foo bar baz", div.getClassName());

    assertFalse(div.addClassName("baz"));
    assertEquals("foo bar baz", div.getClassName());
  }

  public void testRemoveClassName() {
    DivElement div = Document.get().createDivElement();
    div.setClassName("foo bar baz");

    assertTrue(div.removeClassName("bar"));
    assertEquals("foo baz", div.getClassName());

    assertFalse(div.removeClassName("bar"));
    assertEquals("foo baz", div.getClassName());

    assertTrue(div.removeClassName("baz"));
    assertEquals("foo", div.getClassName());

    assertTrue(div.removeClassName("foo"));
    assertEquals("", div.getClassName());
  }

  public void testHasClassName() {
    DivElement div = Document.get().createDivElement();
    div.setClassName("foo bar");

    assertTrue(div.hasClassName("bar"));
    assertTrue(div.hasClassName("foo"));

    div.setClassName("bar");
    assertFalse(div.hasClassName("foo"));
    assertTrue(div.hasClassName("bar"));
  }

  public void testToggleClassName() {
    DivElement div = Document.get().createDivElement();
    div.setClassName("foo bar baz");

    div.toggleClassName("bar");
    assertEquals("foo baz", div.getClassName());

    div.toggleClassName("bar");
    assertEquals("foo baz bar", div.getClassName());
  }

  public void testReplaceClassName() {
    DivElement div = Document.get().createDivElement();
    div.setClassName("foo bar baz");

    div.replaceClassName("bar", "tintin");
    assertEquals("foo baz tintin", div.getClassName());

    div.replaceClassName("bar", "tintin2");
    assertEquals("foo baz tintin tintin2", div.getClassName());
  }

  public void testIndexOfName() {
    assertEquals(-1, Element.indexOfName("", "foo"));

    assertEquals(-1, Element.indexOfName("foo", "fo"));
    assertEquals(-1, Element.indexOfName("foo", "fool"));

    assertEquals(-1, Element.indexOfName("bar fool", "foo"));
    assertEquals(-1, Element.indexOfName("bar fool baz", "foo"));

    assertEquals(0, Element.indexOfName("foo", "foo"));
    assertEquals(0, Element.indexOfName("foo bar", "foo"));
    assertEquals(4, Element.indexOfName("bar foo", "foo"));
    assertEquals(4, Element.indexOfName("bar foo baz", "foo"));
  }

  /**
   * firstChildElement, nextSiblingElement, previousSiblingElement.
   */
  public void testChildElements() {
    Document doc = Document.get();
    DivElement parent = doc.createDivElement();
    DivElement div0 = doc.createDivElement();
    DivElement div1 = doc.createDivElement();

    parent.appendChild(doc.createTextNode("foo"));
    parent.appendChild(div0);
    parent.appendChild(doc.createTextNode("bar"));
    parent.appendChild(div1);

    Element fc = parent.getFirstChildElement();
    Element ns = fc.getNextSiblingElement();
    Element ps = ns.getPreviousSiblingElement();
    assertEquals(div0, fc);
    assertEquals(div1, ns);
    assertEquals(div0, ps);

    assertNull(fc.getPreviousSiblingElement());
    assertNull(ns.getNextSiblingElement());
  }

  /**
   * Test round-trip of the 'disabled' property.
   */
  public void testDisabled() {
    ButtonElement button = Document.get().createPushButtonElement();
    assertFalse(button.isDisabled());
    button.setDisabled(true);
    assertTrue(button.isDisabled());

    InputElement input = Document.get().createTextInputElement();
    assertFalse(input.isDisabled());
    input.setDisabled(true);
    assertTrue(input.isDisabled());
    
    SelectElement select = Document.get().createSelectElement();
    assertFalse(select.isDisabled());
    select.setDisabled(true);
    assertTrue(select.isDisabled());
    
    OptGroupElement optgroup = Document.get().createOptGroupElement();
    assertFalse(optgroup.isDisabled());
    optgroup.setDisabled(true);
    assertTrue(optgroup.isDisabled());
  }

  /**
   * [get|set|remove]Attribute.
   */
  public void testElementAttribute() {
    DivElement div = Document.get().createDivElement();
    div.setAttribute("class", "testClass");
    String cssClass = div.getAttribute("class");
    assertEquals("testClass", cssClass);
    div.removeAttribute("class");
    cssClass = div.getAttribute("class");
    assertEquals("", cssClass);
  }

  /**
   * Ensure that the return type of an attribute is always a string. IE should
   * not return a numeric attribute based on the element property. See issue
   * 3238.
   */
  public void testElementAttributeNumeric() {
    DivElement div = Document.get().createDivElement();
    Document.get().getBody().appendChild(div);
    div.setInnerText("Hello World");
    div.getAttribute("offsetWidth").length();
    div.getAttribute("offsetWidth").trim().length();
    Document.get().getBody().removeChild(div);
  }

  public void testEmptyClassNameAssertion() {
    DivElement div = Document.get().createDivElement();

    if (getClass().desiredAssertionStatus()) {
      div.setClassName("primary");
      try {
        div.addClassName("");
        throw new Error();
      } catch (AssertionError e) {
        // This *should* throw.
      }

      try {
        div.addClassName(" ");
        throw new Error();
      } catch (AssertionError e) {
        // This *should* throw.
      }

      try {
        div.addClassName(null);
        throw new Error();
      } catch (AssertionError e) {
        // This *should* throw.
      }

      try {
        div.removeClassName("");
        throw new Error();
      } catch (AssertionError e) {
        // This *should* throw.
      }

      try {
        div.removeClassName(" ");
        throw new Error();
      } catch (AssertionError e) {
        // This *should* throw.
      }

      try {
        div.removeClassName(null);
        throw new Error();
      } catch (AssertionError e) {
        // This *should* throw.
      }

      assertEquals("primary", div.getClassName());
    }
  }

  /**
   * getAbsolute[Left|Top|Right|Bottom].
   */
  public void testGetAbsolutePosition() {
    final int border = 8;
    final int margin = 9;
    final int padding = 10;

    final int top = 15;
    final int left = 14;
    final int width = 128;
    final int height = 64;

    final Document doc = Document.get();
    final DivElement elem = doc.createDivElement();
    doc.getBody().appendChild(elem);

    elem.getStyle().setProperty("position", "absolute");
    elem.getStyle().setProperty("border", border + "px solid #000");
    elem.getStyle().setProperty("padding", padding + "px");
    elem.getStyle().setProperty("margin", margin + "px");

    elem.getStyle().setPropertyPx("top", top - doc.getBodyOffsetLeft());
    elem.getStyle().setPropertyPx("left", left - doc.getBodyOffsetTop());
    elem.getStyle().setPropertyPx("width", width);
    elem.getStyle().setPropertyPx("height", height);

    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
      @Override
      public void execute() {
        int absLeft = left + margin;
        int absTop = top + margin;
        int interiorDecorations = (border * 2) + (padding * 2);

        assertEquals(absLeft, elem.getAbsoluteLeft());
        assertEquals(absTop, elem.getAbsoluteTop());

        if (isIE6or7() && !doc.isCSS1Compat()) {
          // In IE/quirk, the interior decorations are considered part of the
          // width/height, so there's no need to account for them here.
          assertEquals(absLeft + width, elem.getAbsoluteRight());
          assertEquals(absTop + height, elem.getAbsoluteBottom());
        } else {
          assertEquals(absLeft + width + interiorDecorations,
              elem.getAbsoluteRight());
          assertEquals(absTop + height + interiorDecorations,
              elem.getAbsoluteBottom());
        }
      }
    });
  }

  /**
   * scroll[Left|Top], getAbsolute[Left|Top].
   */
  @DoNotRunWith(Platform.HtmlUnitLayout)
  public void testGetAbsolutePositionWhenBodyScrolled() {
    Document doc = Document.get();
    BodyElement body = doc.getBody();

    DivElement div = doc.createDivElement();
    body.appendChild(div);

    div.setInnerText("foo");
    div.getStyle().setPosition(Position.ABSOLUTE);
    div.getStyle().setLeft(1000, Unit.PX);
    div.getStyle().setTop(1000, Unit.PX);

    DivElement fixedDiv = doc.createDivElement();
    body.appendChild(fixedDiv);
    fixedDiv.setInnerText("foo");
    fixedDiv.getStyle().setPosition(Position.FIXED);

    // Get the absolute position of the element when the body is unscrolled.
    int absLeft = div.getAbsoluteLeft();
    int absTop = div.getAbsoluteTop();

    // Scroll the body as far down and to the right as possible.
    body.setScrollLeft(10000);
    body.setScrollTop(10000);

    // Make sure the absolute position hasn't changed (this has turned out to
    // be a common error in getAbsoluteLeft/Top() implementations).
    //
    // HACK: Firefox 2 has a bug that causes its getBoxObjectFor() to become
    // off-by-one at times when scrolling. It's not clear how to make this go
    // away, and doesn't seem to be worth the trouble to implement
    // getAbsoluteLeft/Top() yet again for FF2.
    assertTrue(Math.abs(absLeft - div.getAbsoluteLeft()) <= 1);
    assertTrue(Math.abs(absTop - div.getAbsoluteTop()) <= 1);

    // Ensure that the 'position:fixed' div's absolute position includes the
    // body's scroll position.
    //
    // Don't do this on IE6/7, which doesn't support position:fixed.
    if (!isIE6or7()) {
      assertTrue(fixedDiv.getAbsoluteLeft() >= body.getScrollLeft());
      assertTrue(fixedDiv.getAbsoluteTop() >= body.getScrollTop());
    }
  }

  /**
   * getElementsByTagName.
   */
  public void testGetElementsByTagName() {
    DivElement div = Document.get().createDivElement();
    div.setInnerHTML("<span><button>foo</button><span><button>bar</button></span></span>");

    NodeList<Element> nodes = div.getElementsByTagName("button");
    assertEquals(2, nodes.getLength());
    assertEquals("foo", nodes.getItem(0).getInnerText());
    assertEquals("bar", nodes.getItem(1).getInnerText());
  }

  public void testHasAttribute() {
    DivElement div = Document.get().createDivElement();

    // Assert that a raw element doesn't incorrectly report that it has any
    // unspecified built-in attributes (this is a problem on IE<8 if you're not
    // careful in implementing hasAttribute()).
    assertFalse(div.hasAttribute("class"));
    assertFalse(div.hasAttribute("style"));
    assertFalse(div.hasAttribute("title"));
    assertFalse(div.hasAttribute("id"));

    // Ensure that setting HTML-defined attributes is properly reported by
    // hasAttribute().
    div.setId("foo");
    assertTrue(div.hasAttribute("id"));

    // Ensure that setting *custom* attributes is properly reported by
    // hasAttribute().
    assertFalse(div.hasAttribute("foo"));
    div.setAttribute("foo", "bar");
    assertTrue(div.hasAttribute("foo"));

    // Ensure that a null attribute argument always returns null.
    assertFalse(div.hasAttribute(null));
  }

  public void testHasTagName() {
    DivElement div = Document.get().createDivElement();

    // hasTagName is case-insensitive
    assertTrue(div.hasTagName("div"));
    assertTrue(div.hasTagName("DIV"));
    assertTrue(div.hasTagName(DivElement.TAG));
    assertTrue(div.hasTagName(div.getTagName()));

    assertFalse(div.hasTagName("dove"));
  }

  /**
   * Tests HeadingElement.as() (it has slightly more complex assertion logic
   * than most).
   */
  public void testHeadingElementAs() {
    DivElement placeHolder = Document.get().createDivElement();

    for (int i = 0; i < 6; ++i) {
      placeHolder.setInnerHTML("<H" + (i + 1) + "/>");
      assertNotNull(HeadingElement.as(placeHolder.getFirstChildElement()));
    }

    if (getClass().desiredAssertionStatus()) {
      Element notHeading = Document.get().createDivElement();
      try {
        HeadingElement.as(notHeading);
        throw new Error("Expected assertion failure");
      } catch (AssertionError e) {
        // this *should* happen.
      }
    }
  }

  /**
   * Tests Element.is() and Element.as().
   */
  public void testIsAndAs() {
    assertFalse(Element.is(Document.get()));

    Node div = Document.get().createDivElement();
    assertTrue(Element.is(div));
    assertEquals("div", Element.as(div).getTagName().toLowerCase(Locale.ROOT));

    // Element.is(null) is allowed and should return false.
    assertFalse(Element.is(null));
    
    // Element sub-classes like DivElement have is(...) and as(...) too
    assertFalse(DivElement.is(Document.get()));
    assertTrue(DivElement.is(div));
    assertEquals("div", DivElement.as(div).getTagName().toLowerCase(Locale.ROOT));
    assertFalse(DivElement.is(null));
  }

  /**
   * Document.createElement('ns:tag'), getTagName().
   */
  public void testNamespaces() {
    Element elem = Document.get().createElement("myns:elem");
    assertEquals("myns:elem", elem.getTagName().toLowerCase(Locale.ROOT));
  }

  /**
   * className, id, tagName, title, dir, lang.
   */
  public void testNativeProperties() {
    DivElement div = Document.get().createDivElement();

    assertEquals("div", div.getTagName().toLowerCase(Locale.ROOT));

    div.setClassName("myClass");
    assertEquals("myClass", div.getClassName());

    div.setId("myId");
    assertEquals("myId", div.getId());

    div.setTitle("myTitle");
    assertEquals("myTitle", div.getTitle());

    div.setDir("rtl");
    assertEquals("rtl", div.getDir());

    div.setLang("fr-FR");
    assertEquals("fr-FR", div.getLang());
  }

  /**
   * offset[Left|Top|Width|Height], offsetParent.
   */
  public void testOffsets() {
    DivElement outer = Document.get().createDivElement();
    DivElement middle = Document.get().createDivElement();
    DivElement inner = Document.get().createDivElement();

    Document.get().getBody().appendChild(outer);
    outer.appendChild(middle);
    middle.appendChild(inner);

    outer.getStyle().setProperty("position", "absolute");
    inner.getStyle().setProperty("position", "relative");
    inner.getStyle().setPropertyPx("left", 19);
    inner.getStyle().setPropertyPx("top", 23);
    inner.getStyle().setPropertyPx("width", 29);
    inner.getStyle().setPropertyPx("height", 31);

    assertEquals(outer, inner.getOffsetParent());
    assertEquals(19, inner.getOffsetLeft());
    assertEquals(23, inner.getOffsetTop());
    assertEquals(29, inner.getOffsetWidth());
    assertEquals(31, inner.getOffsetHeight());
  }

  /**
   * setProperty*, getProperty*.
   */
  public void testProperties() {
    DivElement div = Document.get().createDivElement();

    div.setPropertyString("foo", "bar");
    assertEquals("bar", div.getPropertyString("foo"));

    div.setPropertyInt("foo", 42);
    assertEquals(42, div.getPropertyInt("foo"));

    div.setPropertyBoolean("foo", true);
    div.setPropertyBoolean("bar", false);
    assertEquals(true, div.getPropertyBoolean("foo"));
    assertEquals(false, div.getPropertyBoolean("bar"));

    Object obj = new Object();
    div.setPropertyObject("baz", obj);
    assertEquals(obj, div.getPropertyObject("baz"));

    JavaScriptObject jso = createTrivialJSO();
    div.setPropertyJSO("tintin", jso);
    assertEquals(jso, div.getPropertyJSO("tintin"));
  }

  /**
   * scroll[Left|Top], scrollIntoView.
   */
  @DoNotRunWith({Platform.HtmlUnitLayout})
  public void testScrollIntoView() {
    final DivElement outer = Document.get().createDivElement();
    final DivElement inner = Document.get().createDivElement();

    outer.getStyle().setProperty("position", "absolute");
    outer.getStyle().setProperty("top", "0px");
    outer.getStyle().setProperty("left", "0px");
    outer.getStyle().setProperty("overflow", "auto");
    outer.getStyle().setProperty("width", "200px");
    outer.getStyle().setProperty("height", "200px");

    inner.getStyle().setProperty("marginTop", "800px");
    inner.getStyle().setProperty("marginLeft", "800px");

    outer.appendChild(inner);
    Document.get().getBody().appendChild(outer);
    inner.setInnerText(":-)");
    inner.scrollIntoView();

    // Ensure that we are scrolled.
    assertTrue(outer.getScrollTop() > 0);
    assertTrue(outer.getScrollLeft() > 0);

    outer.setScrollLeft(0);
    outer.setScrollTop(0);

    // Ensure that we are no longer scrolled.
    assertEquals(0, outer.getScrollTop());
    assertEquals(0, outer.getScrollLeft());
  }

  /**
   * Tests that scrollLeft behaves as expected in RTL mode.
   * Failed in all modes due to HtmlUnit bug:
   * https://sourceforge.net/tracker/?func=detail&aid=2941255&group_id=47038&atid=448266
   */
  @DoNotRunWith({Platform.HtmlUnitLayout})
  public void testScrollLeftInRtl() {
    final DivElement outer = Document.get().createDivElement();
    final DivElement inner = Document.get().createDivElement();

    outer.getStyle().setProperty("position", "absolute");
    outer.getStyle().setProperty("top", "0px");
    outer.getStyle().setProperty("left", "0px");
    outer.getStyle().setProperty("overflow", "auto");
    outer.getStyle().setProperty("width", "200px");
    outer.getStyle().setProperty("height", "200px");

    // Force scrolling on the outer div, because WebKit doesn't do this
    // correctly in RTL mode.
    outer.getStyle().setProperty("overflow", "scroll");

    inner.getStyle().setProperty("position", "absolute");
    inner.getStyle().setProperty("top", "0px");
    inner.getStyle().setProperty("left", "0px");
    inner.getStyle().setProperty("right", "0px");
    inner.getStyle().setProperty("marginTop", "800px");
    inner.getStyle().setProperty("marginRight", "800px");

    outer.appendChild(inner);
    Document.get().getBody().appendChild(outer);
    outer.setDir("rtl");

    // FF2 does not render scroll bars reliably in RTL, so we set a large
    // content to force the scroll bars.
    String content = "ssssssssssssssssssssssssssssssssssssssssssssssssssss"
        + "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
        + "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss";
    inner.setInnerText(content);

    // The important thing is that setting and retrieving scrollLeft values in
    // RTL mode works only for negative numbers, and that they round-trip
    // correctly.
    outer.setScrollLeft(-32);
    assertEquals(-32, outer.getScrollLeft());

    outer.setScrollLeft(32);
    assertEquals(0, outer.getScrollLeft());
  }

  @DoNotRunWith({Platform.HtmlUnitLayout})
  public void testDocumentScrollLeftInRtl() {
    Document.get().getDocumentElement().setDir("rtl");
    Document.get().getBody().getStyle().setProperty("direction", "rtl");

    final DivElement bigdiv = Document.get().createDivElement();

    bigdiv.getStyle().setProperty("position", "absolute");
    bigdiv.getStyle().setProperty("top", "0px");
    bigdiv.getStyle().setProperty("right", "0px");
    bigdiv.getStyle().setProperty("width", "10000px");  // Bigger than window size.
    bigdiv.getStyle().setProperty("height", "400px");

    Document.get().getBody().appendChild(bigdiv);

    // The important thing is that setting and retrieving scrollLeft values in
    // RTL mode works only for negative numbers, and that they round-trip
    // correctly.
    try {
      assertEquals(0, Document.get().getScrollLeft());

      Document.get().setScrollLeft(-32);
      assertEquals(-32, Document.get().getScrollLeft());

      Document.get().setScrollLeft(32);
      assertEquals(0, Document.get().getScrollLeft());
    } finally {
      // Restore direction unconditionally to not break all other tests.
      Document.get().getBody().removeChild(bigdiv);
      Document.get().getBody().getStyle().setProperty("direction", "ltr");
      Document.get().getDocumentElement().setDir("ltr");
    }
  }

  /**
   * innerHTML.
   */
  public void testSetInnerHTML() {
    DivElement div = Document.get().createDivElement();
    div.setInnerHTML("<button><img src='foo.gif'></button>");

    Element button = div.getFirstChildElement();
    Element img = button.getFirstChildElement();

    assertEquals("button", button.getTagName().toLowerCase(Locale.ROOT));
    assertEquals("img", img.getTagName().toLowerCase(Locale.ROOT));
    assertTrue(((ImageElement) img).getSrc().endsWith("foo.gif"));
  }

  /**
   * innerText.
   */
  public void testSetInnerText() {
    Document doc = Document.get();

    TableElement tableElem = doc.createTableElement();
    TableRowElement trElem = doc.createTRElement();
    TableCellElement tdElem = doc.createTDElement();
    tdElem.setInnerText("Some Table Heading Data");

    // Add a <em> element as a child to the td element
    Element emElem = doc.createElement("em");
    emElem.setInnerText("Some emphasized text");
    tdElem.appendChild(emElem);

    trElem.appendChild(tdElem);
    tableElem.appendChild(trElem);
    doc.getBody().appendChild(tableElem);
    tdElem.setInnerText(null);

    // Once we set the inner text on an element to null, all of the element's
    // child nodes should be deleted, including any text nodes, for all
    // supported browsers.
    assertTrue(tdElem.getChildNodes().getLength() == 0);
  }

  /**
   * style.
   */
  public void testStyle() {
    DivElement div = Document.get().createDivElement();

    div.getStyle().setProperty("color", "black");
    assertEquals("black", div.getStyle().getProperty("color"));

    div.getStyle().setPropertyPx("width", 42);
    assertEquals("42px", div.getStyle().getProperty("width"));
  }

  /**
   * Test that styles only allow camelCase.
   */
  public void testStyleCamelCase() {
    DivElement div = Document.get().createDivElement();

    // Use a camelCase property
    div.getStyle().setProperty("backgroundColor", "black");
    assertEquals("black", div.getStyle().getProperty("backgroundColor"));
    div.getStyle().setPropertyPx("marginLeft", 10);
    assertEquals("10px", div.getStyle().getProperty("marginLeft"));

    // Use a hyphenated style
    if (Style.class.desiredAssertionStatus()) {
      try {
        div.getStyle().setProperty("background-color", "red");
        throw new Error("Expected assertion error: background-color should be in camelCase");
      } catch (AssertionError e) {
        // expected
      }
      try {
        div.getStyle().setPropertyPx("margin-left", 20);
        throw new Error("Expected assertion error: margin-left should be in camelCase");
      } catch (AssertionError e) {
        // expected
      }
      try {
        div.getStyle().getProperty("margin-right");
        throw new Error("Expected assertion error: margin-right should be in camelCase");
      } catch (AssertionError e) {
        // expected
      }
    }
  }

  private native JavaScriptObject createTrivialJSO() /*-{
    return {};
  }-*/;

  // Stolen from UserAgentPropertyGenerator
  private native boolean isIE6or7() /*-{
    var ua = navigator.userAgent.toLowerCase();
    if (ua.indexOf("msie") != -1) {
      if ($doc.documentMode >= 8) {
        return false;
      }
      return true;
    }
    return false;
  }-*/;
}
