import _defineProperty from "@babel/runtime/helpers/defineProperty";
import { EventEmitter } from 'events';
export class SharedAnnotationManager {
  constructor() {
    /**
     * This is the event emitter that is used to emit events from the manager. It is used to communicate with
     * other parts of the application.
     */
    _defineProperty(this, "emitter", new EventEmitter());
    /**
     * This is the map of hooks that can be added to the manager. Hooks are a 1:1 mapping of methods that can be
     * called on the manager. They are used to extend the functionality of the manager.
     */
    _defineProperty(this, "hooks", new Map());
    _defineProperty(this, "preemptiveGate", () => Promise.resolve(true));
    _defineProperty(this, "activePreemptiveGate", undefined);
  }
  setPreemptiveGate(handler) {
    this.preemptiveGate = handler;
    return this;
  }
  checkPreemptiveGate() {
    if (this.activePreemptiveGate) {
      // If the preemptive gate check already in flight then just return the promise
      // and don't call the preemptive gate again.
      // This is to prevent multiple calls to the preemptive gate creating multiple
      // promises that will resolve at different times.
      return Promise.resolve(this.activePreemptiveGate);
    }
    const gate = this.activePreemptiveGate = this.preemptiveGate().then(result => {
      this.activePreemptiveGate = undefined;
      return result;
    });
    return gate;
  }
  onDraftAnnotationStarted(handler) {
    this.emitter.on('draftAnnotationStarted', handler);
    return this;
  }
  offDraftAnnotationStarted(handler) {
    this.emitter.off('draftAnnotationStarted', handler);
    return this;
  }
  onAnnotationSelectionChange(handler) {
    this.emitter.on('annotationSelectionChanged', handler);
    return this;
  }
  offAnnotationSelectionChange(handler) {
    this.emitter.off('annotationSelectionChanged', handler);
    return this;
  }
  emit(event) {
    this.emitter.emit(event.name, 'data' in event ? event.data : undefined);
    return this;
  }
  hook(method, handler) {
    this.hooks.set(method, handler);
    return this;
  }
  unhook(method, handler) {
    if (!this.hooks.has(method) || this.hooks.get(method) !== handler) {
      return this;
    }
    this.hooks.delete(method);
    return this;
  }
  allowAnnotation() {
    const fn = this.hooks.get('allowAnnotation');
    if (!fn) {
      return false;
    }
    try {
      return fn();
    } catch {
      return false;
    }
  }
  startDraft() {
    const fn = this.hooks.get('startDraft');
    if (!fn) {
      return {
        success: false,
        reason: 'manager-not-initialized'
      };
    }
    try {
      return fn();
    } catch {
      return {
        success: false,
        reason: 'hook-execution-error'
      };
    }
  }
  clearDraft() {
    const fn = this.hooks.get('clearDraft');
    if (!fn) {
      return {
        success: false,
        reason: 'manager-not-initialized'
      };
    }
    try {
      return fn();
    } catch {
      return {
        success: false,
        reason: 'hook-execution-error'
      };
    }
  }
  applyDraft(id) {
    const fn = this.hooks.get('applyDraft');
    if (!fn) {
      return {
        success: false,
        reason: 'manager-not-initialized'
      };
    }
    try {
      return fn(id);
    } catch {
      return {
        success: false,
        reason: 'hook-execution-error'
      };
    }
  }
  getDraft() {
    const fn = this.hooks.get('getDraft');
    if (!fn) {
      return {
        success: false,
        reason: 'manager-not-initialized'
      };
    }
    try {
      return fn();
    } catch {
      return {
        success: false,
        reason: 'hook-execution-error'
      };
    }
  }
  setIsAnnotationSelected(id, isSelected) {
    const fn = this.hooks.get('setIsAnnotationSelected');
    if (!fn) {
      return {
        success: false,
        reason: 'manager-not-initialized'
      };
    }
    try {
      // NOTE: The hook needs to manage the firing the annotationSelectionChanged event when a change is made. This is
      // because the hook is responsible for the state of the selection. The manager is not responsible for the state of
      // the selection.
      return fn(id, isSelected);
    } catch {
      return {
        success: false,
        reason: 'hook-execution-error'
      };
    }
  }
  setIsAnnotationHovered(id, isHovered) {
    const fn = this.hooks.get('setIsAnnotationHovered');
    if (!fn) {
      return {
        success: false,
        reason: 'manager-not-initialized'
      };
    }
    try {
      return fn(id, isHovered);
    } catch {
      return {
        success: false,
        reason: 'hook-execution-error'
      };
    }
  }
  clearAnnotation(id) {
    const fn = this.hooks.get('clearAnnotation');
    if (!fn) {
      return {
        success: false,
        reason: 'manager-not-initialized'
      };
    }
    try {
      return fn(id);
    } catch {
      return {
        success: false,
        reason: 'hook-execution-error'
      };
    }
  }
}