/*
 * Copyright 2012 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 $PACKAGE;
$IMPORTS
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;

import elemental.events.*;
import elemental.util.*;
import elemental.dom.*;
import elemental.html.*;
import elemental.svg.*;
import elemental.js.util.JsElementalBase;

import java.util.Date;

/**
  * A base class containing all of the IDL interfaces which are shared
  * between disjoint type hierarchies. Because of the GWT compiler
  * SingleJsoImpl restriction that only a single JavaScriptObject
  * may implement a given interface, we hoist all of the explicit
  * mixin classes into a base JSO used by all of elemental.
  */
@Deprecated
public class JsElementalMixinBase $EXTENDS $IMPLEMENTS {
  protected JsElementalMixinBase() {}
$!MEMBERS

private static class Remover implements EventRemover {
  private final EventTarget target;
  private final String type;
  private final JavaScriptObject handler;
  private final boolean useCapture;

  private Remover(EventTarget target, String type, JavaScriptObject handler,
      boolean useCapture) {
    this.target = target;
    this.type = type;
    this.handler = handler;
    this.useCapture = useCapture;
  }

  @Override
  public void remove() {
    removeEventListener(target, type, handler, useCapture);
  }

  private static Remover create(EventTarget target, String type, JavaScriptObject handler,
      boolean useCapture) {
    return new Remover(target, type, handler, useCapture);
  }
}

// NOTES:
// - This handler/listener structure is currently the same in DevMode and ProdMode but it is
//   subject to change. In fact, I would like to use:
//     { listener : listener, handleEvent : function() }
//   but Firefox doesn't properly support that form of handler for onEvent type events.
// - The handler property on listener can be removed when removeEventListener is removed.
private native static JavaScriptObject createHandler(EventListener listener) /*-{
  var handler = listener.handler;
  if (!handler) {
    handler = $entry(function(event) {
      @elemental.js.dom.JsElementalMixinBase::handleEvent(Lelemental/events/EventListener;Lelemental/events/Event;)(listener, event);
    });
    handler.listener = listener;
    // TODO(knorton): Remove at Christmas when removeEventListener is removed.
    listener.handler = handler;
  }
  return handler;
}-*/;

private static class ForDevMode {
  private static java.util.Map<EventListener, JavaScriptObject> handlers;

  static {
    if (!com.google.gwt.core.client.GWT.isScript()) {
      handlers = new java.util.HashMap<EventListener, JavaScriptObject>();
    }
  }

  private static JavaScriptObject getHandlerFor(EventListener listener) {
    if (listener == null) {
      return null;
    }

    JavaScriptObject handler = handlers.get(listener);
    if (handler == null) {
      handler = createHandler(listener);
      handlers.put(listener, handler);
    }
    return handler;
  }

  private native static JavaScriptObject createHandler(EventListener listener) /*-{
    var handler = $entry(function(event) {
      @elemental.js.dom.JsElementalMixinBase::handleEvent(Lelemental/events/EventListener;Lelemental/events/Event;)(listener, event);
    });
    handler.listener = listener;
    return handler;
  }-*/;

  private native static EventListener getListenerFor(JavaScriptObject handler) /*-{
    return handler && handler.listener;
  }-*/;
}

private static class ForProdMode {
  private static JavaScriptObject getHandlerFor(EventListener listener) {
    return listener == null ? null : createHandler(listener);
  }

  private native static EventListener getListenerFor(JavaScriptObject handler) /*-{
    return handler && handler.listener;
  }-*/;
}

private static void handleEvent(EventListener listener, Event event) {
  listener.handleEvent(event);
}

private static EventListener getListenerFor(JavaScriptObject handler) {
  return com.google.gwt.core.client.GWT.isScript()
    ? ForProdMode.getListenerFor(handler)
    : ForDevMode.getListenerFor(handler);
}

private static JavaScriptObject getHandlerFor(EventListener listener) {
  return com.google.gwt.core.client.GWT.isScript()
    ? ForProdMode.getHandlerFor(listener)
    : ForDevMode.getHandlerFor(listener);
}
 
public native final EventRemover addEventListener(String type, EventListener listener, boolean useCapture) /*-{
  var handler = @elemental.js.dom.JsElementalMixinBase::getHandlerFor(Lelemental/events/EventListener;)(listener);
  this.addEventListener(type, handler, useCapture);
  return @elemental.js.dom.JsElementalMixinBase.Remover::create(Lelemental/events/EventTarget;Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;Z)
      (this, type, handler, useCapture);
}-*/;

public final EventRemover addEventListener(String type, EventListener listener) {
  return addEventListener(type, listener, false);
}

@Deprecated
public final void removeEventListener(String type, EventListener listener, boolean useCapture) {
  final JavaScriptObject handler = getHandlerFor(listener);
  if (handler != null) {
    removeEventListener(this, type, handler, useCapture);
  }
}

@Deprecated
public final void removeEventListener(String type, EventListener listener) {
  final JavaScriptObject handler = getHandlerFor(listener);
  if (handler != null) {
    removeEventListener(this, type, handler);
  }
}

private static native void removeEventListener(EventTarget target, String type,
    JavaScriptObject handler, boolean useCapture) /*-{
  target.removeEventListener(type, handler, useCapture);
}-*/;

private static native void removeEventListener(EventTarget target, String type,
    JavaScriptObject handler) /*-{
  target.removeEventListener(type, handler);
}-*/;

}
