/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const { classes: Cc, interfaces: Ci, utils: Cu } = Components;

Cu.import("resource://gre/modules/GeckoViewContentModule.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");

XPCOMUtils.defineLazyGetter(this, "dump", () =>
    Cu.import("resource://gre/modules/AndroidLog.jsm",
              {}).AndroidLog.d.bind(null, "ViewContent"));

function debug(aMsg) {
  // dump(aMsg);
}

class GeckoViewContent extends GeckoViewContentModule {
  register() {
    debug("register");

    addEventListener("DOMTitleChanged", this, false);
    addEventListener("MozDOMFullscreen:Entered", this, false);
    addEventListener("MozDOMFullscreen:Exit", this, false);
    addEventListener("MozDOMFullscreen:Exited", this, false);
    addEventListener("MozDOMFullscreen:Request", this, false);
    addEventListener("contextmenu", this, { capture: true, passive: false });

    this.messageManager.addMessageListener("GeckoView:DOMFullscreenEntered",
                                           this);
    this.messageManager.addMessageListener("GeckoView:DOMFullscreenExited",
                                           this);
  }

  unregister() {
    debug("unregister");

    removeEventListener("DOMTitleChanged", this);
    removeEventListener("MozDOMFullscreen:Entered", this);
    removeEventListener("MozDOMFullscreen:Exit", this);
    removeEventListener("MozDOMFullscreen:Exited", this);
    removeEventListener("MozDOMFullscreen:Request", this);
    removeEventListener("contextmenu", this);

    this.messageManager.removeMessageListener("GeckoView:DOMFullscreenEntered",
                                              this);
    this.messageManager.removeMessageListener("GeckoView:DOMFullscreenExited",
                                              this);
  }

  receiveMessage(aMsg) {
    debug("receiveMessage " + aMsg.name);

    switch (aMsg.name) {
      case "GeckoView:DOMFullscreenEntered":
        if (content) {
          content.QueryInterface(Ci.nsIInterfaceRequestor)
                 .getInterface(Ci.nsIDOMWindowUtils)
                 .handleFullscreenRequests();
        }
        break;
      case "GeckoView:DOMFullscreenExited":
        if (content) {
          content.QueryInterface(Ci.nsIInterfaceRequestor)
                 .getInterface(Ci.nsIDOMWindowUtils)
                 .exitFullscreen();
        }
        break;
    }
  }

  handleEvent(aEvent) {
    debug("handleEvent " + aEvent.type);

    switch (aEvent.type) {
      case "contextmenu":
        function nearestParentHref(node) {
          while (node && !node.href) {
            node = node.parentNode;
          }
          return node && node.href;
        }

        let node = aEvent.target;
        let hrefNode = nearestParentHref(node);
        let isImageNode = node instanceof Ci.nsIDOMHTMLImageElement;
        let isMediaNode = node instanceof Ci.nsIDOMHTMLMediaElement;

        if (hrefNode || isImageNode || isMediaNode) {
          this.eventDispatcher.sendRequest({
            type: "GeckoView:ContextMenu",
            screenX: aEvent.screenX,
            screenY: aEvent.screenY,
            uri: hrefNode,
            elementSrc: isImageNode || isMediaNode
                        ? node.currentSrc || node.src
                        : null
          });
          aEvent.preventDefault();
        }
        break;
      case "MozDOMFullscreen:Request":
        sendAsyncMessage("GeckoView:DOMFullscreenRequest");
        break;
      case "MozDOMFullscreen:Entered":
      case "MozDOMFullscreen:Exited":
        // Content may change fullscreen state by itself, and we should ensure
        // that the parent always exits fullscreen when content has left
        // full screen mode.
        if (content && content.document.fullscreenElement) {
          break;
        }
        // fall-through
      case "MozDOMFullscreen:Exit":
        sendAsyncMessage("GeckoView:DOMFullscreenExit");
        break;
      case "DOMTitleChanged":
        this.eventDispatcher.sendRequest({
          type: "GeckoView:DOMTitleChanged",
          title: content.document.title
        });
        break;
    }
  }
}

var contentListener = new GeckoViewContent("GeckoViewContent", this);
