text: import { Meteor } from 'meteor/meteor';
  import { Session } from 'meteor/session';
  import { $ } from 'meteor/jquery';
  import { _ } from 'meteor/underscore';
  import { OHIF } from 'meteor/ohif:core';
  import { toolManager } from './toolManager';
  import { switchToImageRelative } from './switchToImageRelative';
  import { switchToImageByIndex } from './switchToImageByIndex';
  import { viewportUtils } from './viewportUtils';
  import { panelNavigation } from './panelNavigation';
  import { WLPresets } from './WLPresets';
  
  // TODO: add this to namespace definitions
  Meteor.startup(function() {
      OHIF.viewer.loadIndicatorDelay = 200;
      OHIF.viewer.defaultTool = 'wwwc';
      OHIF.viewer.refLinesEnabled = true;
      OHIF.viewer.isPlaying = {};
      OHIF.viewer.cine = {
          framesPerSecond: 24,
          loop: true
      };
  
      OHIF.viewer.defaultHotkeys = {
          // Tool hotkeys
          defaultTool: 'ESC',
          zoom: 'Z',
          wwwc: 'W',
          pan: 'P',
          angle: 'A',
          stackScroll: 'S',
          magnify: 'M',
          length: '',
          annotate: '',
          dragProbe: '',
          ellipticalRoi: '',
          rectangleRoi: '',
  
          // Viewport hotkeys
          flipH: 'H',
          flipV: 'V',
          rotateR: 'R',
          rotateL: 'L',
          invert: 'I',
          zoomIn: '',
          zoomOut: '',
          zoomToFit: '',
          resetViewport: '',
          clearTools: '',
  
          // Viewport navigation hotkeys
          scrollDown: 'DOWN',
          scrollUp: 'UP',
          scrollLastImage: 'END',
          scrollFirstImage: 'HOME',
          previousDisplaySet: 'PAGEUP',
          nextDisplaySet: 'PAGEDOWN',
          nextPanel: 'RIGHT',
          previousPanel: 'LEFT',
  
          // Miscellaneous hotkeys
          toggleOverlayTags: 'SHIFT',
          toggleCinePlay: 'SPACE',
          toggleCineDialog: '',
          toggleDownloadDialog: '',
  
          // Preset hotkeys
          WLPreset0: '1',
          WLPreset1: '2',
          WLPreset2: '3',
          WLPreset3: '4',
          WLPreset4: '5',
          WLPreset5: '6',
          WLPreset6: '7',
          WLPreset7: '8',
          WLPreset8: '9',
          WLPreset9: '0'
      };
  
      // For now
      OHIF.viewer.hotkeys = OHIF.viewer.defaultHotkeys;
  
      // Create commands context for viewer
      const contextName = 'viewer';
      OHIF.commands.createContext(contextName);
  
      // Create a function that returns true if the active viewport is empty
      const isActiveViewportEmpty = () => {
          const activeViewport = Session.get('activeViewport') || 0;
          return $('.imageViewerViewport').eq(activeViewport).hasClass('empty');
      };
  
      // Functions to register the tool switching commands
      const registerToolCommands = map => _.each(map, (commandName, toolId) => {
          OHIF.commands.register(contextName, toolId, {
              name: commandName,
              action: toolManager.setActiveTool,
              params: toolId
          });
      });
  
      // Register the default tool command
      OHIF.commands.register(contextName, 'defaultTool', {
          name: 'Default Tool',
          action: () => toolManager.setActiveTool(toolManager.getDefaultTool())
      });
  
      // Register the tool switching commands
      registerToolCommands({
          wwwc: 'W/L',
          zoom: 'Zoom',
          angle: 'Angle Measurement',
          dragProbe: 'Pixel Probe',
          fiducial: 'Fiducial',
          aiFiducial: 'AI Fiducial',
          scrollSync: 'Scroll Sync',
          serverProbe: 'Server Probe',
          ellipticalRoi: 'Elliptical ROI',
          rectangleRoi: 'Rectangle ROI',
          magnify: 'Magnify',
          annotate: 'Annotate',
          stackScroll: 'Scroll Stack',
          pan: 'Pan',
          length: 'Length Measurement',
          wwwcRegion: 'W/L by Region',
          crosshairs: 'Crosshairs'
      });
  
      // Functions to register the viewport commands
      const registerViewportCommands = map => _.each(map, (commandName, commandId) => {
          OHIF.commands.register(contextName, commandId, {
              name: commandName,
              action: viewportUtils[commandId],
              disabled: isActiveViewportEmpty
          });
      });
  
      // Register the viewport commands
      registerViewportCommands({
          zoomIn: 'Zoom In',
          zoomOut: 'Zoom Out',
          zoomToFit: 'Zoom to Fit',
          invert: 'Invert',
          flipH: 'Flip Horizontally',
          flipV: 'Flip Vertically',
          rotateR: 'Rotate Right',
          rotateL: 'Rotate Left',
          resetViewport: 'Reset',
          clearTools: 'Clear Tools'
      });
  
      // Register the preset switching commands
      const applyPreset = presetName => WLPresets.applyWLPresetToActiveElement(presetName);
      for (let i = 0; i < 10; i++) {
          OHIF.commands.register(contextName, `WLPreset${i}`, {
              name: `W/L Preset ${i + 1}`,
              action: applyPreset,
              params: i
          });
      }
  
      // Check if display sets can be moved
      const canMoveDisplaySets = isNext => {
          if (!OHIF.viewerbase.layoutManager) {
              return false;
          } else {
              return OHIF.viewerbase.layoutManager.canMoveDisplaySets(isNext);
          }
      };
  
      // Register viewport navigation commands
      OHIF.commands.set(contextName, {
          scrollDown: {
              name: 'Scroll Down',
              action: () => !isActiveViewportEmpty() && switchToImageRelative(1)
          },
          scrollUp: {
              name: 'Scroll Up',
              action: () => !isActiveViewportEmpty() && switchToImageRelative(-1)
          },
          scrollFirstImage: {
              name: 'Scroll to First Image',
              action: () => !isActiveViewportEmpty() && switchToImageByIndex(0)
          },
          scrollLastImage: {
              name: 'Scroll to Last Image',
              action: () => !isActiveViewportEmpty() && switchToImageByIndex(-1)
          },
          previousDisplaySet: {
              name: 'Previous Series',
              action: () => OHIF.viewerbase.layoutManager.moveDisplaySets(false),
              disabled: () => !canMoveDisplaySets(false)
          },
          nextDisplaySet: {
              name: 'Next Series',
              action: () => OHIF.viewerbase.layoutManager.moveDisplaySets(true),
              disabled: () => !canMoveDisplaySets(true)
          },
          nextPanel: {
              name: 'Next Panel',
              action: () => panelNavigation.loadNextActivePanel()
          },
          previousPanel: {
              name: 'Previous Panel',
              action: () => panelNavigation.loadPreviousActivePanel()
          }
      }, true);
  
      // Register miscellaneous commands
      OHIF.commands.set(contextName, {
          toggleOverlayTags: {
              name: 'Toggle Image Annotations',
              action() {
                  const $dicomTags = $('.imageViewerViewportOverlay .dicomTag');
                  $dicomTags.toggle($dicomTags.eq(0).css('display') === 'none');
              }
          },
          toggleCinePlay: {
              name: 'Play/Pause Cine',
              action: viewportUtils.toggleCinePlay,
              disabled: OHIF.viewerbase.viewportUtils.hasMultipleFrames
          },
          toggleCineDialog: {
              name: 'Show/Hide Cine Controls',
              action: viewportUtils.toggleCineDialog,
              disabled: OHIF.viewerbase.viewportUtils.hasMultipleFrames
          },
          toggleDownloadDialog: {
              name: 'Show/Hide Download Dialog',
              action: viewportUtils.toggleDownloadDialog,
              disabled: () => !viewportUtils.isDownloadEnabled()
          }
      }, true);
  
      OHIF.viewer.hotkeyFunctions = {};
  
      OHIF.viewer.loadedSeriesData = {};
  
      // Enable hotkeys
      hotkeyUtils.enableHotkeys();
  });
  
  // Define a jQuery reverse function
  $.fn.reverse = [].reverse;
  
  /**
   * Overrides OHIF's refLinesEnabled
   * @param  {Boolean} refLinesEnabled True to enable and False to disable
   */
  function setOHIFRefLines(refLinesEnabled) {
      OHIF.viewer.refLinesEnabled = refLinesEnabled;
  }
  
  /**
   * Overrides OHIF's hotkeys
   * @param  {Object} hotkeys Object with hotkeys mapping
   */
  function setOHIFHotkeys(hotkeys) {
      OHIF.viewer.hotkeys = hotkeys;
  }
  
  /**
   * Binds all hotkeys keydown events to the tasks defined in
   * OHIF.viewer.hotkeys or a given param
   * @param  {Object} hotkeys hotkey and task mapping (not required). If not given, uses OHIF.viewer.hotkeys
   */
  function enableHotkeys(hotkeys) {
      const definitions = hotkeys || OHIF.viewer.hotkeys;
      OHIF.hotkeys.set('viewer', definitions, true);
      OHIF.context.set('viewer');
  }
  
  /**
   * Export functions inside hotkeyUtils namespace.
   */
  
  const hotkeyUtils = {
      setOHIFRefLines, /* @TODO: find a better place for this...  */
      setOHIFHotkeys,
      enableHotkeys
  };
  
  export { hotkeyUtils };
  