import { LitElement, html, nothing, svg, css } from "lit";
import { property } from "lit/decorators.js";
import { customElement } from "../../decorator.js";
import { AdviceState } from "../../navigation-instruments/watch/advice.js";
import { WatchCircleType, innerRingRadiusFor, OUTER_RING_RADIUS } from "../../navigation-instruments/watch/watch.js";
import { TickmarkStyle, TickmarkType } from "../../navigation-instruments/watch/tickmark.js";
import { InstrumentState, Priority } from "../../navigation-instruments/types.js";
import { SetpointMixin } from "../../svghelpers/setpoint-mixin.js";
import { computeZoomToFitArcFrame } from "../../svghelpers/arc-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 ObcGaugeRadialType = /* @__PURE__ */ ((ObcGaugeRadialType2) => {
  ObcGaugeRadialType2["filled"] = "filled";
  ObcGaugeRadialType2["bar"] = "bar";
  ObcGaugeRadialType2["needle"] = "needle";
  return ObcGaugeRadialType2;
})(ObcGaugeRadialType || {});
let ObcInstrumentRadial = class extends SetpointMixin(LitElement) {
  constructor() {
    super(...arguments);
    this.state = InstrumentState.active;
    this.priority = Priority.regular;
    this.value = 0;
    this.maxValue = 100;
    this.minValue = 0;
    this.showLabels = false;
    this.primaryTickmarkInterval = 50;
    this.secondaryTickmarkInterval = 10;
    this.tertiaryTickmarkInterval = void 0;
    this.type = "filled";
    this.needleType = "filled";
    this.tickmarksInside = false;
    this.tickmarkStyle = TickmarkStyle.regular;
    this.advices = [];
    this.clipTop = 0;
    this.clipBottom = 0;
    this.zoomToFitArc = false;
    this._radiusOffset = 0;
  }
  get minAngle() {
    return this.getAngle(this.minValue);
  }
  get maxAngle() {
    return this.getAngle(this.maxValue);
  }
  get _derivedNeedleColor() {
    if (this.state === InstrumentState.loading || this.state === InstrumentState.off) {
      return "transparent";
    }
    return this.priority === Priority.enhanced ? "var(--instrument-enhanced-secondary-color)" : "var(--instrument-regular-secondary-color)";
  }
  get _derivedBarColor() {
    if (this.state === InstrumentState.loading || this.state === InstrumentState.off) {
      return "transparent";
    }
    if (this.type === "filled") {
      return this.priority === Priority.enhanced ? "var(--instrument-enhanced-secondary-color)" : "var(--instrument-regular-secondary-color)";
    }
    return this.priority === Priority.enhanced ? "var(--instrument-enhanced-tertiary-color)" : "var(--instrument-regular-tertiary-color)";
  }
  render() {
    const barColor = this.barColor ?? this._derivedBarColor;
    const setpointAngle = this.setpoint !== void 0 ? this.getAngle(this.setpoint) : void 0;
    const newSetpointAngle = this.newSetpoint !== void 0 ? this.getAngle(this.newSetpoint) : void 0;
    const barAreas = this.type === "needle" ? [] : [
      {
        startAngle: this.getAngle(0),
        endAngle: this.getAngle(this.value),
        fillColor: barColor
      }
    ];
    const areas = [
      {
        startAngle: this.minAngle,
        endAngle: this.maxAngle,
        roundInsideCut: true,
        roundOutsideCut: true
      }
    ];
    const watchCircleType = this.type === "needle" ? WatchCircleType.single : WatchCircleType.double;
    let viewBox;
    if (this.zoomToFitArc) {
      const ext = 48;
      const targetSize = (176 + ext) * 2;
      const frame = computeZoomToFitArcFrame({
        areas,
        outerRadius: OUTER_RING_RADIUS,
        innerRadius: innerRingRadiusFor(watchCircleType),
        extension: ext,
        targetSize
      });
      viewBox = frame.viewBox;
      this._radiusOffset = frame.radiusOffset;
      this._arcFrame = frame;
    } else {
      this._radiusOffset = 0;
      this._arcFrame = void 0;
      const width = 448;
      const height = width * (1 - this.clipTop / 100 - this.clipBottom / 100);
      const top = -width / 2 + width * this.clipTop / 100;
      viewBox = `${-width / 2} ${top} ${width} ${height}`;
    }
    return html`
      <div class="container">
        <obc-watch
          .state=${this.state}
          .priority=${this.priority}
          .angleSetpoint=${setpointAngle}
          .newAngleSetpoint=${newSetpointAngle}
          .atAngleSetpoint=${this.computeAtSetpoint(this.value)}
          .angleSetpointAtZeroDeadband=${this.setpointAtZeroDeadband}
          .setpointOverride=${this.setpointOverride}
          .animateSetpoint=${this.animateSetpoint}
          .padding=${48}
          .tickmarks=${this.tickmarks}
          .tickmarksInside=${this.tickmarksInside}
          .tickmarkStyle=${this.tickmarkStyle}
          .advices=${this._advices}
          .areas=${areas}
          .watchCircleType=${watchCircleType}
          .barAreas=${barAreas}
          .clipTop=${this.zoomToFitArc ? 0 : this.clipTop}
          .clipBottom=${this.zoomToFitArc ? 0 : this.clipBottom}
          .zoomToFitArc=${this.zoomToFitArc}
          .arcFrame=${this._arcFrame}
        ></obc-watch>
        <svg class="gauge-radial" viewBox=${viewBox}>${this._needle}</svg>
      </div>
    `;
  }
  get _needle() {
    if (this.type === "filled") {
      return nothing;
    }
    const needleColor = this.needleColor ?? this._derivedNeedleColor;
    const rOff = this._radiusOffset;
    if (this.type === "needle") {
      return svg`<g transform="rotate(${this.getAngle(this.value)}) translate(-256, -256)">
      <circle cx="256" cy="256" r="14" fill=${needleColor}/>
      <rect x="250" y="${96 - rOff}" width="12" height="${192 + rOff}" rx="6" fill=${needleColor}/>
      <rect x="252" y="${98 - rOff}" width="8" height="${188 + rOff}" rx="4" stroke=${needleColor} fill=${needleColor} stroke-width="4"/>
      </g>
`;
    } else {
      return svg`<g transform="rotate(${this.getAngle(this.value)}) translate(-256, -256)">
<rect x="252" y="${96 - rOff}" width="8" height="48" rx="4" fill=${needleColor} stroke="var(--border-silhouette-color)"/>
</g>
      `;
    }
  }
  get tickmarks() {
    const tickmarks = [];
    const primaryInterval = this.primaryTickmarkInterval;
    if (primaryInterval !== void 0 && primaryInterval > 0 && Number.isFinite(primaryInterval)) {
      for (let i = primaryInterval; i < this.maxValue; i += primaryInterval) {
        tickmarks.push({
          angle: this.getAngle(i),
          type: TickmarkType.primary,
          text: this.showLabels ? i.toString() : void 0
        });
      }
      if (this.showLabels && this.maxValue % primaryInterval === 0) {
        tickmarks.push({
          angle: this.getAngle(this.maxValue),
          type: TickmarkType.textOnly,
          text: this.showLabels ? this.maxValue.toString() : void 0
        });
      }
      for (let i = -primaryInterval; i > this.minValue; i -= primaryInterval) {
        tickmarks.push({
          angle: this.getAngle(i),
          type: TickmarkType.primary,
          text: this.showLabels ? i.toString() : void 0
        });
      }
      if (this.showLabels && this.minValue % primaryInterval === 0) {
        tickmarks.push({
          angle: this.getAngle(this.minValue),
          type: TickmarkType.textOnly,
          text: this.showLabels ? this.minValue.toString() : void 0
        });
      }
    }
    const secondaryInterval = this.secondaryTickmarkInterval;
    if (secondaryInterval !== void 0 && secondaryInterval > 0 && Number.isFinite(secondaryInterval)) {
      const existingTickmarks = tickmarks.map((t) => t.angle);
      for (let i = secondaryInterval; i < this.maxValue; i += secondaryInterval) {
        if (existingTickmarks.includes(this.getAngle(i))) {
          continue;
        }
        tickmarks.push({
          angle: this.getAngle(i),
          type: TickmarkType.secondary
        });
      }
      for (let i = -secondaryInterval; i > this.minValue; i -= secondaryInterval) {
        if (existingTickmarks.includes(this.getAngle(i))) {
          continue;
        }
        tickmarks.push({
          angle: this.getAngle(i),
          type: TickmarkType.secondary
        });
      }
    }
    const tertiaryInterval = this.tertiaryTickmarkInterval;
    if (tertiaryInterval !== void 0 && tertiaryInterval > 0 && Number.isFinite(tertiaryInterval)) {
      const existingTickmarks = tickmarks.map((t) => t.angle);
      for (let i = tertiaryInterval; i < this.maxValue; i += tertiaryInterval) {
        if (existingTickmarks.includes(this.getAngle(i))) {
          continue;
        }
        tickmarks.push({
          angle: this.getAngle(i),
          type: TickmarkType.tertiary
        });
      }
      for (let i = -tertiaryInterval; i > this.minValue; i -= tertiaryInterval) {
        if (existingTickmarks.includes(this.getAngle(i))) {
          continue;
        }
        tickmarks.push({
          angle: this.getAngle(i),
          type: TickmarkType.tertiary
        });
      }
    }
    const zeroTickmark = tickmarks.find((t) => t.angle === this.getAngle(0));
    if (zeroTickmark) {
      zeroTickmark.type = this.minValue < 0 ? TickmarkType.main : TickmarkType.textOnly;
    } else {
      tickmarks.push({
        angle: this.getAngle(0),
        type: this.minValue < 0 ? TickmarkType.main : TickmarkType.textOnly,
        text: this.showLabels ? "0" : void 0
      });
    }
    return tickmarks;
  }
  get _advices() {
    return this.advices.map((advice) => {
      const minAngle = this.getAngle(advice.minValue);
      const maxAngle = this.getAngle(advice.maxValue);
      let state = advice.hinted ? AdviceState.hinted : AdviceState.regular;
      if (this.value >= advice.minValue && this.value <= advice.maxValue) {
        state = AdviceState.triggered;
      }
      return {
        minAngle,
        maxAngle,
        type: advice.type,
        state,
        hideMinTickmark: advice.minValue === this.minValue,
        hideMaxTickmark: advice.maxValue === this.maxValue
      };
    });
  }
};
ObcInstrumentRadial.styles = css`
    * {
      box-sizing: border-box;
    }

    .container {
      position: relative;
      width: 100%;
      height: 100%;
    }

    .container > * {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }

    obc-watch {
      anchor-name: --watch;
    }

    .speed-gauge-value {
      position: absolute;
      top: clamp(
        70%,
        calc(80% - (anchor-size(--watch height) - 200px) * 0.2),
        80%
      );
      left: 50%;
      transform: translateX(-50%);
      width: fit-content;
      height: fit-content;
    }
  `;
__decorateClass([
  property({ type: String })
], ObcInstrumentRadial.prototype, "state", 2);
__decorateClass([
  property({ type: String })
], ObcInstrumentRadial.prototype, "priority", 2);
__decorateClass([
  property({ type: Number })
], ObcInstrumentRadial.prototype, "value", 2);
__decorateClass([
  property({ type: Number })
], ObcInstrumentRadial.prototype, "maxValue", 2);
__decorateClass([
  property({ type: Number })
], ObcInstrumentRadial.prototype, "minValue", 2);
__decorateClass([
  property({ attribute: false })
], ObcInstrumentRadial.prototype, "getAngle", 2);
__decorateClass([
  property({ type: String })
], ObcInstrumentRadial.prototype, "needleColor", 2);
__decorateClass([
  property({ type: String })
], ObcInstrumentRadial.prototype, "barColor", 2);
__decorateClass([
  property({ type: Boolean })
], ObcInstrumentRadial.prototype, "showLabels", 2);
__decorateClass([
  property({ type: Number })
], ObcInstrumentRadial.prototype, "primaryTickmarkInterval", 2);
__decorateClass([
  property({ type: Number })
], ObcInstrumentRadial.prototype, "secondaryTickmarkInterval", 2);
__decorateClass([
  property({ type: Number })
], ObcInstrumentRadial.prototype, "tertiaryTickmarkInterval", 2);
__decorateClass([
  property({ type: String })
], ObcInstrumentRadial.prototype, "type", 2);
__decorateClass([
  property({ type: String })
], ObcInstrumentRadial.prototype, "needleType", 2);
__decorateClass([
  property({ type: Boolean })
], ObcInstrumentRadial.prototype, "tickmarksInside", 2);
__decorateClass([
  property({ type: String })
], ObcInstrumentRadial.prototype, "tickmarkStyle", 2);
__decorateClass([
  property({ type: Array, attribute: false })
], ObcInstrumentRadial.prototype, "advices", 2);
__decorateClass([
  property({ type: Number })
], ObcInstrumentRadial.prototype, "clipTop", 2);
__decorateClass([
  property({ type: Number })
], ObcInstrumentRadial.prototype, "clipBottom", 2);
__decorateClass([
  property({ type: Boolean })
], ObcInstrumentRadial.prototype, "zoomToFitArc", 2);
ObcInstrumentRadial = __decorateClass([
  customElement("obc-instrument-radial")
], ObcInstrumentRadial);
export {
  ObcGaugeRadialType,
  ObcInstrumentRadial
};
//# sourceMappingURL=instrument-radial.js.map
