'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.dispatchSaveAs = dispatchSaveAs;
exports.showSaveAsDialog = showSaveAsDialog;
exports.triggerWindowRefresh = triggerWindowRefresh;
exports.dispatchRestartKernel = dispatchRestartKernel;
exports.triggerKernelRefresh = triggerKernelRefresh;
exports.triggerSaveAs = triggerSaveAs;
exports.dispatchSave = dispatchSave;
exports.dispatchNewKernel = dispatchNewKernel;
exports.dispatchPublishAnonGist = dispatchPublishAnonGist;
exports.dispatchRunAll = dispatchRunAll;
exports.dispatchClearAll = dispatchClearAll;
exports.dispatchKillKernel = dispatchKillKernel;
exports.dispatchInterruptKernel = dispatchInterruptKernel;
exports.dispatchRestartClearAll = dispatchRestartClearAll;
exports.dispatchZoomIn = dispatchZoomIn;
exports.dispatchZoomOut = dispatchZoomOut;
exports.dispatchSetTheme = dispatchSetTheme;
exports.dispatchCopyCell = dispatchCopyCell;
exports.dispatchCutCell = dispatchCutCell;
exports.dispatchPasteCell = dispatchPasteCell;
exports.dispatchCreateCellAfter = dispatchCreateCellAfter;
exports.dispatchLoad = dispatchLoad;
exports.dispatchNewNotebook = dispatchNewNotebook;
exports.dispatchPublishUserGist = dispatchPublishUserGist;
exports.initMenuHandlers = initMenuHandlers;

var _electron = require('electron');

var _path = require('path');

var path = _interopRequireWildcard(_path);

var _homeDir = require('home-dir');

var _homeDir2 = _interopRequireDefault(_homeDir);

var _nativeWindow = require('./native-window');

var _execute = require('./epics/execute');

var _theming = require('./epics/theming');

var _githubPublish = require('./epics/github-publish');

var _loading = require('./epics/loading');

var _actions = require('./actions');

var _saving = require('./epics/saving');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

const BrowserWindow = _electron.remote.BrowserWindow;

function dispatchSaveAs(store, evt, filename) {
  const state = store.getState();
  const notebook = state.document.get('notebook');
  store.dispatch((0, _saving.saveAs)(filename, notebook));
}

const remoteElectron = _electron.remote.require('electron');
const dialog = remoteElectron.dialog;

function showSaveAsDialog(defaultPath) {
  return new Promise(resolve => {
    const filename = dialog.showSaveDialog({
      title: 'Save Notebook',
      defaultPath,
      filters: [{ name: 'Notebooks', extensions: ['ipynb'] }]
    });

    if (filename && path.extname(filename) === '') {
      resolve(`${ filename }.ipynb`);
    }
    resolve(filename);
  });
}

function triggerWindowRefresh(store, filename) {
  if (!filename) {
    return;
  }
  const state = store.getState();
  const executionState = state.app.get('executionState');
  const notebook = state.document.get('notebook');
  store.dispatch((0, _saving.saveAs)(filename, notebook));
}

function dispatchRestartKernel(store) {
  const state = store.getState();
  const notificationSystem = state.app.get('notificationSystem');
  const spawnOptions = {};
  if (state && state.document && state.metadata.get('filename')) {
    spawnOptions.cwd = path.dirname(path.resolve(state.metadata.filename));
  }

  store.dispatch(_actions.killKernel);
  store.dispatch((0, _actions.newKernel)(state.app.kernelSpecName, spawnOptions));

  notificationSystem.addNotification({
    title: 'Kernel Restarted',
    message: `Kernel ${ state.app.kernelSpecName } has been restarted.`,
    dismissible: true,
    position: 'tr',
    level: 'success'
  });
}

function triggerKernelRefresh(store) {
  dialog.showMessageBox({
    type: 'question',
    buttons: ['Launch New Kernel', 'Don\'t Launch New Kernel'],
    title: 'New Kernel Needs to Be Launched',
    message: 'It looks like you\'ve saved your notebook file to a new location.',
    detail: 'The kernel executing your code thinks your notbook is still in the ' + 'old location. Would you like to launch a new kernel to match it with the ' + 'new location of the notebook?'
  }, index => {
    if (index === 0) {
      dispatchRestartKernel(store);
    }
  });
}

function triggerSaveAs(store) {
  showSaveAsDialog(_electron.remote.app.getPath('home')).then(filename => {
    triggerWindowRefresh(store, filename);
    triggerKernelRefresh(store);
  });
}

function dispatchSave(store) {
  const state = store.getState();
  const notebook = state.document.get('notebook');
  const filename = state.metadata.get('filename');
  const notificationSystem = state.app.get('notificationSystem');
  try {
    if (!filename) {
      triggerSaveAs(store);
    } else {
      store.dispatch((0, _saving.save)(filename, notebook));
    }
    notificationSystem.addNotification({
      title: 'Save successful!',
      autoDismiss: 2,
      level: 'success'
    });
  } catch (err) {
    notificationSystem.addNotification({
      title: 'Save failed!',
      message: err.message,
      level: 'error'
    });
  }
}

function dispatchNewKernel(store, evt, name) {
  const state = store.getState();
  const spawnOptions = {};
  if (state && state.document && state.metadata.get('filename')) {
    spawnOptions.cwd = path.dirname(path.resolve(state.metadata.get('filename')));
  }
  store.dispatch((0, _actions.newKernel)(name, spawnOptions));
}

function dispatchPublishAnonGist(store) {
  store.dispatch((0, _actions.setAnonGithub)());
  store.dispatch({ type: 'PUBLISH_GIST' });
}

function dispatchRunAll(store) {
  const state = store.getState();
  const notebook = state.document.get('notebook');
  const cells = notebook.get('cellMap');
  notebook.get('cellOrder').filter(cellID => cells.getIn([cellID, 'cell_type']) === 'code').map(cellID => store.dispatch((0, _execute.executeCell)(cellID, cells.getIn([cellID, 'source']))));
}

function dispatchClearAll(store) {
  const state = store.getState();
  const notebook = state.document.get('notebook');
  notebook.get('cellOrder').map(value => store.dispatch((0, _actions.clearCellOutput)(value)));
}

function dispatchKillKernel(store) {
  store.dispatch(_actions.killKernel);
}

function dispatchInterruptKernel(store) {
  const state = store.getState();
  const notificationSystem = state.app.get('notificationSystem');
  if (process.platform === 'win32') {
    notificationSystem.addNotification({
      title: 'Not supported in Windows',
      message: 'Kernel interruption is currently not supported in Windows.',
      level: 'error'
    });
  } else {
    store.dispatch(_actions.interruptKernel);
  }
}

function dispatchRestartClearAll(store) {
  dispatchRestartKernel(store);
  dispatchClearAll(store);
}

function dispatchZoomIn() {
  _electron.webFrame.setZoomLevel(_electron.webFrame.getZoomLevel() + 1);
}

function dispatchZoomOut() {
  _electron.webFrame.setZoomLevel(_electron.webFrame.getZoomLevel() - 1);
}

function dispatchSetTheme(store, evt, theme) {
  store.dispatch((0, _theming.setTheme)(theme));
}

function dispatchCopyCell(store) {
  const state = store.getState();
  const focused = state.document.get('focusedCell');
  store.dispatch((0, _actions.copyCell)(focused));
}

function dispatchCutCell(store) {
  const state = store.getState();
  const focused = state.document.get('focusedCell');
  store.dispatch((0, _actions.cutCell)(focused));
}

function dispatchPasteCell(store) {
  store.dispatch((0, _actions.pasteCell)());
}

function dispatchCreateCellAfter(store) {
  const state = store.getState();
  const focused = state.document.get('focusedCell');
  store.dispatch((0, _actions.createCellAfter)('code', focused));
}

function dispatchLoad(store, event, filename) {
  store.dispatch((0, _loading.load)(filename));
}

function dispatchNewNotebook(store, event, kernelSpecName) {
  store.dispatch((0, _loading.newNotebook)(kernelSpecName, (0, _homeDir2.default)()));
}

function dispatchPublishUserGist(store, event, githubToken) {
  if (githubToken) {
    store.dispatch((0, _actions.setGithubToken)(githubToken));
  } else {
    const state = store.getState();
    const token = state.app.get('token');
    store.dispatch((0, _actions.setGithubToken)(token));
  }
  store.dispatch((0, _actions.setUserGithub)());
  store.dispatch({ type: 'PUBLISH_GIST' });
}

function initMenuHandlers(store) {
  _electron.ipcRenderer.on('menu:new-kernel', dispatchNewKernel.bind(null, store));
  _electron.ipcRenderer.on('menu:run-all', dispatchRunAll.bind(null, store));
  _electron.ipcRenderer.on('menu:clear-all', dispatchClearAll.bind(null, store));
  _electron.ipcRenderer.on('menu:save', dispatchSave.bind(null, store));
  _electron.ipcRenderer.on('menu:save-as', dispatchSaveAs.bind(null, store));
  _electron.ipcRenderer.on('menu:new-code-cell', dispatchCreateCellAfter.bind(null, store));
  _electron.ipcRenderer.on('menu:copy-cell', dispatchCopyCell.bind(null, store));
  _electron.ipcRenderer.on('menu:cut-cell', dispatchCutCell.bind(null, store));
  _electron.ipcRenderer.on('menu:paste-cell', dispatchPasteCell.bind(null, store));
  _electron.ipcRenderer.on('menu:kill-kernel', dispatchKillKernel.bind(null, store));
  _electron.ipcRenderer.on('menu:interrupt-kernel', dispatchInterruptKernel.bind(null, store));
  _electron.ipcRenderer.on('menu:restart-kernel', dispatchRestartKernel.bind(null, store));
  _electron.ipcRenderer.on('menu:restart-and-clear-all', dispatchRestartClearAll.bind(null, store));
  _electron.ipcRenderer.on('menu:publish:gist', dispatchPublishAnonGist.bind(null, store));
  _electron.ipcRenderer.on('menu:zoom-in', dispatchZoomIn.bind(null, store));
  _electron.ipcRenderer.on('menu:zoom-out', dispatchZoomOut.bind(null, store));
  _electron.ipcRenderer.on('menu:theme', dispatchSetTheme.bind(null, store));
  _electron.ipcRenderer.on('menu:github:auth', dispatchPublishUserGist.bind(null, store));
  // OCD: This is more like the registration of main -> renderer thread
  _electron.ipcRenderer.on('main:load', dispatchLoad.bind(null, store));
  _electron.ipcRenderer.on('main:new', dispatchNewNotebook.bind(null, store));
}