Components.utils.import('resource://unity_webapps/utils.js');

// this file is the JavaScript backing for the UI wrangling which happens in
// browser.xul. It also initializes the Greasemonkey singleton which contains
// all the main injection logic, though that should probably be a proper XPCOM
// service and wouldn't need to be initialized in that case.

function UW_BrowserUI() {};

/**
 * nsISupports.QueryInterface
 */
UW_BrowserUI.QueryInterface = function(aIID) {
  if (!aIID.equals(Components.interfaces.nsISupports) &&
      !aIID.equals(Components.interfaces.nsIObserver) &&
      !aIID.equals(Components.interfaces.nsISupportsWeakReference))
    throw Components.results.NS_ERROR_NO_INTERFACE;

  return UW_BrowserUI;
};


UW_BrowserUI.init = function() {
  window.addEventListener("load", UW_BrowserUI.chromeLoad, false);
};

UW_BrowserUI.progressListener = {
  onLocationChange:function(aBrowser, aProgress, aRequest, aURI) {
    if (aProgress.isLoadingDocument) {
      UW_BrowserUI.gmSvc.runScripts(
          'document-start', aProgress.DOMWindow, window);
    }
  },
  onStateChange:function() { },
  onProgressChange:function() { },
  onStatusChange:function() { },
  onSecurityChange:function() { },
  onLinkIconAvailable:function() { }
};

/**
 * The browser XUL has loaded. Find the elements we need and set up our
 * listeners and wrapper objects.
 */
UW_BrowserUI.chromeLoad = function(e) {
  // Store DOM element references in this object, also for use elsewhere.
  UW_BrowserUI.tabBrowser = document.getElementById("content");
  UW_BrowserUI.bundle = document.getElementById("uw-browser-bundle");

  // Use the appcontent element specifically, see #1344.
  document.getElementById("appcontent")
      .addEventListener("DOMContentLoaded", UW_BrowserUI.contentLoad, true);
  gBrowser.addEventListener("pagehide", UW_BrowserUI.pagehide, true);
  gBrowser.addEventListener("pageshow", UW_BrowserUI.pageshow, true);

  var sidebar = document.getElementById("sidebar");
  sidebar.addEventListener("DOMContentLoaded", UW_BrowserUI.contentLoad, true);
  sidebar.addEventListener("pagehide", UW_BrowserUI.pagehide, true);
  sidebar.addEventListener("pageshow", UW_BrowserUI.pageshow, true);

  var observerService = Components.classes["@mozilla.org/observer-service;1"]
     .getService(Components.interfaces.nsIObserverService);

  observerService.addObserver(UW_BrowserUI, "inner-window-destroyed", true);

  // we use this to determine if we are the active window sometimes
  UW_BrowserUI.winWat = Components
      .classes["@mozilla.org/embedcomp/window-watcher;1"]
      .getService(Components.interfaces.nsIWindowWatcher);

  UW_BrowserUI.gmSvc = UW_util.getService();

  gBrowser.addTabsProgressListener(UW_BrowserUI.progressListener);
};

UW_BrowserUI.contentLoad = function(event) {
  var safeWin = event.target.defaultView;
  var href = safeWin.location.href;

  // Make sure we are still on the page that fired this event, see issue #1083.
  // But ignore hashes; see issue #1445.
  if (href.replace(/#.*/, '') == event.target.documentURI.replace(/#.*/, '')) {
    UW_BrowserUI.gmSvc.runScripts('document-end', safeWin, window);
  }
};

UW_BrowserUI.pagehide = function(aEvent) {
  var windowId = UW_util.windowIdForEvent(aEvent);
  if (aEvent.persisted) {
    UW_BrowserUI.gmSvc.contentFrozen(windowId);
  } else {
    UW_BrowserUI.gmSvc.contentDestroyed(windowId);
  }
};

UW_BrowserUI.pageshow = function(aEvent) {
  var windowId = UW_util.windowIdForEvent(aEvent);
  UW_BrowserUI.gmSvc.contentThawed(windowId);
};

UW_BrowserUI.observe = function(subject, topic, data) {
  if (topic == "dom-window-destroyed") {
    UW_BrowserUI.gmSvc.contentDestroyed(UW_util.windowId(subject));
  } else if (topic == "inner-window-destroyed") {
    UW_BrowserUI.gmSvc.contentDestroyed(
        subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data);
  } else {
    throw new Error("Unexpected topic received: {" + topic + "}");
  }
};

UW_BrowserUI.init();
