/**
 * Layer 1: Normalize
 *
 * Converts raw DOM PointerEvents into NormalizedPointer structs.
 * Pure functions — no side effects, no DOM listeners.
 */

import { classifyPointer } from '../core/input-classifier';
import type { NormalizedPointer, Button, Modifiers, PointerLifecycle } from './types';
import { NO_MODIFIERS } from './types';

/**
 * Extract modifiers from any DOM event with modifier flags.
 */
export function extractModifiers(e: {
	shiftKey: boolean;
	ctrlKey: boolean;
	altKey: boolean;
	metaKey: boolean;
}): Modifiers {
	if (!e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
		return NO_MODIFIERS;
	}
	return {
		shift: e.shiftKey,
		ctrl: e.ctrlKey,
		alt: e.altKey,
		meta: e.metaKey,
	};
}

/**
 * Clamp a raw button value to 0 | 1 | 2.
 */
function clampButton(raw: number): Button {
	if (raw === 1) return 1;
	if (raw === 2) return 2;
	return 0;
}

/**
 * Determine pointer lifecycle from event type.
 */
function lifecycleFromEventType(type: string): PointerLifecycle {
	switch (type) {
		case 'pointerdown':
			return 'down';
		case 'pointerup':
			return 'up';
		case 'pointercancel':
			return 'cancel';
		default:
			return 'move';
	}
}

/**
 * Normalize a raw PointerEvent into a NormalizedPointer.
 */
export function normalizePointer(e: PointerEvent): NormalizedPointer {
	const classified = classifyPointer(e);
	return {
		pointerId: e.pointerId,
		lifecycle: lifecycleFromEventType(e.type),
		source: classified.source,
		button: clampButton(e.button),
		modifiers: extractModifiers(e),
		screenX: e.clientX,
		screenY: e.clientY,
		pressure: e.pressure,
		timestamp: e.timeStamp,
	};
}
