/*
 * Copyright 2007 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;

/**
 * Base implementation of {@link com.google.gwt.user.client.impl.DOMImpl} shared
 * by those browsers that come a bit closer to supporting a common standard (ie,
 * not IE).
 *
 * <p>Deprecated, may be flattened into DOMImpl, as this is the only direct subclass.</p>
 */
@Deprecated
abstract class DOMImplStandard extends DOMImpl {

  @Override
  public native NativeEvent createHtmlEvent(Document doc, String type,
      boolean canBubble, boolean cancelable) /*-{
    var evt = doc.createEvent('HTMLEvents');
    evt.initEvent(type, canBubble, cancelable);

    return evt;
  }-*/;

  @Override
  public native InputElement createInputRadioElement(Document doc, String name) /*-{
    var elem = doc.createElement("INPUT");
    elem.type = 'radio';
    elem.name = name;
    elem.value = 'on';
    return elem;
  }-*/;

  @Override
  public native NativeEvent createMouseEvent(Document doc, String type,
      boolean canBubble, boolean cancelable, int detail, int screenX,
      int screenY, int clientX, int clientY, boolean ctrlKey, boolean altKey,
      boolean shiftKey, boolean metaKey, int button, Element relatedTarget) /*-{
    // Because Event.getButton() returns bitfield values [1, 4, 2] for [left,
    // middle, right], we need to translate them to the standard [0, 1, 2]
    // button constants.
    if (button == 1) {
      button = 0;
    } else if (button == 4) {
      button = 1;
    } else {
      button = 2;
    }

    var evt = doc.createEvent('MouseEvents');
    evt.initMouseEvent(type, canBubble, cancelable, null, detail, screenX,
      screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button,
      relatedTarget);

    return evt;
  }-*/;

  @Override
  public native void dispatchEvent(Element target, NativeEvent evt) /*-{
    target.dispatchEvent(evt);
  }-*/;

  @Override
  public native int eventGetButton(NativeEvent evt) /*-{
    // All modern browsers return 0, 1, and 2 for left, middle, and right,
    // respectively. Because eventGetButton() is expected to return the IE
    // bitfield norms of 1, 4, and 2, we translate them here.
    var button = evt.button;
    if (button == 1) {
      return 4;
    } else if (button == 2) {
      return 2;
    }
    return 1;
  }-*/;

  @Override
  public native int eventGetCharCode(NativeEvent evt) /*-{
    return evt.charCode || 0;
  }-*/;

  @Override
  public native EventTarget eventGetRelatedTarget(NativeEvent evt) /*-{
    return evt.relatedTarget;
  }-*/;

  @Override
  public native EventTarget eventGetTarget(NativeEvent evt) /*-{
    return evt.target;
  }-*/;

  @Override
  public native void eventPreventDefault(NativeEvent evt) /*-{
    evt.preventDefault();
  }-*/;

  @Override
  public native String eventToString(NativeEvent evt) /*-{
    return evt.toString();
  }-*/;

  /*
   * textContent is used over innerText for two reasons:
   * 1 - It is consistent across browsers. textContent
   *     does not convert <br>'s to new lines.
   * 2 - textContent is faster on retreival because WebKit
   *     does not recalculate styles as it does for innerText.
   */ 
  @Override
  public native String getInnerText(Element elem) /*-{
    return elem.textContent;
  }-*/;

  @Override
  public native boolean isOrHasChild(Node parent, Node child) /*-{
    return parent.contains(child);
  }-*/;

  /*
   * See getInnerText for why textContent is used instead of innerText.
   */
  @Override
  public native void setInnerText(Element elem, String text) /*-{
    elem.textContent = text || '';
  }-*/;

  @Override
  Element getDocumentScrollingElement(Document doc) {
    // Uses http://dev.w3.org/csswg/cssom-view/#dom-document-scrolling element to
    // avoid trying to guess about browser behavior.
    if (getNativeDocumentScrollingElement(doc) != null) {
      return getNativeDocumentScrollingElement(doc);
    }

    return getLegacyDocumentScrollingElement(doc);
  }

  Element getLegacyDocumentScrollingElement(Document doc) {
    return doc.getViewportElement();
  }

  final native Element getNativeDocumentScrollingElement(Document doc) /*-{
    return doc.scrollingElement;
  }-*/;

}
