/* documentRegistry.data[k] = {
 *   wrapper: xeIDocumentWrapper,
 *   id: xeIDocumentWrapper.publicURI,
 *   document: xeIDocumentWrapper.wrappedDocument
 * }
 */
const documentRegistry = new DataRegistry();
documentRegistry.requiredFields = ["wrapper", "id", "document"];
documentRegistry.addProperties({
  /**
   * Register a document by the information placed in its wrapper.
   *
   * @param aDocumentWrapper xeIDocumentWrapper containing the document we want
   *                         to register.
   * @param aTxMgr           nsITransactionManager (optional) to use for the
   *                         document.
   *
   * @return XULElement for the document wrapper's tab.
   */
  addDocumentByWrapper: function addDocumentByWrapper(aDocumentWrapper, aTxMgr) {
    assertLoadStatus();

    var mustBeTrue = true;

    var rv = isInstance(aDocumentWrapper, "xeIDocumentWrapper");
    assert(rv > 0, "addDocumentByWrapper must be called with a xeIDocumentWrapper!");
    if (aDocumentWrapper.publicURI) {
      mustBeTrue = !this.searchFirstEntry({
        id: aDocumentWrapper.publicURI
      });
      this.check(mustBeTrue, "This document is already open!");

      verbosio.virtualFileService.setWrapper(aDocumentWrapper);
    }

    this.addEntryByArguments("id", aDocumentWrapper.publicURI,
                             "wrapper", aDocumentWrapper,
                             "document", aDocumentWrapper.wrappedDocument
                             );

    const nsITxMgrCID = "@mozilla.org/transactionmanager;1";
    const nsITxMgr = Components.interfaces.nsITransactionManager;

    if (!(aTxMgr instanceof nsITxMgr)) {
      var txmgrClass = Components.classes[nsITxMgrCID];
      aDocumentWrapper.txmgr = txmgrClass.createInstance(nsITxMgr);
    } else {
      aDocumentWrapper.txmgr = aTxMgr;
    }

    // XXX ajvincent Do *NOT* call txmgr.AddListener(aDocumentWrapper)!

    // Add the default tab.
    var docTab = documentViewer.appendDocTab(aDocumentWrapper);
    docTab.documentWrapper = aDocumentWrapper;

    // Attach our standard mutation event listeners before the viewer listeners.
    mutationEventRegistry.registerDocument(aDocumentWrapper.wrappedDocument);

    // Register viewers
    /* XXX ajvincent What's this doing here?  We want to disable viewers,
     * but we're not doing anything with created viewers.
     */
    var disabledViewers = [];
    for (var i = 0; i < documentViewer.viewTabs.childNodes.length; i++) {
      var tab = documentViewer.viewTabs.childNodes[i];
      documentViewer.getViewer(aDocumentWrapper, tab, true);
    }

    return docTab;
  },

  /**
   * Remove a document from the registered documents (we're done editing it).
   *
   * @param aDocumentWrapper xeIDocumentWrapper containing the document we want
   *                         to remove.
   */
  removeDocumentByWrapper: function removeDocumentByWrapper(aDocumentWrapper) {
    throw Components.results.NS_ERROR_NOT_YET_IMPLEMENTED;

    var result = this.searchFirstIndex({
      wrapper: aDocumentWrapper
    });

    this.check(result, "No wrapper found in registry!");
    this.removeIndex(result);

    if (aDocumentWrapper.publicURI) {
      verbosio.virtualFileService.removeWrapper(aDocumentWrapper);
    }

    // memory leak cleanup, just in case
    for (var prop in aDocumentWrapper) {
      aDocumentWrapper[prop] = null;
    }
  },

  /**
   * Get the document wrapper for a document.
   *
   * @param aDocument nsIDOMDocument to find the wrapper for.
   *
   * @return xeIDocumentWrapper whose wrappedDocument property is aDocument.
   */
  getWrapperByDocument: function getWrapperByDocument(aDocument) {
    var result = this.searchFirstEntry({
      document: aDocument
    });
    return result ? result.wrapper : null;
  }
});
