import { type CameraState } from '../camera/camera' import { type TileStoreStats } from '../tile/tileStore' import { type LonLatPoint, type MapCalibration } from '../../utils/projection' import { type TileZoomBounds } from '../../utils/remoteMapConfig' import { type OrienteeringCourseData } from '../../utils/orienteeringCourse' import { type AnimationLevel } from '../../utils/animationLevel' import { type ControlPointStyleEntry, type CourseLegStyleEntry, type CourseStyleConfig } from '../../game/presentation/courseStyleConfig' import { type GpsMarkerStyleConfig } from '../../game/presentation/gpsMarkerStyleConfig' import { type TrackDisplayMode, type TrackVisualizationConfig } from '../../game/presentation/trackStyleConfig' export interface MapScene { tileSource: string osmTileSource: string zoom: number centerTileX: number centerTileY: number exactCenterWorldX: number exactCenterWorldY: number tileBoundsByZoom: Record | null viewportWidth: number viewportHeight: number visibleColumns: number overdraw: number translateX: number translateY: number rotationRad: number animationLevel: AnimationLevel previewScale: number previewOriginX: number previewOriginY: number trackMode: TrackDisplayMode trackStyleConfig: TrackVisualizationConfig track: LonLatPoint[] gpsPoint: LonLatPoint | null gpsMarkerStyleConfig: GpsMarkerStyleConfig gpsHeadingDeg: number | null gpsHeadingAlpha: number gpsCalibration: MapCalibration gpsCalibrationOrigin: LonLatPoint course: OrienteeringCourseData | null cpRadiusMeters: number gameMode: 'classic-sequential' | 'score-o' courseStyleConfig: CourseStyleConfig controlScoresBySequence: Record defaultControlStyleOverride: ControlPointStyleEntry | null controlStyleOverridesBySequence: Record startStyleOverrides: ControlPointStyleEntry[] finishStyleOverrides: ControlPointStyleEntry[] defaultLegStyleOverride: CourseLegStyleEntry | null legStyleOverridesByIndex: Record controlVisualMode: 'single-target' | 'multi-target' showCourseLegs: boolean guidanceLegAnimationEnabled: boolean focusableControlIds: string[] focusedControlId: string | null focusedControlSequences: number[] activeControlSequences: number[] readyControlSequences: number[] activeStart: boolean completedStart: boolean activeFinish: boolean focusedFinish: boolean completedFinish: boolean revealFullCourse: boolean activeLegIndices: number[] completedLegIndices: number[] completedControlSequences: number[] skippedControlIds: string[] skippedControlSequences: number[] osmReferenceEnabled: boolean overlayOpacity: number } export type MapRendererStats = TileStoreStats export interface MapRenderer { attachCanvas(canvasNode: any, width: number, height: number, dpr: number, labelCanvasNode?: any): void updateScene(scene: MapScene): void setAnimationPaused(paused: boolean): void getGpsLogoDebugInfo?(): { status: string; url: string; resolvedSrc: string } destroy(): void } export function buildCamera(scene: MapScene): CameraState { return { centerWorldX: scene.centerTileX + 0.5, centerWorldY: scene.centerTileY + 0.5, viewportWidth: scene.viewportWidth, viewportHeight: scene.viewportHeight, visibleColumns: scene.visibleColumns, translateX: scene.translateX, translateY: scene.translateY, rotationRad: scene.rotationRad, } }