var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var media_clip_selector_exports = {};
__export(media_clip_selector_exports, {
  default: () => media_clip_selector_default
});
module.exports = __toCommonJS(media_clip_selector_exports);
var import_server_safe_globals = require("../../utils/server-safe-globals.js");
var import_constants = require("../../constants.js");
var import_element_utils = require("../../utils/element-utils.js");
const template = import_server_safe_globals.document.createElement("template");
const HANDLE_W = 8;
const Z = {
  100: 100,
  200: 200,
  300: 300
};
function lockBetweenZeroAndOne(num) {
  return Math.max(0, Math.min(1, num));
}
template.innerHTML = `
  <style>
    #selectorContainer {
      background-color: transparent;
      height: 44px;
      width: 100%;
      display: flex;
      position: relative;
    }

    #timeline {
      width: 100%;
      height: 10px;
      background: #ccc;
      position: absolute;
      top: 16px;
      z-index: ${Z["100"]};
    }

    #startHandle, #endHandle {
      cursor: var(--media-cursor, pointer);
      height: 80%;
      width: ${HANDLE_W}px;
      border-radius: 4px;
      background-color: royalblue;
    }

    #playhead {
      height: 100%;
      width: 3px;
      background-color: #aaa;
      position: absolute;
      display: none;
      z-index: ${Z["300"]};
    }

    #selection {
      display: flex;
      z-index: ${Z["200"]};
      width: 25%;
      height: 100%;
      align-items: center;
    }

    #leftTrim {
      width: 25%;
    }

    #spacer {
      flex: 1;
      background-color: cornflowerblue;
      height: 40%;
    }

    #thumbnailContainer {
      display: none;
      position: absolute;
      top: 0;
    }

    media-preview-thumbnail {
      position: absolute;
      bottom: 10px;
      border: 2px solid #fff;
      border-radius: 2px;
      background-color: #000;
      width: 160px;
      height: 90px;

      /* Negative offset of half to center on the handle */
      margin-left: -80px;
    }

    /* Can't get this working. Trying a downward triangle. */
    /* media-preview-thumbnail::after {
      content: "";
      display: block;
      width: 300px;
      height: 300px;
      margin: 100px;
      background-color: #ff0;
    } */

    :host(:hover) #thumbnailContainer.enabled {
      display: block;
      animation: fadeIn ease 0.5s;
    }

    @keyframes fadeIn {
      0% {
        /* transform-origin: bottom center; */
        /* transform: scale(0.7); */
        margin-top: 10px;
        opacity: 0;
      }
      100% {
        /* transform-origin: bottom center; */
        /* transform: scale(1); */
        margin-top: 0;
        opacity: 1;
      }
    }
  </style>
  <div id="thumbnailContainer">
    <media-preview-thumbnail></media-preview-thumbnail>
  </div>
  <div id="selectorContainer">
    <div id="timeline"></div>
    <div id="playhead"></div>
    <div id="leftTrim"></div>
    <div id="selection">
      <div id="startHandle"></div>
      <div id="spacer"></div>
      <div id="endHandle"></div>
    </div>
  </div>
`;
class MediaClipSelector extends import_server_safe_globals.globalThis.HTMLElement {
  static get observedAttributes() {
    return [
      "thumbnails",
      import_constants.MediaUIAttributes.MEDIA_DURATION,
      import_constants.MediaUIAttributes.MEDIA_CURRENT_TIME
    ];
  }
  constructor() {
    var _a, _b, _c;
    super();
    if (!this.shadowRoot) {
      this.attachShadow({ mode: "open" });
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
    this.draggingEl = null;
    this.wrapper = this.shadowRoot.querySelector("#selectorContainer");
    this.selection = this.shadowRoot.querySelector("#selection");
    this.playhead = this.shadowRoot.querySelector("#playhead");
    this.leftTrim = this.shadowRoot.querySelector("#leftTrim");
    this.spacerFirst = this.shadowRoot.querySelector("#spacerFirst");
    this.startHandle = this.shadowRoot.querySelector("#startHandle");
    this.spacerMiddle = this.shadowRoot.querySelector("#spacerMiddle");
    this.endHandle = this.shadowRoot.querySelector("#endHandle");
    this.spacerLast = this.shadowRoot.querySelector("#spacerLast");
    this._clickHandler = this.handleClick.bind(this);
    this._dragStart = this.dragStart.bind(this);
    this._dragEnd = this.dragEnd.bind(this);
    this._drag = this.drag.bind(this);
    this.wrapper.addEventListener("click", this._clickHandler, false);
    this.wrapper.addEventListener("touchstart", this._dragStart, false);
    (_a = import_server_safe_globals.globalThis.window) == null ? void 0 : _a.addEventListener("touchend", this._dragEnd, false);
    this.wrapper.addEventListener("touchmove", this._drag, false);
    this.wrapper.addEventListener("mousedown", this._dragStart, false);
    (_b = import_server_safe_globals.globalThis.window) == null ? void 0 : _b.addEventListener("mouseup", this._dragEnd, false);
    (_c = import_server_safe_globals.globalThis.window) == null ? void 0 : _c.addEventListener("mousemove", this._drag, false);
    this.enableThumbnails();
  }
  get mediaDuration() {
    return +this.getAttribute(import_constants.MediaUIAttributes.MEDIA_DURATION);
  }
  set mediaDuration(value) {
    (0, import_element_utils.setNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_DURATION, value);
  }
  get mediaCurrentTime() {
    return +this.getAttribute(import_constants.MediaUIAttributes.MEDIA_CURRENT_TIME);
  }
  set mediaCurrentTime(value) {
    (0, import_element_utils.setNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_CURRENT_TIME, value);
  }
  /*
   * pass in a mouse event (evt.clientX)
   * calculates the percentage progress based on the bounding rectang
   * converts the percentage progress into a duration in seconds
   */
  getPlayheadBasedOnMouseEvent(evt) {
    const duration = this.mediaDuration;
    if (!duration)
      return;
    const mousePercent = lockBetweenZeroAndOne(this.getMousePercent(evt));
    return mousePercent * duration;
  }
  getXPositionFromMouse(evt) {
    let clientX;
    if (["touchstart", "touchmove"].includes(evt.type)) {
      clientX = evt.touches[0].clientX;
    }
    return clientX || evt.clientX;
  }
  getMousePercent(evt) {
    const rangeRect = this.wrapper.getBoundingClientRect();
    const mousePercent = (this.getXPositionFromMouse(evt) - rangeRect.left) / rangeRect.width;
    return lockBetweenZeroAndOne(mousePercent);
  }
  dragStart(evt) {
    if (evt.target === this.startHandle) {
      this.draggingEl = this.startHandle;
    }
    if (evt.target === this.endHandle) {
      this.draggingEl = this.endHandle;
    }
    this.initialX = this.getXPositionFromMouse(evt);
  }
  dragEnd() {
    this.initialX = null;
    this.draggingEl = null;
  }
  setSelectionWidth(selectionPercent, fullTimelineWidth) {
    let percent = selectionPercent;
    const minWidthPx = HANDLE_W * 3;
    const minWidthPercent = lockBetweenZeroAndOne(
      minWidthPx / fullTimelineWidth
    );
    if (percent < minWidthPercent) {
      percent = minWidthPercent;
    }
    this.selection.style.width = `${percent * 100}%`;
  }
  drag(evt) {
    if (!this.draggingEl) {
      return;
    }
    evt.preventDefault();
    const rangeRect = this.wrapper.getBoundingClientRect();
    const fullTimelineWidth = rangeRect.width;
    const endXPosition = this.getXPositionFromMouse(evt);
    const xDelta = endXPosition - this.initialX;
    const percent = this.getMousePercent(evt);
    const selectionW = this.selection.getBoundingClientRect().width;
    if (this.draggingEl === this.startHandle) {
      this.initialX = this.getXPositionFromMouse(evt);
      this.leftTrim.style.width = `${percent * 100}%`;
      const selectionPercent = lockBetweenZeroAndOne(
        (selectionW - xDelta) / fullTimelineWidth
      );
      this.setSelectionWidth(selectionPercent, fullTimelineWidth);
    }
    if (this.draggingEl === this.endHandle) {
      this.initialX = this.getXPositionFromMouse(evt);
      const selectionPercent = lockBetweenZeroAndOne(
        (selectionW + xDelta) / fullTimelineWidth
      );
      this.setSelectionWidth(selectionPercent, fullTimelineWidth);
    }
    this.dispatchUpdate();
  }
  dispatchUpdate() {
    const updateEvent = new CustomEvent("update", {
      detail: this.getCurrentClipBounds()
    });
    this.dispatchEvent(updateEvent);
  }
  getCurrentClipBounds() {
    const rangeRect = this.wrapper.getBoundingClientRect();
    const leftTrimRect = this.leftTrim.getBoundingClientRect();
    const selectionRect = this.selection.getBoundingClientRect();
    const percentStart = lockBetweenZeroAndOne(
      leftTrimRect.width / rangeRect.width
    );
    const percentEnd = lockBetweenZeroAndOne(
      (leftTrimRect.width + selectionRect.width) / rangeRect.width
    );
    return {
      startTime: Math.round(percentStart * this.mediaDuration),
      endTime: Math.round(percentEnd * this.mediaDuration)
    };
  }
  isTimestampInBounds(timestamp) {
    const { startTime, endTime } = this.getCurrentClipBounds();
    return startTime <= timestamp && endTime >= timestamp;
  }
  handleClick(evt) {
    const mousePercent = this.getMousePercent(evt);
    const timestampForClick = mousePercent * this.mediaDuration;
    if (this.isTimestampInBounds(timestampForClick)) {
      this.dispatchEvent(
        new import_server_safe_globals.globalThis.CustomEvent(import_constants.MediaUIEvents.MEDIA_SEEK_REQUEST, {
          composed: true,
          bubbles: true,
          detail: timestampForClick
        })
      );
    }
  }
  mediaCurrentTimeSet() {
    const percentComplete = lockBetweenZeroAndOne(
      this.mediaCurrentTime / this.mediaDuration
    );
    this.playhead.style.left = `${percentComplete * 100}%`;
    this.playhead.style.display = "block";
    if (!this.mediaPaused) {
      const { startTime, endTime } = this.getCurrentClipBounds();
      if (this.mediaCurrentTime < startTime || this.mediaCurrentTime > endTime) {
        this.dispatchEvent(
          new import_server_safe_globals.globalThis.CustomEvent(import_constants.MediaUIEvents.MEDIA_SEEK_REQUEST, {
            composed: true,
            bubbles: true,
            detail: startTime
          })
        );
      }
    }
  }
  mediaUnsetCallback(media) {
    var _a, _b;
    super.mediaUnsetCallback(media);
    this.wrapper.removeEventListener("touchstart", this._dragStart);
    this.wrapper.removeEventListener("touchend", this._dragEnd);
    this.wrapper.removeEventListener("touchmove", this._drag);
    this.wrapper.removeEventListener("mousedown", this._dragStart);
    (_a = import_server_safe_globals.globalThis.window) == null ? void 0 : _a.removeEventListener("mouseup", this._dragEnd);
    (_b = import_server_safe_globals.globalThis.window) == null ? void 0 : _b.removeEventListener("mousemove", this._drag);
  }
  /*
   * This was copied over from media-time-range, we should have a way of making
   * this code shared between the two components
   */
  enableThumbnails() {
    this.thumbnailPreview = this.shadowRoot.querySelector(
      "media-preview-thumbnail"
    );
    const thumbnailContainer = this.shadowRoot.querySelector(
      "#thumbnailContainer"
    );
    thumbnailContainer.classList.add("enabled");
    let mouseMoveHandler;
    const trackMouse = () => {
      var _a;
      mouseMoveHandler = (evt) => {
        const duration = this.mediaDuration;
        if (!duration)
          return;
        const rangeRect = this.wrapper.getBoundingClientRect();
        const mousePercent = this.getMousePercent(evt);
        const leftPadding = rangeRect.left - this.getBoundingClientRect().left;
        const thumbnailLeft = leftPadding + mousePercent * rangeRect.width;
        this.thumbnailPreview.style.left = `${thumbnailLeft}px`;
        this.dispatchEvent(
          new import_server_safe_globals.globalThis.CustomEvent(import_constants.MediaUIEvents.MEDIA_PREVIEW_REQUEST, {
            composed: true,
            bubbles: true,
            detail: mousePercent * duration
          })
        );
      };
      (_a = import_server_safe_globals.globalThis.window) == null ? void 0 : _a.addEventListener("mousemove", mouseMoveHandler, false);
    };
    const stopTrackingMouse = () => {
      var _a;
      (_a = import_server_safe_globals.globalThis.window) == null ? void 0 : _a.removeEventListener("mousemove", mouseMoveHandler);
    };
    let rangeEntered = false;
    const rangeMouseMoveHander = () => {
      var _a;
      if (!rangeEntered && this.mediaDuration) {
        rangeEntered = true;
        this.thumbnailPreview.style.display = "block";
        trackMouse();
        const offRangeHandler = (evt) => {
          var _a2;
          if (evt.target != this && !this.contains(evt.target)) {
            this.thumbnailPreview.style.display = "none";
            (_a2 = import_server_safe_globals.globalThis.window) == null ? void 0 : _a2.removeEventListener(
              "mousemove",
              offRangeHandler
            );
            rangeEntered = false;
            stopTrackingMouse();
          }
        };
        (_a = import_server_safe_globals.globalThis.window) == null ? void 0 : _a.addEventListener(
          "mousemove",
          offRangeHandler,
          false
        );
      }
      if (!this.mediaDuration) {
        this.thumbnailPreview.style.display = "none";
      }
    };
    this.addEventListener("mousemove", rangeMouseMoveHander, false);
  }
  disableThumbnails() {
    const thumbnailContainer = this.shadowRoot.querySelector(
      "#thumbnailContainer"
    );
    thumbnailContainer.classList.remove("enabled");
  }
}
if (!import_server_safe_globals.globalThis.customElements.get("media-clip-selector")) {
  import_server_safe_globals.globalThis.customElements.define("media-clip-selector", MediaClipSelector);
}
var media_clip_selector_default = MediaClipSelector;
