import {
LitElement,
SVGTemplateResult,
html,
nothing,
svg,
unsafeCSS,
} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import {circle} from '../../svghelpers';
import {roundedArch} from '../../svghelpers/roundedArch';
import {InstrumentState} from '../types';
import compentStyle from './watch.css?inline';
import {ResizeController} from '@lit-labs/observers/resize-controller.js';
import {AngleAdviceRaw, renderAdvice} from './advice';
import {Tickmark, TickmarkStyle, tickmark} from './tickmark';
import {renderLabels} from './label';
@customElement('obc-watch')
export class ObcWatch extends LitElement {
@property({type: String}) state: InstrumentState = InstrumentState.inCommand;
@property({type: Number}) angleSetpoint: number | undefined;
@property({type: Boolean}) atAngleSetpoint: boolean = false;
@property({type: Number}) padding = 24;
@property({type: Number}) cutAngleStart: number | null = null;
@property({type: Number}) cutAngleEnd: number | null = null;
@property({type: Boolean}) roundOutsideCut = false;
@property({type: Boolean}) roundInsideCut = false;
@property({type: Array, attribute: false}) tickmarks: Tickmark[] = [];
@property({type: Array, attribute: false}) advices: AngleAdviceRaw[] = [];
@property({type: Boolean}) crosshairEnabled: boolean = false;
@property({type: Boolean}) labelFrameEnabled: boolean = false;
// @ts-expect-error TS6133: The controller ensures that the render
// function is called on resize of the element
private _resizeController = new ResizeController(this, {});
private watchCircle(): SVGTemplateResult {
if (this.cutAngleStart === null || this.cutAngleEnd === null) {
return svg`
${
this.state === InstrumentState.off
? null
: svg`
`
}
${circle('innerRing', {
radius: 320 / 2,
strokeWidth: 1,
strokeColor: 'var(--instrument-frame-tertiary-color)',
strokePosition: 'center',
fillColor: 'none',
})}
${
this.state === InstrumentState.off
? null
: circle('outerRing', {
radius: 368 / 2,
strokeWidth: 1,
strokeColor: 'var(--instrument-frame-tertiary-color)',
strokePosition: 'center',
fillColor: 'none',
})
}
`;
} else {
const R = 184;
const r = 160;
const svgPath = roundedArch({
startAngle: this.cutAngleStart,
endAngle: this.cutAngleEnd,
R,
r,
roundOutsideCut: this.roundOutsideCut,
roundInsideCut: this.roundInsideCut,
});
return svg`
`;
}
}
private renderCrosshair(radius: number): SVGTemplateResult {
return svg`
`;
}
override render() {
const width = (176 + this.padding) * 2;
const viewBox = `-${width / 2} -${width / 2} ${width} ${width}`;
const angleSetpoint = this.renderSetpoint();
const scale = Math.min(this.clientWidth, this.clientHeight) / width;
const tickmarks = this.tickmarks.map((t) =>
tickmark(t.angle, t.type, TickmarkStyle.hinted, scale, t.text)
);
const advices = this.advices
? this.advices.map((a) => renderAdvice(a))
: nothing;
const labels = this.labelFrameEnabled ? renderLabels(scale) : nothing;
return html`
`;
}
private renderSetpoint(): SVGTemplateResult | typeof nothing {
let setPointColor = 'var(--instrument-enhanced-primary-color)';
if (this.atAngleSetpoint) {
setPointColor = 'var(--instrument-enhanced-secondary-color)';
}
if (this.state === InstrumentState.active) {
setPointColor = 'var(--instrument-regular-primary-color)';
if (this.atAngleSetpoint) {
setPointColor = 'var(--instrument-regular-secondary-color)';
}
} else if (this.state === InstrumentState.loading) {
setPointColor = 'var(--instrument-frame-tertiary-color)';
} else if (this.state === InstrumentState.off) {
setPointColor = 'var(--instrument-frame-tertiary-color)';
}
if (this.angleSetpoint === undefined) {
return nothing;
} else {
let path;
if (this.state === InstrumentState.inCommand) {
path =
'M23.5119 8C24.6981 6.35191 23.5696 4 21.5926 4L2.39959 4C0.422598 4 -0.705911 6.35191 0.480283 8L11.9961 24L23.5119 8Z';
} else {
path =
'M18.5836 8L5.4086 8L11.9961 17.1526L18.5836 8ZM23.5119 8C24.6981 6.35191 23.5696 4 21.5926 4L2.39959 4C0.422598 4 -0.705911 6.35191 0.480283 8L11.9961 24L23.5119 8Z';
}
return svg`
`;
}
}
static override styles = unsafeCSS(compentStyle);
}
declare global {
interface HTMLElementTagNameMap {
'obc-watch': ObcWatch;
}
}