import { html, LitElement } from "lit";
import { property, state } from "lit/decorators.js";
import { customElement } from "../../decorator.js";
import { ResizeController } from "@lit-labs/observers/resize-controller.js";
import { CHART_DIMENSIONS } from "../../charthelpers/constants.js";
import { FrameStyle, Priority, InstrumentState } from "../../navigation-instruments/types.js";
import { BorderRadiusPosition } from "../../navigation-instruments/types.js";
import { ExternalScaleSide, computeFixedAspectRatioScale, ExternalScaleOrientation, ScaleType, FillMode, AdvicePosition, computeExternalScaleLayout, toExternalScaleLayoutConfig, renderExternalScale, computeExternalScaleEffectiveBarThickness, computeScaleDimensionsForReport, startExternalScaleBorderRadiusObserver, readExternalScaleBorderRadiusPx, computeExternalScaleViewBox } from "../external-scale/external-scale.js";
import { BarContainerStyle } from "../external-scale/external-scale.js";
import { SetpointMixin } from "../../svghelpers/setpoint-mixin.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;
};
let ObcBarHorizontal = class extends SetpointMixin(LitElement, {
  defaultDeadband: 1
}) {
  constructor() {
    super(...arguments);
    this.minValue = 0;
    this.maxValue = 100;
    this.width = 320;
    this.paddingLeft = CHART_DIMENSIONS.CANVAS_PADDING;
    this.paddingRight = CHART_DIMENSIONS.CANVAS_PADDING;
    this.side = ExternalScaleSide.bottom;
    this.fixedAspectRatio = false;
    this.scaleReferenceSize = 384;
    this._scale = 1;
    this._resizeController = new ResizeController(this, {
      callback: (entries) => {
        if (!this.fixedAspectRatio) return;
        const entry = entries[0];
        if (!entry) return;
        const containerMainAxisSize = entry.contentRect.width;
        this._scale = computeFixedAspectRatioScale({
          orientation: ExternalScaleOrientation.horizontal,
          containerMainAxisSize,
          scaleReferenceSize: this.scaleReferenceSize
        });
        this.reportDimensions();
      }
    });
    this.hasScale = true;
    this.showLabels = true;
    this.hasBar = false;
    this.scaleBackground = false;
    this.barContainerStyle = void 0;
    this.barThickness = 24;
    this.tickThickness = 24;
    this.labelThickness = 60;
    this.mainTickmarks = [];
    this.primaryTickmarkInterval = void 0;
    this.secondaryTickmarkInterval = void 0;
    this.tertiaryTickmarkInterval = void 0;
    this.scaleType = ScaleType.regular;
    this.frameStyle = FrameStyle.regular;
    this.borderRadiusPosition = void 0;
    this.instrumentMode = false;
    this.borderRadius = void 0;
    this._borderRadiusResizeController = new ResizeController(this, {
      callback: () => {
        if (!this.instrumentMode) {
          this._refreshBorderRadiusFromCssVar();
        }
      }
    });
    this.priority = Priority.regular;
    this.fillMode = FillMode.fill;
    this.fillMin = void 0;
    this.fillMax = void 0;
    this.value = void 0;
    this.state = InstrumentState.active;
    this.advicePosition = AdvicePosition.inner;
    this.advices = [];
    this.highlightCurrentValue = false;
  }
  render() {
    const effectiveLength = this.fixedAspectRatio ? this.scaleReferenceSize : this.width;
    const config = {
      orientation: ExternalScaleOrientation.horizontal,
      side: this.side,
      length: effectiveLength,
      paddingStart: this.paddingLeft,
      paddingEnd: this.paddingRight,
      minValue: this.minValue,
      maxValue: this.maxValue,
      hasScale: this.hasScale,
      labels: this.showLabels,
      hasBar: this.hasBar,
      scaleBackground: this.scaleBackground,
      barContainerStyle: this.barContainerStyle,
      barThickness: this.barThickness,
      tickThickness: this.tickThickness,
      labelThickness: this.labelThickness,
      borderRadius: this._getEffectiveBorderRadius(),
      mainTickmarks: this.mainTickmarks,
      primaryTickmarkInterval: this.primaryTickmarkInterval,
      secondaryTickmarkInterval: this.secondaryTickmarkInterval,
      tertiaryTickmarkInterval: this.tertiaryTickmarkInterval,
      scaleType: this.scaleType,
      frameStyle: this.frameStyle,
      borderRadiusPosition: this.borderRadiusPosition,
      priority: this.priority,
      setpointOverride: this.setpointOverride,
      fillMode: this.fillMode,
      fillMin: this.fillMin,
      fillMax: this.fillMax,
      value: this.value,
      setpoint: this.setpoint,
      newSetpoint: this.newSetpoint,
      atSetpoint: this.atSetpoint,
      autoAtSetpoint: this.autoAtSetpoint,
      autoAtSetpointDeadband: this.autoAtSetpointDeadband,
      setpointAtZeroDeadband: this.setpointAtZeroDeadband,
      animateSetpoint: this.animateSetpoint,
      departingNewSetpoint: this.departingNewSetpoint,
      state: this.state,
      touching: this.touching,
      advicePosition: this.advicePosition,
      advices: this.advices,
      fixedAspectRatio: this.fixedAspectRatio,
      instrumentMode: this.instrumentMode,
      highlightCurrentValue: this.highlightCurrentValue
    };
    const layout = computeExternalScaleLayout(
      toExternalScaleLayoutConfig(config)
    );
    const parts = renderExternalScale(config);
    const viewBox = computeExternalScaleViewBox(
      { orientation: config.orientation, length: effectiveLength },
      layout
    );
    const preserveAspectRatio = this.fixedAspectRatio ? "xMidYMid meet" : "none";
    return html`
      <svg
        width=${this.fixedAspectRatio ? "100%" : `${this.width}px`}
        height=${this.fixedAspectRatio ? "100%" : `${viewBox.height}px`}
        viewBox="${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}"
        preserveAspectRatio="${preserveAspectRatio}"
        style="--scale: ${this.fixedAspectRatio ? this._scale : 1};"
        part="svg"
      >
        ${parts.barContainer} ${parts.barFill} ${parts.scaleBackground}
        ${parts.tickmarks} ${parts.labels} ${parts.adviceOverlays}
        ${parts.currentValueDot} ${parts.setpoint}
      </svg>
    `;
  }
  updated(changed) {
    super.updated(changed);
    if (changed.has("scaleType")) {
      this._refreshBorderRadiusFromCssVar();
    }
    if (changed.has("fixedAspectRatio")) {
      if (this.fixedAspectRatio) {
        this._applyFixedAspectRatioStyles();
        this._updateScaleFromCurrentSize();
      } else {
        this._removeFixedAspectRatioStyles();
        this._scale = 1;
      }
    }
    if (changed.has("scaleReferenceSize") && this.fixedAspectRatio) {
      this._updateScaleFromCurrentSize();
    }
    const layoutChanged = changed.has("side") || changed.has("showLabels") || changed.has("hasScale") || changed.has("hasBar") || changed.has("barThickness") || changed.has("tickThickness") || changed.has("labelThickness") || changed.has("scaleType") || changed.has("borderRadiusPosition") || changed.has("borderRadius");
    if (!this.fixedAspectRatio || layoutChanged) {
      this.reportDimensions();
    }
  }
  /**
   * Report scale dimensions to parent chart component.
   * When fixedAspectRatio=true, reports the actual visual (scaled) thickness
   * so the chart can correctly reserve space for the scale.
   * When fixedAspectRatio=false, reports the base/unscaled thickness.
   */
  reportDimensions() {
    const effectiveBarThickness = computeExternalScaleEffectiveBarThickness({
      hasBar: this.hasBar,
      barThickness: this.barThickness,
      borderRadius: this._getEffectiveBorderRadius(),
      scaleType: this.scaleType
    });
    const effectiveLength = this.fixedAspectRatio ? this.scaleReferenceSize : this.width;
    const baseDimensions = computeScaleDimensionsForReport({
      orientation: ExternalScaleOrientation.horizontal,
      side: this.side,
      hasBar: this.hasBar,
      hasScale: this.hasScale,
      labels: this.showLabels,
      barThickness: effectiveBarThickness,
      tickThickness: this.tickThickness,
      labelThickness: this.labelThickness,
      length: effectiveLength,
      scaleType: this.scaleType
    });
    const dimensions = this.fixedAspectRatio ? {
      ...baseDimensions,
      thickness: Math.round(baseDimensions.thickness * this._scale)
    } : baseDimensions;
    this.dispatchEvent(
      new CustomEvent("scale-dimensions-changed", {
        detail: dimensions,
        bubbles: true,
        composed: true
      })
    );
  }
  createRenderRoot() {
    return this;
  }
  connectedCallback() {
    super.connectedCallback();
    if (!this.instrumentMode) {
      this._refreshBorderRadiusFromCssVar();
      this._startBorderRadiusObserver();
    }
    if (this.fixedAspectRatio) {
      this._applyFixedAspectRatioStyles();
    }
  }
  disconnectedCallback() {
    this._borderRadiusObserver?.disconnect();
    this._borderRadiusObserver = void 0;
    super.disconnectedCallback();
  }
  _startBorderRadiusObserver() {
    this._borderRadiusObserver?.disconnect();
    this._borderRadiusObserver = startExternalScaleBorderRadiusObserver(
      this,
      () => this._refreshBorderRadiusFromCssVar()
    );
  }
  /**
   * Apply CSS styles needed for fixedAspectRatio mode.
   * Custom elements are display:inline by default, which doesn't work with percentage-based sizing.
   * We need display:block and width:100% to fill the slot container.
   */
  _applyFixedAspectRatioStyles() {
    this.style.display = "block";
    this.style.width = "100%";
    this.style.height = "auto";
  }
  /**
   * Remove fixed aspect ratio styles when switching back to pixel mode.
   */
  _removeFixedAspectRatioStyles() {
    this.style.display = "";
    this.style.width = "";
    this.style.height = "";
  }
  /**
   * Calculate scale based on current element size.
   * Called when fixedAspectRatio is enabled or scaleReferenceSize changes.
   */
  _updateScaleFromCurrentSize() {
    requestAnimationFrame(() => {
      const containerWidth = this.clientWidth;
      if (containerWidth > 0) {
        this._scale = computeFixedAspectRatioScale({
          orientation: ExternalScaleOrientation.horizontal,
          containerMainAxisSize: containerWidth,
          scaleReferenceSize: this.scaleReferenceSize
        });
        this.requestUpdate();
        this.reportDimensions();
      }
    });
  }
  _refreshBorderRadiusFromCssVar() {
    if (this.instrumentMode) return;
    const next = readExternalScaleBorderRadiusPx(this, this.scaleType);
    if (this._computedBorderRadius !== next) {
      this._computedBorderRadius = next;
    }
    if (this.fixedAspectRatio) {
      const rect = this.getBoundingClientRect();
      if (rect.width > 0) {
        this._scale = computeFixedAspectRatioScale({
          orientation: ExternalScaleOrientation.horizontal,
          containerMainAxisSize: rect.width,
          scaleReferenceSize: this.scaleReferenceSize
        });
        this.reportDimensions();
      }
    }
  }
  /**
   * Get the effective border radius to use.
   * In instrument mode: use explicit borderRadius prop or default based on scaleType.
   * In normal mode: use CSS variable computed value.
   */
  _getEffectiveBorderRadius() {
    if (this.instrumentMode) {
      if (this.borderRadius !== void 0) {
        return this.borderRadius;
      }
      return this.scaleType === ScaleType.condensed ? 4 : 8;
    }
    return this._computedBorderRadius ?? (this.scaleType === ScaleType.condensed ? 4 : 8);
  }
};
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "minValue", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "maxValue", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "width", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "paddingLeft", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "paddingRight", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "side", 2);
__decorateClass([
  property({ type: Boolean })
], ObcBarHorizontal.prototype, "fixedAspectRatio", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "scaleReferenceSize", 2);
__decorateClass([
  state()
], ObcBarHorizontal.prototype, "_scale", 2);
__decorateClass([
  property({ type: Boolean, attribute: false })
], ObcBarHorizontal.prototype, "hasScale", 2);
__decorateClass([
  property({ type: Boolean, attribute: false })
], ObcBarHorizontal.prototype, "showLabels", 2);
__decorateClass([
  property({ type: Boolean })
], ObcBarHorizontal.prototype, "hasBar", 2);
__decorateClass([
  property({ type: Boolean })
], ObcBarHorizontal.prototype, "scaleBackground", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "barContainerStyle", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "barThickness", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "tickThickness", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "labelThickness", 2);
__decorateClass([
  property({ attribute: false })
], ObcBarHorizontal.prototype, "mainTickmarks", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "primaryTickmarkInterval", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "secondaryTickmarkInterval", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "tertiaryTickmarkInterval", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "scaleType", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "frameStyle", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "borderRadiusPosition", 2);
__decorateClass([
  property({ type: Boolean })
], ObcBarHorizontal.prototype, "instrumentMode", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "borderRadius", 2);
__decorateClass([
  state()
], ObcBarHorizontal.prototype, "_computedBorderRadius", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "priority", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "fillMode", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "fillMin", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "fillMax", 2);
__decorateClass([
  property({ type: Number })
], ObcBarHorizontal.prototype, "value", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "state", 2);
__decorateClass([
  property({ type: String })
], ObcBarHorizontal.prototype, "advicePosition", 2);
__decorateClass([
  property({ attribute: false })
], ObcBarHorizontal.prototype, "advices", 2);
__decorateClass([
  property({ type: Boolean })
], ObcBarHorizontal.prototype, "highlightCurrentValue", 2);
ObcBarHorizontal = __decorateClass([
  customElement("obc-bar-horizontal")
], ObcBarHorizontal);
export {
  AdvicePosition,
  BarContainerStyle,
  BorderRadiusPosition,
  ExternalScaleSide,
  FillMode,
  FrameStyle,
  InstrumentState,
  ObcBarHorizontal,
  Priority,
  ScaleType
};
//# sourceMappingURL=bar-horizontal.js.map
