import { DanceRole } from "../danceCommon.js"; import { HandTo, SemanticPosition, DancerDistance, HandConnection, PositionKind } from "../interpreterCommon.js"; import { Move } from "../libfigureMapper.js"; import { SemanticAnimationKind } from "../lowLevelMove.js"; import { Hand } from "../rendererConstants.js"; import { ISingleVariantMoveInterpreter, LowLevelMovesForAllDancers, MoveInterpreter, PartialLowLevelMove, SemanticPositionsForAllDancers, SingleVariantMoveInterpreter, moveInterpreters } from "./_moveInterpreter.js"; const moveName: Move["move"] = "promenade"; class PromenadeSingleVariant extends SingleVariantMoveInterpreter { moveAsLowLevelMoves(): LowLevelMovesForAllDancers { if (this.move.parameters.dir !== "across") { // TODO "along" would be the bicycle chain? Not sure what left/right diagonal means here. throw "Promenade not across the set is unsupported." } // TODO How to know? const twirlAfterPromenade = true; const twirlBeats = twirlAfterPromenade ? this.move.beats / 2 : 0; const promenadeBeats = this.move.beats - twirlBeats; return this.handleCirclePairedMove(this.move.parameters.who, ({ startPos }) => { const handTo = startPos.which.isOnLeftLookingAcross() ? HandTo.DancerRight : HandTo.DancerLeft; const startingPos: SemanticPosition = { ...startPos, facing: startPos.which.facingAcross(), dancerDistance: DancerDistance.Compact, hands: new Map([ [Hand.Left, { hand: Hand.Left, to: handTo }], [Hand.Right, { hand: Hand.Right, to: handTo }], ]), }; const endSetOffset = this.move.progression ? (startPos.setOffset ?? 0) + (startPos.which.isLeft() ? +0.5 : -0.5) : startPos.setOffset; const beforeTwirlPos: SemanticPosition & { kind: PositionKind.Circle } = { ...startingPos, which: startPos.which.swapAcross(), facing: startPos.which.facingAcross(), setOffset: endSetOffset, }; const endPos: SemanticPosition = { ...beforeTwirlPos, which: beforeTwirlPos.which.swapUpAndDown(), facing: beforeTwirlPos.which.facingAcross(), dancerDistance: undefined, }; const maybeTwirl: [] | [PartialLowLevelMove] = (twirlAfterPromenade ? [{ beats: twirlBeats, endPosition: endPos, movementPattern: { kind: SemanticAnimationKind.CourtesyTurn, clockwise: this.move.parameters.turn, // TODO or ! this? } }] : []) return this.combine([{ beats: promenadeBeats, endPosition: beforeTwirlPos, movementPattern: { kind: SemanticAnimationKind.Promenade, swingRole: startPos.which.isOnLeftLookingAcross() ? DanceRole.Lark : DanceRole.Robin, twirl: true, passBy: this.move.parameters.turn ? Hand.Left : Hand.Right, } }, ...maybeTwirl], startingPos); }); } } class Promenade extends MoveInterpreter { buildSingleVariantMoveInterpreter(startingPos: SemanticPositionsForAllDancers): ISingleVariantMoveInterpreter { return new PromenadeSingleVariant(this, startingPos); } } moveInterpreters.set(moveName, Promenade);