import { unsafeCSS, LitElement, html } from "lit";
import { property } from "lit/decorators.js";
import { InstrumentState, Priority } from "../types.js";
import { SetpointBundle } from "../../svghelpers/setpoint-bundle.js";
import { thruster } from "../thruster/thruster.js";
import "../watch/watch.js";
import componentStyle from "./azimuth-thruster.css.js";
import { ifDefined } from "lit/directives/if-defined.js";
import { AdviceState } from "../watch/advice.js";
import { TickmarkStyle, TickmarkType } from "../watch/tickmark.js";
import { PropellerType } from "../thruster/propeller.js";
import { customElement } from "../../decorator.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;
};
function mapAngle0to360(angle) {
  const a = angle % 360;
  if (a >= 0) {
    return a;
  } else {
    return a + 360;
  }
}
let ObcAzimuthThruster = class extends LitElement {
  constructor() {
    super(...arguments);
    this._thrustSetpointId = `azimuth-thrust-sp-${Math.random().toString(36).slice(2, 9)}`;
    this.angle = 0;
    this.atAngleSetpoint = false;
    this.angleSetpointAtZeroDeadband = 0.5;
    this.angleSetpointOverride = false;
    this.touching = false;
    this.autoAtAngleSetpoint = true;
    this.autoAtAngleSetpointDeadband = 2;
    this.animateSetpoint = false;
    this.primaryTickmarkInterval = 90;
    this.secondaryTickmarkInterval = void 0;
    this.tertiaryTickmarkInterval = void 0;
    this.showLabels = false;
    this.tickmarksInside = false;
    this.thrust = 0;
    this.atThrustSetpoint = false;
    this.thrustSetpointAtZeroDeadband = 0.1;
    this.thrustSetpointOverride = false;
    this.autoAtThrustSetpoint = true;
    this.autoAtThrustSetpointDeadband = 1;
    this.state = InstrumentState.active;
    this.priority = Priority.regular;
    this._angleSp = new SetpointBundle({
      angularWraparound: true,
      onAnimationEnd: () => this.requestUpdate()
    });
    this._thrustSp = new SetpointBundle({
      defaultDeadband: 1,
      defaultZeroDeadband: 0.1,
      onAnimationEnd: () => this.requestUpdate()
    });
    this.loading = 0;
    this.hasLabelSpacer = true;
    this.angleAdvices = [];
    this.thrustAdvices = [];
    this.singleDirection = false;
    this.topPropeller = PropellerType.none;
    this.bottomPropeller = PropellerType.none;
    this.tickmarkStyle = TickmarkStyle.regular;
    this.starboardPortIndicator = false;
  }
  willUpdate(changed) {
    super.willUpdate(changed);
    this._angleSp.sync({
      setpoint: this.angleSetpoint,
      newSetpoint: this.newAngleSetpoint,
      atSetpoint: this.atAngleSetpoint,
      touching: this.touching,
      autoAtSetpoint: this.autoAtAngleSetpoint,
      autoAtSetpointDeadband: this.autoAtAngleSetpointDeadband,
      setpointAtZeroDeadband: this.angleSetpointAtZeroDeadband,
      setpointOverride: this.angleSetpointOverride,
      animateSetpoint: this.animateSetpoint
    });
    this._thrustSp.sync({
      setpoint: this.thrustSetpoint,
      newSetpoint: this.newThrustSetpoint,
      touching: this.touching,
      atSetpoint: this.atThrustSetpoint,
      autoAtSetpoint: this.autoAtThrustSetpoint,
      autoAtSetpointDeadband: this.autoAtThrustSetpointDeadband,
      setpointAtZeroDeadband: this.thrustSetpointAtZeroDeadband,
      setpointOverride: this.thrustSetpointOverride,
      animateSetpoint: this.animateSetpoint
    });
  }
  get angleAdviceRaw() {
    return this.angleAdvices.map((advice) => {
      const triggered = this.angleSetpoint !== void 0 && mapAngle0to360(this.angleSetpoint - advice.minAngle) < 180 && mapAngle0to360(this.angleSetpoint - advice.maxAngle) > 180;
      let state;
      if (triggered) {
        state = AdviceState.triggered;
      } else if (advice.hinted) {
        state = AdviceState.hinted;
      } else {
        state = AdviceState.regular;
      }
      return {
        minAngle: advice.minAngle,
        maxAngle: advice.maxAngle,
        type: advice.type,
        state
      };
    });
  }
  getTickmarks() {
    const tickmarks = [];
    const skipAngles = [];
    const labelText = (angle) => {
      if (!this.showLabels) return void 0;
      return angle <= 180 ? `${angle}` : `${angle - 360}`;
    };
    tickmarks.push({
      angle: 0,
      type: TickmarkType.zeroLine,
      text: this.showLabels ? "0" : void 0
    });
    skipAngles.push(0);
    const primaryInterval = this.primaryTickmarkInterval;
    if (primaryInterval !== void 0 && primaryInterval > 0 && Number.isFinite(primaryInterval)) {
      for (let i = primaryInterval; i < 360; i += primaryInterval) {
        if (skipAngles.includes(i)) continue;
        tickmarks.push({
          angle: i,
          type: TickmarkType.primary,
          text: labelText(i)
        });
        skipAngles.push(i);
      }
    }
    const secondaryInterval = this.secondaryTickmarkInterval;
    if (secondaryInterval !== void 0 && secondaryInterval > 0 && Number.isFinite(secondaryInterval)) {
      for (let i = 0; i < 360; i += secondaryInterval) {
        if (skipAngles.includes(i)) continue;
        tickmarks.push({
          angle: i,
          type: TickmarkType.secondary
        });
        skipAngles.push(i);
      }
    }
    const tertiaryInterval = this.tertiaryTickmarkInterval;
    if (tertiaryInterval !== void 0 && tertiaryInterval > 0 && Number.isFinite(tertiaryInterval)) {
      for (let i = 0; i < 360; i += tertiaryInterval) {
        if (skipAngles.includes(i)) continue;
        tickmarks.push({
          angle: i,
          type: TickmarkType.tertiary
        });
        skipAngles.push(i);
      }
    }
    return tickmarks;
  }
  render() {
    const rotateAngle = this.angle;
    const tickmarks = this.getTickmarks();
    let viewBox;
    if (!this.hasLabelSpacer) {
      viewBox = "-192 -192 384 384";
    } else if (this.showLabels && !this.tickmarksInside) {
      viewBox = "-236 -236 472 472";
    } else {
      viewBox = "-200 -200 400 400";
    }
    return html`
      <div class="container">
        <obc-watch
          .touching=${this.touching}
          .tickmarks=${tickmarks}
          .state=${this.state}
          .priority=${this.priority}
          .angleSetpoint=${this.angleSetpoint}
          .newAngleSetpoint=${this.newAngleSetpoint}
          .atAngleSetpoint=${this._angleSp.computeAtSetpoint(this.angle)}
          .angleSetpointAtZeroDeadband=${this.angleSetpointAtZeroDeadband}
          .setpointOverride=${this.angleSetpointOverride}
          .animateSetpoint=${this.animateSetpoint}
          .tickmarksInside=${this.tickmarksInside}
          .tickmarkStyle=${this.tickmarkStyle}
          padding=${ifDefined(!this.hasLabelSpacer ? 16 : void 0)}
          .advices=${this.angleAdviceRaw}
          .starboardPortIndicator=${this.starboardPortIndicator}
        ></obc-watch>
        <svg viewBox=${viewBox} xmlns="http://www.w3.org/2000/svg">
          <g transform="rotate(${rotateAngle})">
            ${thruster(
      this.thrust,
      this.thrustSetpoint,
      this.state,
      this.priority,
      {
        atSetpoint: this.atThrustSetpoint,
        singleSided: true,
        singleDirection: false,
        singleDirectionHalfSize: this.singleDirection,
        tunnel: false,
        autoAtSetpoint: this.autoAtThrustSetpoint,
        autoAtSetpointDeadband: this.autoAtThrustSetpointDeadband,
        setpointAtZeroDeadband: this.thrustSetpointAtZeroDeadband,
        touching: this.touching,
        advices: this.thrustAdvices,
        topPropeller: this.topPropeller,
        bottomPropeller: this.bottomPropeller,
        narrow: true,
        newSetpoint: this.newThrustSetpoint,
        setpointId: this._thrustSetpointId,
        animateSetpoint: this.animateSetpoint,
        departingNewSetpoint: this._thrustSp.departingNewSetpoint,
        setpointOverride: this.thrustSetpointOverride
      }
    )}
          </g>
        </svg>
      </div>
    `;
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this._angleSp.dispose();
    this._thrustSp.dispose();
  }
};
ObcAzimuthThruster.styles = unsafeCSS(componentStyle);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "angle", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "angleSetpoint", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "newAngleSetpoint", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "atAngleSetpoint", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "angleSetpointAtZeroDeadband", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "angleSetpointOverride", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "touching", 2);
__decorateClass([
  property({ type: Boolean, attribute: false })
], ObcAzimuthThruster.prototype, "autoAtAngleSetpoint", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "autoAtAngleSetpointDeadband", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "animateSetpoint", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "primaryTickmarkInterval", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "secondaryTickmarkInterval", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "tertiaryTickmarkInterval", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "showLabels", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "tickmarksInside", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "thrust", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "thrustSetpoint", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "newThrustSetpoint", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "atThrustSetpoint", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "thrustSetpointAtZeroDeadband", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "thrustSetpointOverride", 2);
__decorateClass([
  property({ type: Boolean, attribute: false })
], ObcAzimuthThruster.prototype, "autoAtThrustSetpoint", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "autoAtThrustSetpointDeadband", 2);
__decorateClass([
  property({ type: String })
], ObcAzimuthThruster.prototype, "state", 2);
__decorateClass([
  property({ type: String })
], ObcAzimuthThruster.prototype, "priority", 2);
__decorateClass([
  property({ type: Number })
], ObcAzimuthThruster.prototype, "loading", 2);
__decorateClass([
  property({ type: Boolean, attribute: false })
], ObcAzimuthThruster.prototype, "hasLabelSpacer", 2);
__decorateClass([
  property({ type: Array, attribute: false })
], ObcAzimuthThruster.prototype, "angleAdvices", 2);
__decorateClass([
  property({ type: Array, attribute: false })
], ObcAzimuthThruster.prototype, "thrustAdvices", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "singleDirection", 2);
__decorateClass([
  property({ type: String })
], ObcAzimuthThruster.prototype, "topPropeller", 2);
__decorateClass([
  property({ type: String })
], ObcAzimuthThruster.prototype, "bottomPropeller", 2);
__decorateClass([
  property({ type: String })
], ObcAzimuthThruster.prototype, "tickmarkStyle", 2);
__decorateClass([
  property({ type: Boolean })
], ObcAzimuthThruster.prototype, "starboardPortIndicator", 2);
ObcAzimuthThruster = __decorateClass([
  customElement("obc-azimuth-thruster")
], ObcAzimuthThruster);
export {
  ObcAzimuthThruster
};
//# sourceMappingURL=azimuth-thruster.js.map
