/** * EventLayoutCoordinator - Coordinates event layout calculations * * Separates layout logic from rendering concerns. * Calculates stack levels, groups events, and determines rendering strategy. */ import { ICalendarEvent } from '../types/CalendarTypes'; import { EventStackManager, IStackLink } from './EventStackManager'; import { PositionUtils } from '../utils/PositionUtils'; import { Configuration } from '../configurations/CalendarConfig'; export interface IGridGroupLayout { events: ICalendarEvent[]; stackLevel: number; position: { top: number; }; columns: ICalendarEvent[][]; } export interface IStackedEventLayout { event: ICalendarEvent; stackLink: IStackLink; position: { top: number; height: number; }; } export interface IColumnLayout { gridGroups: IGridGroupLayout[]; stackedEvents: IStackedEventLayout[]; } export declare class EventLayoutCoordinator { private stackManager; private config; private positionUtils; constructor(stackManager: EventStackManager, config: Configuration, positionUtils: PositionUtils); /** * Calculate complete layout for a column of events (recursive approach) */ calculateColumnLayout(columnEvents: ICalendarEvent[]): IColumnLayout; /** * Calculate stack level for a grid group based on already rendered events */ private calculateGridGroupStackLevelFromRendered; /** * Calculate stack level for a single stacked event based on already rendered events */ private calculateStackLevelFromRendered; /** * Detect if two events have a conflict based on threshold * * @param event1 - First event * @param event2 - Second event * @param thresholdMinutes - Threshold in minutes * @returns true if events conflict */ private detectConflict; /** * Expand grid candidates to find all events connected by conflict chains * * Uses expanding search to find chains (A→B→C where each conflicts with next) * * @param firstEvent - The first event to start with * @param remaining - Remaining events to check * @param thresholdMinutes - Threshold in minutes * @returns Array of all events in the conflict chain */ private expandGridCandidates; /** * Allocate events to columns within a grid group * * Events that don't overlap can share the same column. * Uses a greedy algorithm to minimize the number of columns. * * @param events - Events in the grid group (should already be sorted by start time) * @returns Array of columns, where each column is an array of events */ private allocateColumns; }