import { unsafeCSS, LitElement, nothing, html } from "lit";
import { property } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import componentStyle from "./poi-pointer.css.js";
import { customElement } from "../../../decorator.js";
import { ObcPoiSelectionFrameType, ObcPoiSelectionFrameState, OBC_POI_SELECTION_FRAME_MIN_CUSTOM_SIZE_PX } from "../poi-selection-frame/poi-selection-frame.js";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result) __defProp(target, key, result);
  return result;
};
var ObcPoiPointerType = /* @__PURE__ */ ((ObcPoiPointerType2) => {
  ObcPoiPointerType2["Point"] = "point";
  ObcPoiPointerType2["Button"] = "button";
  ObcPoiPointerType2["Camera"] = "camera";
  return ObcPoiPointerType2;
})(ObcPoiPointerType || {});
var ObcPoiPointerState = /* @__PURE__ */ ((ObcPoiPointerState2) => {
  ObcPoiPointerState2["Regular"] = "regular";
  ObcPoiPointerState2["Selected"] = "selected";
  ObcPoiPointerState2["Active"] = "active";
  ObcPoiPointerState2["Uncertain"] = "uncertain";
  return ObcPoiPointerState2;
})(ObcPoiPointerState || {});
const CAMERA_SELECTION_FRAME_WIDTH_PX = 64;
const CAMERA_SELECTION_FRAME_HEIGHT_PX = 56;
const CAMERA_SELECTION_FRAME_BOX_WIDTH_PX = CAMERA_SELECTION_FRAME_WIDTH_PX - OBC_POI_SELECTION_FRAME_MIN_CUSTOM_SIZE_PX;
const CAMERA_SELECTION_FRAME_BOX_HEIGHT_PX = CAMERA_SELECTION_FRAME_HEIGHT_PX - OBC_POI_SELECTION_FRAME_MIN_CUSTOM_SIZE_PX;
const BUTTON_SELECTION_FRAME_SIZE_PX = 39;
const BUTTON_SELECTION_FRAME_BOX_OFFSET_PX = BUTTON_SELECTION_FRAME_SIZE_PX - OBC_POI_SELECTION_FRAME_MIN_CUSTOM_SIZE_PX;
const POINT_SIZE_PX = 32;
const POINT_SELECTION_FRAME_BOX_OFFSET_PX = POINT_SIZE_PX - OBC_POI_SELECTION_FRAME_MIN_CUSTOM_SIZE_PX;
const BUTTON_SIZE_PX = 48;
const CAMERA_WIDTH_PX = 52;
const CAMERA_HEIGHT_PX = 44;
const BOX_FILTER_CUTOFF_HZ = 14;
const BOX_FILTER_DEADBAND_PX = 0.25;
let ObcPoiPointer = class extends LitElement {
  constructor() {
    super(...arguments);
    this.type = "point";
    this.state = "regular";
    this.boxWidth = null;
    this.boxHeight = null;
    this.filteredBoxWidth = 0;
    this.filteredBoxHeight = 0;
    this.boxFilterTargetWidth = 0;
    this.boxFilterTargetHeight = 0;
    this.boxFilterInitialized = false;
    this.lastFilterTimestampMs = 0;
    this.boxFilterRaf = 0;
    this.stepBoxFilter = (nowMs) => {
      this.boxFilterRaf = 0;
      if (!this.isConnected || !this.boxFilterInitialized) {
        this.lastFilterTimestampMs = 0;
        return;
      }
      const dtSeconds = this.lastFilterTimestampMs > 0 ? Math.min(
        0.25,
        Math.max(1 / 120, (nowMs - this.lastFilterTimestampMs) / 1e3)
      ) : 1 / 60;
      this.lastFilterTimestampMs = nowMs;
      const alpha = 1 - Math.exp(-2 * Math.PI * BOX_FILTER_CUTOFF_HZ * dtSeconds);
      const prevWidth = this.filteredBoxWidth;
      const prevHeight = this.filteredBoxHeight;
      this.filteredBoxWidth = this.filterBoxValue(
        this.filteredBoxWidth,
        this.boxFilterTargetWidth,
        alpha
      );
      this.filteredBoxHeight = this.filterBoxValue(
        this.filteredBoxHeight,
        this.boxFilterTargetHeight,
        alpha
      );
      const settledWidth = Math.abs(this.boxFilterTargetWidth - this.filteredBoxWidth) <= BOX_FILTER_DEADBAND_PX;
      const settledHeight = Math.abs(this.boxFilterTargetHeight - this.filteredBoxHeight) <= BOX_FILTER_DEADBAND_PX;
      const settled = settledWidth && settledHeight;
      if (settled) {
        this.filteredBoxWidth = this.boxFilterTargetWidth;
        this.filteredBoxHeight = this.boxFilterTargetHeight;
      }
      const changed = Math.abs(this.filteredBoxWidth - prevWidth) > 1e-6 || Math.abs(this.filteredBoxHeight - prevHeight) > 1e-6;
      this.applyPointerSize();
      if (changed || settled) {
        this.requestUpdate();
      }
      if (settled) {
        this.lastFilterTimestampMs = 0;
        return;
      }
      this.boxFilterRaf = requestAnimationFrame(this.stepBoxFilter);
    };
  }
  get shouldUseBoxDimensions() {
    if (this.type === "point") {
      return this.state === "selected";
    }
    if (this.type === "button" || this.type === "camera") {
      return true;
    }
    return false;
  }
  get resolvedBoxWidth() {
    if (!this.shouldUseBoxDimensions || this.boxWidth === null || this.boxWidth < 0) {
      return null;
    }
    return this.boxWidth;
  }
  get resolvedBoxHeight() {
    if (!this.shouldUseBoxDimensions || this.boxHeight === null || this.boxHeight < 0) {
      return null;
    }
    return this.boxHeight;
  }
  get targetBoxWidth() {
    return this.resolvedBoxWidth ?? 0;
  }
  get targetBoxHeight() {
    return this.resolvedBoxHeight ?? 0;
  }
  filterBoxValue(current, target, alpha) {
    const delta = target - current;
    if (Math.abs(delta) <= BOX_FILTER_DEADBAND_PX) {
      return current;
    }
    return current + delta * alpha;
  }
  applyPointerSize() {
    let widthPx = POINT_SIZE_PX;
    let heightPx = POINT_SIZE_PX;
    if (this.type === "button") {
      widthPx = BUTTON_SIZE_PX + this.filteredBoxWidth;
      heightPx = BUTTON_SIZE_PX + this.filteredBoxHeight;
    } else if (this.type === "camera") {
      widthPx = CAMERA_WIDTH_PX + this.filteredBoxWidth;
      heightPx = CAMERA_HEIGHT_PX + this.filteredBoxHeight;
    } else if (this.type === "point" && this.state === "selected") {
      widthPx = POINT_SIZE_PX;
      heightPx = POINT_SIZE_PX;
    }
    this.style.width = `${widthPx}px`;
    this.style.height = `${heightPx}px`;
  }
  syncBoxFilterTargets() {
    this.boxFilterTargetWidth = this.targetBoxWidth;
    this.boxFilterTargetHeight = this.targetBoxHeight;
    if (!this.boxFilterInitialized) {
      this.boxFilterInitialized = true;
      this.filteredBoxWidth = this.boxFilterTargetWidth;
      this.filteredBoxHeight = this.boxFilterTargetHeight;
      this.applyPointerSize();
      this.requestUpdate();
      return;
    }
    const settled = Math.abs(this.boxFilterTargetWidth - this.filteredBoxWidth) <= BOX_FILTER_DEADBAND_PX && Math.abs(this.boxFilterTargetHeight - this.filteredBoxHeight) <= BOX_FILTER_DEADBAND_PX;
    if (settled) {
      const changed = Math.abs(this.boxFilterTargetWidth - this.filteredBoxWidth) > 1e-6 || Math.abs(this.boxFilterTargetHeight - this.filteredBoxHeight) > 1e-6;
      this.filteredBoxWidth = this.boxFilterTargetWidth;
      this.filteredBoxHeight = this.boxFilterTargetHeight;
      this.applyPointerSize();
      if (this.boxFilterRaf) {
        cancelAnimationFrame(this.boxFilterRaf);
        this.boxFilterRaf = 0;
      }
      this.lastFilterTimestampMs = 0;
      if (changed) {
        this.requestUpdate();
      }
      return;
    }
    if (!this.boxFilterRaf) {
      this.lastFilterTimestampMs = 0;
      this.boxFilterRaf = requestAnimationFrame(this.stepBoxFilter);
    }
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    if (this.boxFilterRaf) {
      cancelAnimationFrame(this.boxFilterRaf);
      this.boxFilterRaf = 0;
    }
    this.lastFilterTimestampMs = 0;
  }
  get wrapperStyle() {
    if (this.type === "point" && this.state === "selected") {
      return null;
    }
    const width = this.filteredBoxWidth > 0 ? this.filteredBoxWidth : null;
    const height = this.filteredBoxHeight > 0 ? this.filteredBoxHeight : null;
    const styles = [];
    if (width !== null) {
      styles.push(`--obc-poi-pointer-box-width-extra: ${width}px;`);
    }
    if (height !== null) {
      styles.push(`--obc-poi-pointer-box-height-extra: ${height}px;`);
    }
    if (styles.length === 0) {
      return null;
    }
    return styles.join(" ");
  }
  renderSquareSelectionFrame() {
    if (this.state !== "selected") {
      return nothing;
    }
    if (this.type !== "point" && this.type !== "button") {
      return nothing;
    }
    const isPoint = this.type === "point";
    const isButton = this.type === "button";
    const hasBoxOverrides = this.filteredBoxWidth > 0 || this.filteredBoxHeight > 0;
    const useCustomMode = isPoint || isButton && hasBoxOverrides;
    const frameType = isPoint ? ObcPoiSelectionFrameType.Indicator : ObcPoiSelectionFrameType.Button;
    const customBoxWidth = isPoint ? POINT_SELECTION_FRAME_BOX_OFFSET_PX + this.filteredBoxWidth : BUTTON_SELECTION_FRAME_BOX_OFFSET_PX + this.filteredBoxWidth;
    const customBoxHeight = isPoint ? POINT_SELECTION_FRAME_BOX_OFFSET_PX + this.filteredBoxHeight : BUTTON_SELECTION_FRAME_BOX_OFFSET_PX + this.filteredBoxHeight;
    return html`
      <div class="square-frame" aria-hidden="true">
        <obc-poi-selection-frame
          class="selection-frame"
          .type=${frameType}
          .state=${ObcPoiSelectionFrameState.Regular}
          .customMode=${useCustomMode}
          .boxWidth=${useCustomMode ? customBoxWidth : null}
          .boxHeight=${useCustomMode ? customBoxHeight : null}
        ></obc-poi-selection-frame>
      </div>
    `;
  }
  renderCameraSelectionFrame() {
    if (!(this.type === "camera" && this.state === "selected")) {
      return nothing;
    }
    return html`
      <div class="square-frame camera-selection-frame" aria-hidden="true">
        <obc-poi-selection-frame
          class="selection-frame"
          .type=${ObcPoiSelectionFrameType.Button}
          .state=${ObcPoiSelectionFrameState.Regular}
          .customMode=${true}
          .boxWidth=${CAMERA_SELECTION_FRAME_BOX_WIDTH_PX + this.filteredBoxWidth}
          .boxHeight=${CAMERA_SELECTION_FRAME_BOX_HEIGHT_PX + this.filteredBoxHeight}
        ></obc-poi-selection-frame>
      </div>
    `;
  }
  renderPoint() {
    if (this.type !== "point" || this.state === "selected") {
      return nothing;
    }
    return html`
      <div
        class=${classMap({
      point: true,
      regular: this.state === "regular",
      active: this.state === "active",
      uncertain: this.state === "uncertain"
      /* Uncertain */
    })}
      ></div>
    `;
  }
  renderButton() {
    if (this.type !== "button") {
      return nothing;
    }
    return html`
      <div
        class=${classMap({
      button: true,
      regular: this.state === "regular",
      active: this.state === "active",
      selected: this.state === "selected",
      uncertain: this.state === "uncertain"
      /* Uncertain */
    })}
      ></div>
    `;
  }
  renderCamera() {
    if (this.type !== "camera") {
      return nothing;
    }
    return html`
      <div
        class=${classMap({
      camera: true,
      regular: this.state === "regular",
      active: this.state === "active",
      selected: this.state === "selected",
      uncertain: this.state === "uncertain"
      /* Uncertain */
    })}
      ></div>
    `;
  }
  render() {
    return html`
      <div
        class=${classMap({
      wrapper: true,
      point: this.type === "point",
      button: this.type === "button",
      camera: this.type === "camera"
      /* Camera */
    })}
        style=${this.wrapperStyle ?? nothing}
      >
        ${this.renderSquareSelectionFrame()}
        ${this.renderCameraSelectionFrame()} ${this.renderPoint()}
        ${this.renderButton()} ${this.renderCamera()}
      </div>
    `;
  }
  updated(_changedProperties) {
    this.syncBoxFilterTargets();
  }
};
ObcPoiPointer.styles = unsafeCSS(componentStyle);
__decorateClass([
  property({ type: String, reflect: true })
], ObcPoiPointer.prototype, "type", 2);
__decorateClass([
  property({ type: String, reflect: true })
], ObcPoiPointer.prototype, "state", 2);
__decorateClass([
  property({ type: Number, attribute: "box-width" })
], ObcPoiPointer.prototype, "boxWidth", 2);
__decorateClass([
  property({ type: Number, attribute: "box-height" })
], ObcPoiPointer.prototype, "boxHeight", 2);
ObcPoiPointer = __decorateClass([
  customElement("obc-poi-pointer")
], ObcPoiPointer);
export {
  ObcPoiPointer,
  ObcPoiPointerState,
  ObcPoiPointerType
};
//# sourceMappingURL=poi-pointer.js.map
