text: import { Template } from 'meteor/templating';
  import { Blaze } from 'meteor/blaze';
  import Hammer from 'hammerjs';
  import { OHIF } from 'meteor/ohif:core';
  
  // Clear all selected studies
  function doClearStudySelections() {
      OHIF.studylist.collections.Studies.update({}, {
          $set: { selected: false }
      }, { multi: true });
  }
  
  function doSelectRow($studyRow, data) {
      // Mark the current study as selected if it's not marked yet
      if (!data.selected) {
          const filter = { studyInstanceUid: data.studyInstanceUid };
          const modifiers = { $set: { selected: true } };
          OHIF.studylist.collections.Studies.update(filter, modifiers);
      }
  
      // Set it as the previously selected row, so the user can use Shift to select from this point on
      OHIF.studylist.$lastSelectedRow = $studyRow;
  }
  
  function doSelectSingleRow($studyRow, data) {
      // Clear all selected studies
      doClearStudySelections();
  
      // Add selected row to selection list
      doSelectRow($studyRow, data);
  }
  
  function doUnselectRow($studyRow, data) {
      // Find the current studyInstanceUid in the stored list and mark as unselected
      const filter = { studyInstanceUid: data.studyInstanceUid };
      const modifiers = { $set: { selected: false } };
      OHIF.studylist.collections.Studies.update(filter, modifiers);
  }
  
  function handleShiftClick($studyRow, data) {
      let study;
      let $previousRow = OHIF.studylist.$lastSelectedRow;
      if ($previousRow && $previousRow.length > 0) {
          study = Blaze.getData($previousRow.get(0));
          if (!study.selected) {
              $previousRow = $(); // undefined
              OHIF.studylist.$lastSelectedRow = $previousRow;
          }
      }
  
      // Select all rows in between these two rows
      if ($previousRow.length) {
          let $rowsInBetween;
          if ($previousRow.index() < $studyRow.index()) {
              // The previously selected row is above (lower index) the
              // currently selected row.
  
              // Fill in the rows upwards from the previously selected row
              $rowsInBetween = $previousRow.nextAll('tr');
          } else if ($previousRow.index() > $studyRow.index()) {
              // The previously selected row is below the currently
              // selected row.
  
              // Fill in the rows upwards from the previously selected row
              $rowsInBetween = $previousRow.prevAll('tr');
          } else {
              // nothing to do since $previousRow.index() === $studyRow.index()
              // the user is shift-clicking the same row...
              return;
          }
  
          // Loop through the rows in between current and previous selected studies
          $rowsInBetween.each((index, row) => {
              const $row = $(row);
  
              // Retrieve the data context through Blaze
              const data = Blaze.getData(row);
  
              // If we find one that is already selected, do nothing
              if (data.selected) return;
  
              // Set the current study as selected
              doSelectRow($row, data);
  
              // When we reach the currently clicked-on $row, stop the loop
              return !$row.is($studyRow);
          });
      } else {
          // Set the current study as selected
          doSelectSingleRow($studyRow, data);
      }
  }
  
  function handleCtrlClick($studyRow, data) {
      const handler = data.selected ? doUnselectRow : doSelectRow;
      handler($studyRow, data);
  }
  
  Template.studylistStudy.onRendered(() => {
      const instance = Template.instance();
      const data = instance.data;
      const $row = instance.$('tr.studylistStudy').first();
  
      // Enable HammerJS to allow touch support
      const mc = new Hammer.Manager($row.get(0));
      const doubleTapRecognizer = new Hammer.Tap({
          event: 'doubletap',
          taps: 2,
          interval: 500,
          threshold: 30,
          posThreshold: 30
      });
      mc.add(doubleTapRecognizer);
  
      // Check if current row has been previously selected
      if (data.selected) {
          doSelectRow($row, data);
      }
  });
  
  Template.studylistStudy.events({
      'click tr.studylistStudy'(event, instance) {
          const $studyRow = $(event.currentTarget);
          const data = instance.data;
  
          // Remove the ID so we can directly insert this into our client-side collection
          delete data._id;
  
          if (event.shiftKey) {
              handleShiftClick($studyRow, data);
          } else if (event.ctrlKey || event.metaKey) {
              handleCtrlClick($studyRow, data);
          } else {
              doSelectSingleRow($studyRow, data);
          }
      },
  
      'mousedown tr.studylistStudy'(event, instance) {
          // This event handler is meant to handle middle-click on a study
          if (event.which !== 2) {
              return;
          }
  
          const middleClickOnStudy = OHIF.studylist.callbacks.middleClickOnStudy;
          if (middleClickOnStudy && typeof middleClickOnStudy === 'function') {
              middleClickOnStudy(instance.data);
          }
      },
  
      'dblclick tr.studylistStudy, doubletap tr.studylistStudy'(event, instance) {
          if (event.which !== undefined && event.which !== 1) {
              return;
          }
  
          const dblClickOnStudy = OHIF.studylist.callbacks.dblClickOnStudy;
  
          if (dblClickOnStudy && typeof dblClickOnStudy === 'function') {
              dblClickOnStudy(instance.data);
          }
      },
  
      'contextmenu tr.studylistStudy, press tr.studylistStudy'(event, instance) {
          const $studyRow = $(event.currentTarget);
  
          if (!instance.data.selected) {
              doSelectSingleRow($studyRow, instance.data);
          }
  
          event.preventDefault();
          OHIF.ui.showDropdown(OHIF.studylist.dropdown.getItems(), {
              event,
              menuClasses: 'dropdown-menu-left'
          });
          return false;
      }
  });
  