// encoding ='UTF-8'

/*
  # File : xnote-overlay.js
  # Author : Hugo Smadja, Pierre-Andre Galmes, Lorenz Froihofer, Klaus Buecher
  # Description : functions associated to the "xnote-overlay.xul" overlay file.
*/

/* 
 This overlay only deals with the context menu entries and should be replaced by
 menus API in background entirely.

 When a context menu entry closes a note window, it does not update xnote_displayed,
 so when this moves into background it should be more simple
 
 Tag management principles and thoughts
 - When should labels be applied?
    - When a new post-it is saved.
    - When XNote notes are imported from a PC to another PC (cf TODO: import
      procedure).

 - When should the XNote label related to a message be removed?
    - When the message is empty (no text in it).
    - When the message is removed.

 - What should happened when XNote is removed?
  - Remove the XNote tag ? No
  - Remove the XNote labels associated to messages? No
*/
//console.log("start xnote-about-overlay");

Services.scriptloader.loadSubScript("resource://xnote/content/tooltip/tippy/popper.js", window);
Services.scriptloader.loadSubScript("resource://xnote/content/tooltip/tippy/tippy.js", window);//, tabAbout3pane.messageBrowser.contentWindow
//console.log("tippy", window.tippy);

var { xnote } = ChromeUtils.import ? ChromeUtils.import("resource://xnote/modules/xnote.jsm")
  : ChromeUtils.importESModule("resource://xnote/modules/xnote.sys.mjs");

//var { MessageListTracker, MessageTracker, MessageManager } =
//  ChromeUtils.importESModule("resource:///modules/ExtensionMessages.sys.mjs");

var logException = function (exc, unknown) {
  try {
    Services.console.logStringMessage(exc.toString() + "\n" + exc.stack);
  } catch (x) { };
};


function GetThreadTree() {
  // let mainWindow = Services.wm.getMostRecentWindow("mail:3pane");
  // let threadTree1 = mainWindow.gTabmail.currentAbout3Pane.threadTree ;
  //  let threadTree = mainWindow.gTabmail.tabInfo[0].chromeBrowser.contentWindow.threadTree;
  //console.log("threadtree in about" , window, window.threadTree);
  return window.threadTree;

};

function GetXNoteColumn() {
  // let mainWindow = Services.wm.getMostRecentWindow("mail:3pane");
  // let threadTree1 = mainWindow.gTabmail.currentAbout3Pane.threadTree ;
  //  let threadTree = mainWindow.gTabmail.tabInfo[0].chromeBrowser.contentWindow.threadTree;
  //console.log("threadtree in about" , window, window.threadTree);
  let XNcolumn = window.document.getElementById("XNote-column");
  //  console.log("XNote-column", XNcolumn);
  return XNcolumn;

};

var xnoteOverlayObj = function () {
  var pub = {};
  Services.scriptloader.loadSubScript("chrome://xnote/content/scripts/notifyTools.js", pub, "UTF-8");

  // Variables related to the XNote context menu.
  var noteForContextMenu;
  var currentIndex;

  /** Contains the note for the current message */
  // This state variable is used by the Experiment, if this file goes away, the state could move into
  // a window map stored in the Experiment.
  var note;

  /** Contains the XNote window instance. */
  // This state variable is used by the Experiment, if this file goes away, the state could move into
  // a window map stored in the Experiment.
  var xnoteWindow;
  var oldLocationColTitle = "";
  var showXNoteColumn = true;

  /**
   * CALLER XUL
   * Type: event command element XUL <menuitem>
   * Id: context-addition
   * FUNCTION
   * Creation and modification of notes uses the same function, that is context_modifierNote()
   */
  pub.context_createNote = function () {
    pub.context_modifyNote(false);
  }

  /**
   * CALLER XUL
   * Type: event command element XUL <menuitem>
   * Id: context-modif
   * FUNCTION
   */


  pub.getDBView = function () {
    let mainWindow = Services.wm.getMostRecentWindow("mail:3pane");
    //console.log("about3",mainWindow.gTabmail.currentAbout3Pane, mainWindow.gTabmail.currentTabInfo.chromeBrowser.contentWindow, mainWindow.gTabmail.tabInfo[0].chromeBrowser.contentWindow );
    //      this.mail3PaneWindow = mainWindow.gTabmail.currentAbout3Pane;
    let gDBView = mainWindow.gTabmail.currentAbout3Pane.gDBView;//mainWindow.gDBView  ;//this.mail3PaneWindow.gDBView;
    //     this.threadTree = mainWindow.gTabmail.currentAbout3Pane.threadTree ;
    //     this.threadTree.addEventListener("select", mainWindow.NostalgyDefLabel, false);
    return gDBView;


  }


  pub.context_modifyNote = function (defaultSize, clicked = false) {
    let gDBView = pub.getDBView();
    //  debugger;
    //  console.log( "context_modifyNote wnd", window, window.document.title, gDBView.msgFolder.name, gDBView);
    if (gDBView.selection.currentIndex == currentIndex) {
      //Closes the note (if any) of the old (deselected) message.
      pub.closeNote();

      //Initialize note for the newly selected message.
      note = new xnote.ns.Note(pub.getMessageID());
      pub.updateTag(note.text);
      //    console.log("note", note, "wnd", window);
      if (defaultSize) {
        note.x = note.DEFAULT_X;
        note.y = note.DEFAULT_Y;
        //        note.width = note.DEFAULT_XNOTE_WIDTH;
        //        note.height = note.DEFAULT_XNOTE_HEIGHT;

      }

      xnoteWindow = window.openDialog(
        'chrome://xnote/content/xnote-window.xhtml',
        'XNote',
        'chrome=yes,dependent=yes,titlebar, resizable=yes,status, modal=no,left=' + (window.screenX + note.x) + ',top=' + (window.screenY + note.y) + ',width=' + note.width + ',height=' + (note.height + 50),
        note, true
      );
      //   console.log("xnotewnd in modify_note", xnoteWindow, window, window.document.title);
    }
    else {
      gDBView.selection.select(currentIndex);
      gDBView.selectionChanged();
      // The following prevents the previous message selection from
      // being restored during closing of the context menu.
      // Variable not present in SeaMonkey --> check to prevent errors.
      if (xnote.ns.Commons.isInThunderbird) {
        //115?       gRightMouseButtonSavedSelection.realSelection.select(currentIndex);
      }
    }
  }

  /**
   * CALLER XUL
   * Type: event command element XUL &lt;menuitem&gt;
   * Id: context-suppr
   * FUNCTION
   * Delete the note associated with the selected e-mail.
   */
  pub.context_deleteNote = function () {
    //   console.log("about context_deleteNote", noteForContextMenu);
    //    pub.closeNote();
    noteForContextMenu.deleteNote();
    pub.updateTag("");

    pub.closeNote();
  }

  pub.context_resetNoteWindow = function () {
    if (gDBView.selection.currentIndex == currentIndex) {
      pub.context_modifyNote(true);
      /*      
            xnoteWindow.resizeTo(noteForContextMenu.DEFAULT_XNOTE_WIDTH, noteForContextMenu.DEFAULT_XNOTE_HEIGHT);
            xnoteWindow.moveTo(noteForContextMenu.DEFAULT_X, noteForContextMenu.DEFAULT_Y)
            note.modified = true;
          */
    }
    else {
      noteForContextMenu.x = noteForContextMenu.DEFAULT_X;
      noteForContextMenu.y = noteForContextMenu.DEFAULT_Y;
      noteForContextMenu.width = noteForContextMenu.DEFAULT_XNOTE_WIDTH;
      noteForContextMenu.height = noteForContextMenu.DEFAULT_XNOTE_HEIGHT;
      noteForContextMenu.modified = true;
      noteForContextMenu.saveNote();
    }
  }

  /**
   * Closes the XNote window.
   */
  pub.closeNote = function () {
    //  console.log("close xnotewnd", xnoteWindow, xnoteOverlayObj.xnoteWindow);
    if (xnoteWindow != null) {//115? && xnoteWindow.document) {
      //  setTimeout(xnoteWindow.close,500);
      //  pub.notifyTools.notifyBackground({ command: "closeNote" });

      xnoteWindow.close();
    }
  }

  /**
   * FUNCTION
   * Applies the XNote tag to the selected message.
   * (Choice of tag in the preferences.)
   */
  pub.updateTag = function (noteText) {
    //    console.log("about: updateTag", xnote.ns.Commons.useTag);
    if (xnote.ns.Commons.useTag) {
      let gDBView = pub.getDBView();
      //    console.log("gDBView",gDBView, window.WL);
      let msgHdr = gDBView.hdrForFirstSelectedMessage;
      let msgId = xnote.ns.Commons.context.extension.messageManager.convert(pub.msgHdr);
      // If the note isn't empty,
      if (noteText != '') {
        // Add the XNote Tag.
        //       ToggleMessageTag("xnote", true);
        pub.notifyTools.notifyBackground({ command: "updateTag", info: { msgId: msgId.id, addTag: true, removeTag: false } });
        //      console.log("addTag", noteText);
      }
      // If the note is empty,
      else {
        // Remove the XNote Tag.
        //        ToggleMessageTag("xnote", false);
        pub.notifyTools.notifyBackground({ command: "updateTag", info: { msgId: msgId.id, addTag: false, removeTag: true } });
        //     console.log("removeTag", noteText);
      }
    }
  }

  function updateContextMenu() {
    noteForContextMenu = new xnote.ns.Note(pub.getMessageID());
    window.browsingContext.topChromeWindow.xnoteOverlayObj.noteForContextMenu = noteForContextMenu;
    //  console.log("contextmenu", noteForContextMenu);
    let noteExists = noteForContextMenu.exists();
    /* Commented until button will be re-enabled in manifest.json 
      ("message_display_action" removed in earlier commit).
    if (noteExists) xnote.WL.messenger.messageDisplayAction.disable(); else 
         xnote.WL.messenger.messageDisplayAction.enable(); */
    if (noteExists) {
      document.getElementById('xnote-context-create').setAttribute('hidden', noteExists);
      document.getElementById('xnote-context-modify').removeAttribute('hidden');
      document.getElementById('xnote-context-delete').removeAttribute('hidden');
      document.getElementById('xnote-context-separator-after-delete').removeAttribute('hidden');
      document.getElementById('xnote-context-reset-note-window').removeAttribute('hidden');
    }
    else {
      document.getElementById('xnote-context-create').removeAttribute('hidden');
      document.getElementById('xnote-context-modify').setAttribute('hidden', !noteExists);
      document.getElementById('xnote-context-delete').setAttribute('hidden', !noteExists);
      document.getElementById('xnote-context-separator-after-delete').setAttribute('hidden', !noteExists);
      document.getElementById('xnote-context-reset-note-window').setAttribute('hidden', !noteExists);
    };
    var messageArray = pub.getDBView().getSelectedMsgHdrs(); //115  gFolderDisplay.selectedMessages;
    if (messageArray && messageArray.length == 1) {
      document.getElementById('xnote-mailContext-xNote').setAttribute('disabled', false);
    }
    else {
      document.getElementById('xnote-mailContext-xNote').setAttribute('disabled', true);
    }
  }

  /**
   * FUNCTION
   * For right click in message pane:
   *   - Instantiates an object notes for the message on which was clicked or hovered (!!)
   *   - Functions that are not currently possible are greyed out in the context
   *     menu, e.g., modify or delete a note for a message not containing a note.
   */
  pub.messageListClicked = function (e) {
    if (e.button == 2) {
      updateContextMenu();
    }
    let t = e.originalTarget;
    if (true) { //t.className == "thread-container") {
      let tree = GetThreadTree();
      //   let treeCellInfo = tree.getCellAt(e.clientX, e.clientY);
      currentIndex = tree._selection._currentIndex;
      let gDBView = pub.getDBView();
      window.browsingContext.topChromeWindow.xnoteOverlayObj.msgHdr = gDBView.getMsgHdrAt(currentIndex);
      // console.log("currInd/messlistclicked", currentIndex, gDBView); //115treeCellInfo.row;
    };
  }

  pub.getCurrentRow = function (e) {
    /*102
       let t = e.originalTarget;
       if (t.localName == 'treechildren') {
         let tree = GetThreadTree();
         let treeCellInfo = tree.getCellAt(e.clientX, e.clientY);
         currentIndex = treeCellInfo.row;
       }
     */
    //   console.log("click", e);
    let t = e.originalTarget;
    //TB115  if (t.localName == 'treechildren') {
    if (true) { //t.className == "thread-container") {
      let tree = GetThreadTree();
      //   let treeCellInfo = tree.getCellAt(e.clientX, e.clientY);
      currentIndex = tree._selection._currentIndex;
      //      console.log("currInd", currentIndex); //115treeCellInfo.row;

    };
  }


  pub.messagePaneClicked = function (e) {
    if (e.button == 2) {
      updateContextMenu();
    }
    //  currentIndex = gDBView.selection.currentIndex;
  }

  /**
   * Get message id from selected message
   */
  pub.getMessageID = function () {
    /*
      let message = gFolderDisplay.selectedMessage;
      if (message != null) return message.messageId;
    */
    //    console.log("hdr-id", pub.getDBView(), pub.getDBView().getSelectedMsgHdrs());
    let message = pub.getDBView().hdrForFirstSelectedMessage;
    //  console.log("hdr", message.messageId);

    //  let message = null; //TB115 gFolderDisplay.selectedMessage;
    if (message != null) return message.messageId;
    return null;
  }

  pub.mouseover = function (ev) {
    if (ev.originalTarget.className.includes("xnote")) {
      /*
      //      console.log("mouseover", ev);//, ev.originalTarget.parentElement, ev.originalTarget.parentElement._index);
      //      console.log("mouseover2", this);
      //      console.log("mouseover3", this.id);
      //      console.log("mouseover4", ev.originalTarget);
      //      console.log("mouseover5", ev.originalTarget.parentNode);
      //      console.log("mouseover6", ev.originalTarget.parentNode.id);
      */
      //      console.log("mouseover7", ev.originalTarget.parentNode._index);
      let msgHdr = this._view.getMsgHdrAt(ev.originalTarget.parentNode._index);
      //          console.log("entry", msgHdr, msgHdr.messageId);//, msgHdr.msgId, msgHdr.msgKey, subCol);
      note = new xnote.ns.Note(msgHdr.messageId);
      //subCol.textContent = subCol.title = note.text; 
      if (note.exists()) {
        let ic = '\u{1F4D2}';
        //        console.log("note", ic + note.text);//.substr(0, xnotePrefs.show_first_x_chars_in_col));
        let txt = window.document.createElement("textarea");
        txt.value = note.text;
        txt.style.display = 'block';
        txt.style.maxHeight = "500px";
        /*        let popperOptions = {
                  modifiers: [
                    maxSize,
                    {
                      name: "applyMaxSize",
                      enabled: true,
                      phase: "beforeWrite",
                      requires: ["maxSize"],
                      fn({ state }) {
                        const { height } = state.modifiersData.maxSize;
                        // state.styles.popper.maxHeight = `${height}px`;
                        state.elements.popper.style.setProperty("--max-height", `${height}px`);
                        state.styles.popper.display = "flex";
                      }
                    }
                  ]
                };
        */
        window.tippy(ev.originalTarget,
          {
            maxWidth: 550,
            //         popperOptions:popperOptions,
            allowHTML: true,
            placement: 'right',
            //        appendTo: document.body,
            content: note.text.replace(/\n/g, '<p></p>'),//"test<p></p><b>hhh</b>",//txt, //"<div>"+note.text.replace(/\n/g, '<br>') +"</div>",//replace("\n", "<br/>"),
            /*      
                   function (reference) {
                    //                 console.log("tippy", reference);
                    //                 let content1 = "test";
                    //let imgg = await getImageData(reference.attachment.url);
                     reference._tippy.setContent(note.text);
                    //                 console.log("tipnote", imgg);
                    //var imgNew = tabAbout3pane.messageBrowser.contentDocument.createElement('img')
                    //imgNew.src = "data:image/jpeg;base64," + tabAbout3pane.messageBrowser.contentWindow.btoa(imgg);
                    //imgNew.setAttribute("height", "300");
                    //reference._tippy.setContent(imgNew);
        
                    return note.text.replace("\n", "<br/>");//node.key + " -  <b>" + node.title + "</b>  <p></p> " + note.body;//node.data.body;
                  }
          */
          });

      }
    }
  }


  pub.notef = function (ev) {
    //     console.log("tree changed", ev);
    let aaas = () => {
      let xnotePrefs = xnote.ns.Commons.xnotePrefs;
      xnoteOverlayObj.showXNoteColumn = xnotePrefs.show_column;
      if (xnotePrefs.show_column) {
        //       let locationColButton = ev.originalTarget.children[0].querySelector("#sizeColButton");
        let locationColButton = ev.originalTarget.parentNode.querySelector("#sizeColButton");
        //     console.log("locationColButton", locationColButton);
        let locText = locationColButton.textContent;
        if (xnoteOverlayObj && xnoteOverlayObj.showXNoteColumn) {
          if (!locText.includes("XNote")) {
            xnoteOverlayObj.oldLocationColTitle = locationColButton.textContent;
            locationColButton.textContent = "XNote / " + locationColButton.textContent;
          };
          //         let subCols = ev.originalTarget.children[0].body.querySelectorAll(".sizecol-column");
          let subCols = ev.originalTarget.parentNode.querySelectorAll(".sizecol-column");
          //     console.log("sub", ev.originalTarget.children[0].body, ev.originalTarget.threadTree, subCols.NodeList);
          /*
              subCol.textContent = subCol.title = "bäh";
              let  div = subCol.querySelector(".subject-line");
              let span = div.querySelector("span");
              subCol.title = span.textContent = "bäh1";;//cellTexts[textIndex];
          */
          //        console.log("cols", subCols);
          let subCol;
          for (let ind = 0; ind < subCols.length; ind++) {  //(subCol of subCols) {
            subCol = subCols[ind];
            //         console.log("col", subCol);
            let msgHdr = ev.originalTarget._view.getMsgHdrAt(ind);
            //          console.log("entry", msgHdr, msgHdr.messageId);//, msgHdr.msgId, msgHdr.msgKey, subCol);
            note = new xnote.ns.Note(msgHdr.messageId);
            //subCol.textContent = subCol.title = note.text; 
            if (note.exists()) {
              let ic = '\u{1F4D2}';
              subCol.textContent = ic + note.text.substr(0, xnotePrefs.show_first_x_chars_in_col);
              subCol.title = note.text;
            } else {
              subCol.textContent = subCol.title = "";
            };//"bäh1";
            //  subCol.flattenedTreeParentNode.setAttribute("aria-label",  "bäh1");//attributes["aria-label"]= "bäh1";
            //let  div = subCol.querySelector(".subject-line");
            //let span = div.querySelector("span");
            subCol.title = note.text;;//cellTexts[textIndex];  span.textContent =
          };
        };
      };
    };
    //    setTimeout(aaas, 350);  //use new column
  },

    pub.setTreeListener = function (e) {
      tree.addEventListener("viewchange", pub.notef, true);  //
      tree.addEventListener('click', pub.getCurrentRow, false);
      tree.addEventListener('contextmenu', pub.messageListClicked, false);
      tree.addEventListener("select", pub.notef, true);
      tree.addEventListener("load", pub.notef, true);
      tree.addEventListener("mouseover", pub.mouseover, true);
    },

    /**
     * At each boot of the extension, associate events such as selection of mails,
     * files, or right click on the list of messages. On selection show the associated
     * note.
     */
    pub.onLoad = function (e) {
      //   console.log("onload xn about overlay");
      setTimeout(GetXNoteColumn, 1000);
      try {
        let m3pane = window;//.gTabmail.tabInfo[0].chromeBrowser.contentWindow;//window.gTabmail.currentAbout3Pane
        //      let tree = m3pane.threadTree;//document.getElementById('threadTree');
        //      console.log("pane",m3pane.threadTree ,m3pane.threadTree );
        let tree = GetThreadTree();
        //    console.log("pane",m3pane ,m3pane.threadTree , tree);
        //    tree.addEventListener('contextmenu', pub.messageListClicked, false);
        //    tree.addEventListener('mouseover', pub.getCurrentRow, false);

        //let messagePane = document.getElementById("messagepane");
        //      m3pane.messagePane.addEventListener("contextmenu", pub.messagePaneClicked, false);
        //  tree = GetThreadTree();

        let xnotePrefs = xnote.ns.Commons.xnotePrefs;
        xnoteOverlayObj.showXNoteColumn = xnotePrefs.show_column;
        //   xnoteOverlayObj.showXNoteColumn = true;
        //      console.log("adding view listener", window, window.messagePane.name);
        //       window.addEventListener("viewchange", pub.notef, true);  //
        //      window.threadTree.addEventListener("select", notef);
        //      window.threadTree.addEventListener("load", notef);



        if (tree) {
          tree.addEventListener("viewchange", pub.notef, true);  //
          tree.addEventListener('click', pub.getCurrentRow, false);
          tree.addEventListener('contextmenu', pub.messageListClicked, false);
          tree.addEventListener("select", pub.notef, true);
          tree.addEventListener("load", pub.notef, true);
          //    GetXNoteColumn()
          tree.addEventListener("mouseover", pub.mouseover, false);

          //  setTimeout(setTreeListener, 500);
        };


      }
      catch (e) {
        logException(e, false);
      }
    }

  pub.onUnload = function (e) {
    // console.log("close xn-about-overlay");
    try {
      let m3pane = window;//.gTabmail.currentAbout3Pane
      //     let tree = m3pane.threadTree;// document.getElementById('threadTree');
      //   tree = GetThreadTree();
      //115!!     tree.removeEventListener('mouseover', pub.getCurrentRow);

      // let messagePane = document.getElementById("messagepane");
      //115!!    m3pane.messagePane.removeEventListener("contextmenu", pub.messagePaneClicked);
      //    console.log("removing c ev listener", window, window.messagePane.name);
      //    window.removeEventListener("viewchange", pub.notef);  //
      //      window.removeEventListener("viewchange", pub.notef);  //
      xnoteOverlayObj.showXNoteColumn = false;
      tree = GetThreadTree();
      if (tree) {
        tree.removeEventListener("viewchange", pub.notef);  //
        tree.removeEventListener('click', pub.getCurrentRow);
        tree.removeEventListener('contextmenu', pub.messageListClicked);
        tree.removeEventListener("select", pub.notef);
        tree.removeEventListener("load", pub.notef);
        //
      }
      let locationColButton = window.threadTree.querySelector("#sizeColButton");
      //    console.log("new locationColButton", locationColButton);
      locationColButton.textContent = xnoteOverlayObj.oldLocationColTitle;
      //   console.log("old locationColButton", locationColButton.textContent);
    }
    catch (e) {
      logException(e, false);
    };
    //  console.log("close xn-overlay, unloaded");
  }

  return pub;
}();
