import { FlowBlock, Layout, Measure, Fragment, DrawingFragment, ImageFragment, Line, TableFragment, TableBlock, TableMeasure, ParagraphBlock, ParagraphMeasure } from '../../contracts/src/index.js';
import { PageGeometryHelper } from './page-geometry-helper.js';
export type Point = {
    x: number;
    y: number;
};
export type PageHit = {
    pageIndex: number;
    page: Layout['pages'][number];
};
export type FragmentHit = {
    fragment: Fragment;
    block: FlowBlock;
    measure: Measure;
    pageIndex: number;
    pageY: number;
};
export type PositionHit = {
    pos: number;
    layoutEpoch: number;
    blockId: string;
    pageIndex: number;
    column: number;
    lineIndex: number;
};
/**
 * Result of hit-testing a table fragment.
 * Contains all information needed to identify the cell and paragraph at a click point.
 */
export type TableHitResult = {
    /** The table fragment that was hit */
    fragment: TableFragment;
    /** The table block from the document structure */
    block: TableBlock;
    /** The table measurement data */
    measure: TableMeasure;
    /** Index of the page containing the hit */
    pageIndex: number;
    /** Row index of the hit cell (0-based) */
    cellRowIndex: number;
    /** Column index of the hit cell (0-based) */
    cellColIndex: number;
    /** The paragraph block inside the cell */
    cellBlock: ParagraphBlock;
    /** Measurement data for the paragraph inside the cell */
    cellMeasure: ParagraphMeasure;
    /** X coordinate relative to the cell content area */
    localX: number;
    /** Y coordinate relative to the cell content area */
    localY: number;
    /**
     * Cumulative line count of preceding paragraph blocks in this cell.
     * Used by callers to compute the hit paragraph's local first-line flag
     * when the row continues from a prior page: `isFirstLineOfParagraph` is
     * `lineIndex === 0 && max(0, cellLineStart - blockStartGlobal) === 0`,
     * matching `renderTableCell.ts`'s `localStartLine` computation.
     */
    blockStartGlobal: number;
};
type AtomicFragment = DrawingFragment | ImageFragment;
export type GeometryPageHint = {
    pageIndex: number;
    pageRelativeY?: number;
};
export type ClickToPositionGeometryOptions = {
    geometryHelper?: PageGeometryHelper;
    pageHint?: GeometryPageHint;
};
export declare const isAtomicFragment: (fragment: Fragment) => fragment is AtomicFragment;
export declare const getAtomicPmRange: (fragment: AtomicFragment, block: FlowBlock) => {
    pmStart?: number;
    pmEnd?: number;
};
export declare const isRtlBlock: (block: FlowBlock) => boolean;
export declare const determineColumn: (layout: Layout, fragmentX: number) => number;
/**
 * Finds the line index at a given Y offset within a set of lines.
 */
export declare const findLineIndexAtY: (lines: Line[], offsetY: number, fromLine: number, toLine: number) => number | null;
/**
 * Maps an X coordinate within a line to a ProseMirror position.
 */
export declare const mapPointToPm: (block: FlowBlock, line: Line, x: number, isRTL: boolean, availableWidthOverride?: number, alignmentOverride?: string) => number | null;
/**
 * Finds the nearest paragraph or atomic fragment to a point on a page.
 */
export declare function snapToNearestFragment(pageHit: PageHit, blocks: FlowBlock[], measures: Measure[], pageRelativePoint: Point): FragmentHit | null;
/**
 * Find a block by fragment blockId, handling continuation fragments.
 * When paragraphs split across pages, continuation fragments get suffixed IDs
 * (e.g., "5-paragraph-1") while the blocks array uses the base ID ("5-paragraph").
 */
export declare function findBlockIndexByFragmentId(blocks: FlowBlock[], fragmentBlockId: string, targetPmRange?: {
    from: number;
    to: number;
}): number;
/**
 * Calculates cumulative Y position for a page (fallback when no geometry helper provided).
 */
export declare const calculatePageTopFallback: (layout: Layout, pageIndex: number) => number;
/**
 * Find the page hit given layout and a coordinate relative to the layout container.
 * Accounts for gaps between pages when calculating page boundaries.
 */
export declare function hitTestPage(layout: Layout, point: Point, geometryHelper?: PageGeometryHelper): PageHit | null;
/**
 * Hit-test fragments within a page for a given point (page-relative coordinates).
 */
export declare function hitTestFragment(layout: Layout, pageHit: PageHit, blocks: FlowBlock[], measures: Measure[], point: Point): FragmentHit | null;
export declare const hitTestAtomicFragment: (pageHit: PageHit, blocks: FlowBlock[], measures: Measure[], point: Point) => FragmentHit | null;
/**
 * Hit-test table fragments to find the cell and paragraph at a click point.
 */
export declare const hitTestTableFragment: (pageHit: PageHit, blocks: FlowBlock[], measures: Measure[], point: Point) => TableHitResult | null;
/**
 * Enriches a DOM-resolved PM position into a full PositionHit by searching layout
 * metadata. Pure data lookup — no DOM reads.
 *
 * Extracted from the DOM-success path of the original `clickToPosition()`.
 */
export declare function resolvePositionHitFromDomPosition(layout: Layout, blocks: FlowBlock[], measures: Measure[], domPos: number, layoutEpoch: number): PositionHit;
/**
 * Geometry-only hit testing. DOM-free — no `elementsFromPoint`, no `getBoundingClientRect`.
 *
 * When `options.pageHint` is provided, uses the hint's page index and optional
 * page-relative Y instead of recomputing from geometry. This allows callers that
 * have already done DOM page detection to pass their result through.
 *
 * Extracted from the geometry fallback path of the original `clickToPosition()`.
 */
export declare function clickToPositionGeometry(layout: Layout, blocks: FlowBlock[], measures: Measure[], containerPoint: Point, options?: ClickToPositionGeometryOptions): PositionHit | null;
export {};
//# sourceMappingURL=position-hit.d.ts.map