<?xml version="1.0"?>
<!--
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

/**
 * Bug 544356 - This tests that the Download Manager is closed
 * when the last browser window is closed, if there are no active
 * downloads.
 */
-->

<window title="Download Manager Test"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        onload="test();">

  <script type="application/javascript"
          src="chrome://mochikit/content/MochiKit/packed.js"/>
  <script type="application/javascript"
          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
  <script type="application/javascript"
          src="chrome://mochikit/content/chrome/toolkit/mozapps/downloads/tests/chrome/utils.js"/>

  <script type="application/javascript">
  <![CDATA[

const DLMGR_UI_DONE = "download-manager-ui-done";

let Services = {
  wm: Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator),
  obs: Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
}

let gGen, dm, dmui, chromeWindow, testCleanup;

function test()
{
  if (testSetup()) {
    SimpleTest.waitForExplicitFinish();

    //Start test
    gGen = doTest();
    gGen.next();
  }
}

function doTest()
{
  let browserWindow1 = openBrowserWindow(continueTest);
  yield;
  let browserWindow2 = openBrowserWindow(continueTest);
  yield;
  openDownloadManager(continueTest);
  yield;
  let DMWindow = Services.wm.getMostRecentWindow("Download:Manager");

  addCloseListener([browserWindow1, browserWindow2]);
  browserWindow1.BrowserTryToCloseWindow();

  yield;

  // Wait for a moment and make sure the Download Manager didn't close,
  // because there's still one browser window
  setTimeout(continueTest, 500); yield;
  ok(dmui.visible, "Download Manager wasn't closed");

  let download = addDownload();
  // The download listener will pause the download and continue the test
  yield;

  browserWindow2.BrowserTryToCloseWindow();
  yield;

  // Wait for a moment and make sure the Download Manager didn't close,
  // because there's one active download
  setTimeout(continueTest, 500); yield;
  ok(dmui.visible, "Download Manager wasn't closed");

  dm.cancelDownload(download.id);
  dm.removeDownload(download.id);

  let browserWindow3 = openBrowserWindow(continueTest);
  yield;

  // Prepare to close last window
  ok(dmui.visible, "Download Manager wasn't closed");

  let isMac = /Mac/.test(navigator.platform);
  addCloseListener(isMac ? [browserWindow3] : [browserWindow3, DMWindow]);
  browserWindow3.BrowserTryToCloseWindow();
  if (isMac) {
    // Manually continue the test after a moment to make sure the Download Manager
    // didn't close
    setTimeout(continueTest, 500);
  }
  yield; yield;

  // Finally we reach the case where the Download Manager should have been closed
  if (isMac) {
    ok(dmui.visible, "Download Manager wasn't closed");
    DMWindow.close();
  } else {
    ok (!dmui.visible, "Download Manager was closed");
  }

  testCleanup();
  SimpleTest.finish();
  yield;
}

function continueTest()
{
  SimpleTest.executeSoon(function() {
    gGen.next();
  });
}

function testSetup()
{
  chromeWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                  getInterface(Components.interfaces.nsIWebNavigation).
                  QueryInterface(Components.interfaces.nsIDocShellTreeItem).
                  rootTreeItem.
                  QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                  getInterface(Components.interfaces.nsIDOMWindow);

  // Change the window type so this one doesn't count as a browser window
  let oldWinType = chromeWindow.document.documentElement.getAttribute("windowtype");
  chromeWindow.document.documentElement.setAttribute("windowtype", "navigator:testrunner");

  dm = Cc["@mozilla.org/download-manager;1"].
       getService(Ci.nsIDownloadManager);

  dmui = getDMUI();
  if (!dmui) {
    todo(false, "skip test for toolkit download manager UI");
    return false;
  }

  downloadListener = {

    onDownloadStateChange: function(aState, aDownload)
    {
      if (aDownload.state == Ci.nsIDownloadManager.DOWNLOAD_PAUSED) {
        continueTest();
      } else if (aDownload.state == Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING) {
        dm.pauseDownload(aDownload.id);
      }
    },

    onStateChange: function() { },
    onProgressChange: function() { },
    onSecurityChange: function() { }
  };

  dm.addListener(downloadListener);

  testCleanup = function() {
    dm.removeListener(downloadListener);
    chromeWindow.document.documentElement.setAttribute("windowtype", oldWinType);
  };

  return true;
}

function openBrowserWindow(callback)
{
  let browserWindow = openDialog(chromeWindow.location, "_blank",
                                 "chrome,all,dialog=no", "about:blank");
 
  let helperFunc = function() {
    callback();
    browserWindow.removeEventListener("load", helperFunc, false);
  }

  browserWindow.addEventListener("load", helperFunc, false);

  return browserWindow;
}

function openDownloadManager(callback)
{
  let testObs = {
    observe: function(aSubject, aTopic, aData) {
      if (aTopic != DLMGR_UI_DONE) {
        return;
      }

      callback();
      Services.obs.removeObserver(testObs, DLMGR_UI_DONE);
    }
  };

  Services.obs.addObserver(testObs, DLMGR_UI_DONE, false);

  dmui.show();
}

function addCloseListener(aWins)
{
  aWins.forEach(function(win) {
    let listener = function() {
      win.removeEventListener("unload", listener, false);
      continueTest();
    };
    win.addEventListener("unload", listener, false);
  });
}

  ]]>
  </script>

  <body xmlns="http://www.w3.org/1999/xhtml">
    <p id="display"></p>
    <div id="content" style="display:none;"></div>
    <pre id="test"></pre>
  </body>
</window>
