/*
 * Copyright 2009 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.impl;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.Event;

/**
 * Trident layout engine implementation of
 * {@link com.google.gwt.user.client.impl.DOMImpl}.
 */
public abstract class DOMImplTrident extends DOMImpl {
  private static JavaScriptObject callDispatchEvent;

  private static JavaScriptObject callDispatchDblClickEvent;

  private static JavaScriptObject callDispatchOnLoadEvent;

  private static JavaScriptObject callDispatchUnhandledEvent;

  /**
   * Let every GWT app on the page preview the current event. If any app cancels
   * the event, the event will be canceled for all apps.
   * 
   * @return <code>false</code> to cancel the event
   */
  private static native boolean previewEventImpl() /*-{
    var isCancelled = false; 
    for (var i = 0; i < $wnd.__gwt_globalEventArray.length; i++) {
      if (!$wnd.__gwt_globalEventArray[i]()) {
        isCancelled = true;
      }
    }
    return !isCancelled;
  }-*/;

  @Override
  public native Element eventGetFromElement(Event evt) /*-{
    // Prefer 'relatedTarget' if it's set (see createMouseEvent(), which
    // explicitly sets relatedTarget when synthesizing mouse events).
    return evt.relatedTarget || evt.fromElement;
  }-*/;

  @Override
  public native Element eventGetToElement(Event evt) /*-{
    // Prefer 'relatedTarget' if it's set (see createMouseEvent(), which
    // explicitly sets relatedTarget when synthesizing mouse events).
    return evt.relatedTarget || evt.toElement;
  }-*/;

  @Override
  public native Element getChild(Element elem, int index) /*-{
    return elem.children[index];
  }-*/;

  @Override
  public native int getChildCount(Element elem) /*-{
    return elem.children.length;
  }-*/;

  @Override
  public native int getChildIndex(Element parent, Element child) /*-{
    var count = parent.children.length;
    for (var i = 0; i < count; ++i) {
      if (child === parent.children[i]) {
        return i;
      }
    }
    return -1;
  }-*/;

  @Override
  public native void initEventSystem() /*-{
    // All GWT apps on the page register themselves with the globalEventArray
    // so that the first app to handle an event can allow all apps on the page
    // to preview it. See issue 3892 for more details.
    //
    // Apps cannot just mark the event as they visit it for a few reasons.
    // First, window level event handlers fire last in IE, so the first app to
    // cancel the event will be the last to see it. Second, window events do
    // not support arbitrary attributes, and the only writable field is the
    // returnValue, which has another use. Finally, window events are not
    // comparable (ex. a=event; b=event; a!=b), so we cannot keep a list of
    // events that have already been previewed by the current app.
    if ($wnd.__gwt_globalEventArray == null) {
      $wnd.__gwt_globalEventArray = new Array();
    }
    $wnd.__gwt_globalEventArray[$wnd.__gwt_globalEventArray.length] = $entry(function() {
      return @com.google.gwt.user.client.DOM::previewEvent(Lcom/google/gwt/user/client/Event;)($wnd.event);
    });

    var dispatchEvent = $entry(function() {
      // IE doesn't define event.currentTarget, so we squirrel it away here. It
      // also seems that IE won't allow you to add expandos to the event object,
      // so we have to store it in a global. This is ok because only one event
      // can actually be dispatched at a time.
      var oldEventTarget = @com.google.gwt.dom.client.DOMImplTrident::currentEventTarget;
      @com.google.gwt.dom.client.DOMImplTrident::currentEventTarget = this;

      // The first GWT app on the page to handle the event allows all apps to
      // preview it before continuing or cancelling, which is consistent with
      // other browsers.
      if ($wnd.event.returnValue == null) {
        $wnd.event.returnValue = true;
        if (!@com.google.gwt.user.client.impl.DOMImplTrident::previewEventImpl()()) {
          @com.google.gwt.dom.client.DOMImplTrident::currentEventTarget = oldEventTarget;
          return;
        }
      }

      var getEventListener = @com.google.gwt.user.client.impl.DOMImpl::getEventListener(*);

      var listener, curElem = this;
      while (curElem && !(listener = getEventListener(curElem))) {
        curElem = curElem.parentElement;
      }

      if (listener) {
        @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/user/client/EventListener;)($wnd.event, curElem, listener);
      }

      @com.google.gwt.dom.client.DOMImplTrident::currentEventTarget = oldEventTarget;
    });

    var dispatchDblClickEvent = $entry(function() {
      var newEvent = $doc.createEventObject();
      // Synthesize a click event if one hasn't already been synthesized.
      // Issue 4027: fireEvent is undefined on disabled input elements.
      if ($wnd.event.returnValue == null && $wnd.event.srcElement.fireEvent) {
        $wnd.event.srcElement.fireEvent('onclick', newEvent);
      }
      if (this.__eventBits & 2) {
        dispatchEvent.call(this);
      } else if ($wnd.event.returnValue == null) {
        // Ensure that we preview the event even if we aren't handling it.
        $wnd.event.returnValue = true;
        @com.google.gwt.user.client.impl.DOMImplTrident::previewEventImpl()();
      }
    });

    var dispatchUnhandledEvent = $entry(function() {
      this.__gwtLastUnhandledEvent = $wnd.event.type;
      dispatchEvent.call(this);
    });

    // Hook the above functions on the current window object, and
    // create a caller function for each one that indirects via
    // the global object. Make sure that the caller function has
    // no direct reference to the GWT program.
    var moduleName = @com.google.gwt.core.client.GWT::getModuleName()().replace(/\./g,'_');

    $wnd['__gwt_dispatchEvent_' + moduleName] = dispatchEvent;
    @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent = new Function('w',
      'return function() { w.__gwt_dispatchEvent_' + moduleName + '.call(this) }')($wnd);

    $wnd['__gwt_dispatchDblClickEvent_' + moduleName] = dispatchDblClickEvent;
    @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchDblClickEvent = new Function('w',
      'return function() { w.__gwt_dispatchDblClickEvent_' + moduleName + '.call(this)}')($wnd);

    $wnd['__gwt_dispatchUnhandledEvent_' + moduleName] = dispatchUnhandledEvent;
    @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchUnhandledEvent = new Function('w',
      'return function() { w.__gwt_dispatchUnhandledEvent_' + moduleName + '.call(this)}')($wnd);

    @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchOnLoadEvent = new Function('w',
      'return function() { w.__gwt_dispatchUnhandledEvent_' + moduleName + '.call(w.event.srcElement)}')($wnd);

    // We need to create these delegate functions to fix up the 'this' context.
    // Normally, 'this' is the firing element, but this is only true for
    // 'onclick = ...' event handlers, not for handlers setup via attachEvent().
    var bodyDispatcher = $entry(function() { dispatchEvent.call($doc.body); });
    var bodyDblClickDispatcher = $entry(function() { dispatchDblClickEvent.call($doc.body); });

    $doc.body.attachEvent('onclick', bodyDispatcher);
    $doc.body.attachEvent('onmousedown', bodyDispatcher);
    $doc.body.attachEvent('onmouseup', bodyDispatcher);
    $doc.body.attachEvent('onmousemove', bodyDispatcher);
    $doc.body.attachEvent('onmousewheel', bodyDispatcher);
    $doc.body.attachEvent('onkeydown', bodyDispatcher);
    $doc.body.attachEvent('onkeypress', bodyDispatcher);
    $doc.body.attachEvent('onkeyup', bodyDispatcher);
    $doc.body.attachEvent('onfocus', bodyDispatcher);
    $doc.body.attachEvent('onblur', bodyDispatcher);
    $doc.body.attachEvent('ondblclick', bodyDblClickDispatcher);
    $doc.body.attachEvent('oncontextmenu', bodyDispatcher);
  }-*/;

  @Override
  public native void insertChild(Element parent, Element child, int index) /*-{
    if (index >= parent.children.length)
      parent.appendChild(child);
    else
      parent.insertBefore(child, parent.children[index]);
  }-*/;

  @Override
  public void releaseCapture(Element elem) {
    maybeInitializeEventSystem();
    releaseCaptureImpl(elem);
  }

  @Override
  public void setCapture(Element elem) {
    maybeInitializeEventSystem();
    setCaptureImpl(elem);
  }

  @Override
  public void sinkBitlessEvent(Element elem, String eventTypeName) {
    // not supported
  }

  @Override
  public void sinkEvents(Element elem, int bits) {
    maybeInitializeEventSystem();
    sinkEventsImpl(elem, bits);
  }

  private native void releaseCaptureImpl(Element elem) /*-{
    elem.releaseCapture();
  }-*/;

  private native void setCaptureImpl(Element elem) /*-{
    elem.setCapture();
  }-*/;

  private native void sinkEventsImpl(Element elem, int bits) /*-{
    var chMask = (elem.__eventBits || 0) ^ bits;
    elem.__eventBits = bits;
    if (!chMask) return;
    
    if (chMask & 0x00001) elem.onclick       = (bits & 0x00001) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    // Add a ondblclick handler if onclick is desired to ensure that 
    // a user's double click will result in two onclick events.
    if (chMask & (0x00003)) elem.ondblclick  = (bits & (0x00003)) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchDblClickEvent : null;
    if (chMask & 0x00004) elem.onmousedown   = (bits & 0x00004) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00008) elem.onmouseup     = (bits & 0x00008) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00010) elem.onmouseover   = (bits & 0x00010) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00020) elem.onmouseout    = (bits & 0x00020) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00040) elem.onmousemove   = (bits & 0x00040) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00080) elem.onkeydown     = (bits & 0x00080) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00100) elem.onkeypress    = (bits & 0x00100) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00200) elem.onkeyup       = (bits & 0x00200) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00400) elem.onchange      = (bits & 0x00400) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x00800) elem.onfocus       = (bits & 0x00800) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x01000) elem.onblur        = (bits & 0x01000) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x02000) elem.onlosecapture = (bits & 0x02000) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x04000) elem.onscroll      = (bits & 0x04000) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x08000) {
      if (elem.nodeName == "IFRAME") {
        if (bits & 0x08000) {
          elem.attachEvent('onload', @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchOnLoadEvent);
        } else {
          elem.detachEvent('onload', @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchOnLoadEvent);
        }
      } else {
       elem.onload = (bits & 0x08000) ?
          @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchUnhandledEvent : null;
      }
    }
    if (chMask & 0x10000) elem.onerror       = (bits & 0x10000) ?
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x20000) elem.onmousewheel  = (bits & 0x20000) ? 
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x40000) elem.oncontextmenu = (bits & 0x40000) ? 
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
    if (chMask & 0x80000) elem.onpaste       = (bits & 0x80000) ? 
        @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
  }-*/;
}
