const electron = require('electron');

const app = electron.app;
const Shell = electron.shell;
const Menu = electron.Menu;
const MenuItem = electron.MenuItem;
const ipcMain = electron.ipcMain;

const is = require('electron-is');

var spellingSuggestions = [];
ipcMain.on('set-spelling-suggestions', (event, suggestions) => {
  spellingSuggestions = suggestions;
});

// Some of this is lifted from https://github.com/sindresorhus/electron-context-menu
// But modified beyond the limits of its prepend/append abilities
module.exports = (win) => {
  win.webContents.on('context-menu', (e, props) => {
    const editFlags = props.editFlags;
    const hasText = props.selectionText.trim().length > 0;
    const can = type => editFlags[`can${type}`] && hasText;
    const cmdOrCtrl = e => {
      if (is.macOS()) {
        return e.metaKey;
      } else {
        return e.ctrlKey;
      }
    };

    let template = [];
    spellingSuggestions.forEach(suggestion => {
      template.push({
        label: suggestion,
        click (item, focusedWindow, e) {
          win.webContents.replaceMisspelling(suggestion);
        }
      });
    });

    if (props.linkURL) {
      template.push({
        label: 'Open Link in Browser',
        click (item, focusedWindow, e) {
          Shell.openExternal(props.linkURL, {
            activate: !cmdOrCtrl(e)
          });
        }
      });
    } else {
      if (!props.selectionText) {
        template.push({
          label: 'Back',
          enabled: win.webContents.canGoBack(),
          click (item, focusedWindow, e) {
            win.webContents.goBack();
          }
        }, {
          label: 'Forward',
          enabled: win.webContents.canGoForward(),
          click (item, focusedWindow, e) {
            win.webContents.goForward();
          }
        }, {
          label: 'Reload',
          click(item, focusedWindow, e) {
            win.webContents.reloadIgnoringCache();
          }
        });
      }
    }

    template.push({
      type: 'separator'
    }, {
      label: 'Cut',
      // needed because of macOS limitation:
      // https://github.com/electron/electron/issues/5860
      role: can('Cut') ? 'cut' : '',
      enabled: can('Cut'),
      visible: props.isEditable
    }, {
      label: 'Copy',
      role: can('Copy') ? 'copy' : '',
      enabled: can('Copy'),
      visible: props.isEditable || hasText
    }, {
      label: 'Paste',
      role: editFlags.canPaste ? 'paste' : '',
      enabled: editFlags.canPaste,
      visible: props.isEditable
    }, {
      type: 'separator'
    });

    if (props.linkURL) {
      template.push({
        type: 'separator'
      }, {
        label: 'Save Link As…',
        click (item, focusedWindow, e) {
          app.doDownload(win, props.linkURL, {
            saveAs: !e.altKey
          });

        }
      }, {
        label: 'Copy Link Address',
        click (item, focusedWindow, e) {
          if (is.linux() || !props.linkText) {
            electron.clipboard.writeText(props.linkURL);
          } else {
            electron.clipboard.writeBookmark(props.linkText, props.linkURL);
          }
        }
      }, {
        type: 'separator'
      });
    }

    if (props.mediaType === 'image') {
      template.push({
        type: 'separator'
      }, {
        label: 'Open Image in Browser',
        click (item, focusedWindow, e) {
          Shell.openExternal(props.srcURL, {
            activate: !cmdOrCtrl(e)
          });
        }
      }, {
        label: 'Save Image As…',
        click (item, focusedWindow, e) {
          app.doDownload(win, props.srcURL, {
            saveAs: !e.altKey
          });
        }
      }, {
        label: 'Copy Image',
        click (item, focusedWindow, e) {
          win.webContents.copyImageAt(props.x, props.y);
        }
      }, {
        label: 'Copy Image Address',
        click (item, focusedWindow, e) {
          electron.clipboard.writeText(props.srcURL);
        }
      }, {
        type: 'separator'
      });
    }

    template.push({
      type: 'separator'
    }, {
      label: 'Inspect Element',
      click (item, focusedWindow, e) {
        win.webContents.inspectElement(props.x, props.y);
        if (win.webContents.isDevToolsOpened()) {
          win.webContents.devToolsWebContents.focus();
        }
      }
    }, {
      type: 'separator'
    });

    if (hasText && is.macOS()) {
      template.push({
        role: 'services',
        submenu: []
      }, {
        type: 'separator'
      });
    }


    template = delUnusedElements(template);

    const menu = Menu.buildFromTemplate(template);
    setTimeout(() => {
      menu.popup(win);
    }, 20);
  });
};

// copied from https://github.com/sindresorhus/electron-context-menu/blob/master/index.js
// filter out leading/trailing/duplicate separators
// TODO: https://github.com/electron/electron/issues/5869
function delUnusedElements(menuTpl) {
  let notDeletedPrevEl;
  return menuTpl.filter(el => el.visible !== false).filter((el, i, arr) => {
    const toDelete = el.type === 'separator' && (!notDeletedPrevEl || i === arr.length - 1 || arr[i + 1].type === 'separator');
    notDeletedPrevEl = toDelete ? notDeletedPrevEl : el;
    return !toDelete;
  });
}
@@ -2924,57 +2924,8 @@
 ) %7B%0A
-          if (is.linux() %7C%7C !props.linkText) %7B%0A  
     
@@ -2950,29 +2950,45 @@
 pboard.write
-Text(
+(%7B%0A            text: 
 props.linkUR
@@ -2992,75 +2992,32 @@
 kURL
-);%0A          %7D else %7B%0A            electron.clipboard.writeB
+,%0A            b
 ookmark
-(
+: 
 prop
@@ -3030,25 +3030,8 @@
 Text
-, props.linkURL);
 %0A   
@@ -3030,32 +3030,34 @@
 Text%0A          %7D
+);
 %0A        %7D%0A     

Switch to clipboard.write which should handle both text and bookmarks when supported. Fixes #104