/**
 * Column Balancing Module
 *
 * Implements Word-compatible column balancing for section boundaries.
 * Column balancing distributes content evenly across columns at section end,
 * matching Microsoft Word's behavior.
 */
/**
 * Configuration for column balancing behavior.
 */
export interface ColumnBalancingConfig {
    /** Whether column balancing is enabled */
    enabled: boolean;
    /** Acceptable height difference between columns in pixels */
    tolerance: number;
    /** Maximum iterations to prevent infinite loops */
    maxIterations: number;
    /** Minimum content height per column in pixels */
    minColumnHeight: number;
}
/**
 * Default configuration for column balancing.
 * These values are tuned to match Word's behavior.
 */
export declare const DEFAULT_BALANCING_CONFIG: ColumnBalancingConfig;
/**
 * Context for a column balancing operation.
 * Contains all information needed to calculate balanced layout.
 */
export interface BalancingContext {
    /** Number of columns to balance across */
    columnCount: number;
    /** Width of each column in pixels */
    columnWidth: number;
    /** Gap between columns in pixels */
    columnGap: number;
    /** Available height from current position to content bottom */
    availableHeight: number;
    /** Content blocks to distribute across columns */
    contentBlocks: BalancingBlock[];
}
/**
 * A content block for balancing calculations.
 * Contains height and constraint information.
 */
export interface BalancingBlock {
    /** Unique identifier for the block */
    blockId: string;
    /** Measured height of the block in pixels */
    measuredHeight: number;
    /** Whether this block can be split across columns */
    canBreak: boolean;
    /** Whether this block must stay with the next block */
    keepWithNext: boolean;
    /** Whether this block must stay together (not split) */
    keepTogether: boolean;
    /** Minimum lines at start of column (orphan control) */
    orphanLines?: number;
    /** Minimum lines at end of column (widow control) */
    widowLines?: number;
    /** Individual line heights for paragraph blocks (for line-level breaking) */
    lineHeights?: number[];
}
/**
 * Result of a column balancing calculation.
 */
export interface BalancingResult {
    /** Target height for each column */
    targetColumnHeight: number;
    /** Map of block ID to assigned column index */
    columnAssignments: Map<string, number>;
    /** Whether balancing converged successfully */
    success: boolean;
    /** Number of iterations used */
    iterations: number;
    /** Optional break points within blocks (for paragraph splitting) */
    blockBreakPoints?: Map<string, BlockBreakPoint>;
}
/**
 * Break point information for splitting a block across columns.
 */
export interface BlockBreakPoint {
    /** Block ID this break point applies to */
    blockId: string;
    /** Line index after which to break (for paragraphs) */
    breakAfterLine: number;
    /** Height of content before the break */
    heightBeforeBreak: number;
    /** Height of content after the break */
    heightAfterBreak: number;
}
/**
 * Calculate optimal column height for balanced layout.
 *
 * Algorithm:
 * 1. Sum total content height
 * 2. Calculate initial target = total / columnCount
 * 3. Simulate layout with target height
 * 4. Adjust if columns overflow/underflow
 * 5. Iterate until balanced or max iterations reached
 *
 * @param ctx - Balancing context with column config and content blocks
 * @param config - Balancing configuration
 * @returns Balancing result with column assignments
 */
export declare function calculateBalancedColumnHeight(ctx: BalancingContext, config?: ColumnBalancingConfig): BalancingResult;
/**
 * Check if column balancing should be triggered for a section.
 *
 * Balancing is triggered when:
 * 1. Section type is 'continuous' (mid-page section break)
 * 2. Section has explicit balanceColumns flag set to true
 * 3. This is the last section in the document (end of document)
 *
 * @param sectionType - Type of section break
 * @param balanceColumns - Explicit balance flag from section properties
 * @param isLastSection - Whether this is the document's final section
 * @returns Whether column balancing should be performed
 */
export declare function shouldBalanceColumns(sectionType: 'continuous' | 'nextPage' | 'evenPage' | 'oddPage' | undefined, balanceColumns: boolean | undefined, isLastSection: boolean): boolean;
/**
 * Determine if content should skip balancing (optimization).
 *
 * Skip balancing when:
 * 1. Balancing is disabled
 * 2. Single column (nothing to balance across)
 * 3. No content blocks
 * 4. Single unbreakable block that can't be split
 * 5. Total content fits in a single column (no overflow = no need to balance)
 * 6. Total content is less than minimum column height
 *
 * Word only balances columns when content would overflow a single column.
 * If all content fits comfortably in column 0, there's no redistribution.
 *
 * @param ctx - Balancing context
 * @param config - Balancing configuration
 * @returns Whether to skip balancing
 */
export declare function shouldSkipBalancing(ctx: BalancingContext, config?: ColumnBalancingConfig): boolean;
/**
 * Fragment with required properties for column balancing.
 * Represents a positioned content block that can be redistributed across columns.
 */
export interface BalancingFragment {
    /** Horizontal position in pixels from left edge of page */
    x: number;
    /** Vertical position in pixels from top edge of page */
    y: number;
    /** Width of the fragment in pixels (updated during balancing to match column width) */
    width: number;
    /** Type of content: 'para', 'image', 'drawing', 'table', etc. */
    kind: string;
    /** Unique identifier linking fragment to its source block */
    blockId: string;
    /** Starting line index for partial paragraph fragments */
    fromLine?: number;
    /** Ending line index (exclusive) for partial paragraph fragments */
    toLine?: number;
    /** Pre-computed height for non-paragraph fragments */
    height?: number;
}
/**
 * Measure data used to calculate fragment heights.
 * Contains layout measurements from the measuring phase.
 */
export interface MeasureData {
    /** Type of measure: 'paragraph', 'image', etc. */
    kind: string;
    /** Line measurements for paragraph content */
    lines?: Array<{
        lineHeight: number;
    }>;
    /** Total height for non-paragraph content (image, drawing) */
    height?: number;
    /** Total height for table content (TableMeasure stores this rather than `height`). */
    totalHeight?: number;
}
/**
 * Column layout properties relevant to balancing decisions.
 * Mirrors the subset of ColumnLayout that this module reads.
 */
export interface SectionColumnLayout {
    count: number;
    gap: number;
    width?: number;
    widths?: number[];
    equalWidth?: boolean;
}
export interface BalanceSectionOnPageArgs {
    /** All fragments on the target page. Only those belonging to sectionIndex are balanced (mutated in place). */
    fragments: BalancingFragment[];
    /** Section whose content ends on this page. */
    sectionIndex: number;
    /** Column layout of the ending section. */
    sectionColumns: SectionColumnLayout;
    /** True if the section contains an explicit <w:br w:type="column"/> — skip balancing to preserve author intent. */
    sectionHasExplicitColumnBreak: boolean;
    /** blockId -> sectionIndex map (built once per layout, shared across calls). */
    blockSectionMap: Map<string, number>;
    /** Left page margin, used to compute column X positions. */
    margins: {
        left: number;
    };
    /** Y position where the section's region begins on this page. */
    topMargin: number;
    /** Column width — passed to balancePageColumns so it can resize fragments. */
    columnWidth: number;
    /** Available height from topMargin to content bottom. */
    availableHeight: number;
    /** Measurement data for fragments (built from measures array). */
    measureMap: Map<string, MeasureData>;
    /**
     * Block IDs of paragraphs that exist only to carry `<w:sectPr>` properties.
     * These contribute zero height to balanced columns — see `getBalancingHeight`.
     * Optional; when omitted no fragment is treated as a marker.
     */
    sectPrMarkerBlockIds?: Set<string>;
}
/**
 * Balance the fragments of one section on one page.
 *
 * Returns the tallest balanced column's bottom Y, or null if balancing was skipped.
 * Callers can use the returned Y to update paginator cursors so subsequent content
 * starts just below the balanced section rather than below an unbalanced maxCursorY.
 *
 * Guards (skip balancing when):
 *   - Section has <= 1 column (nothing to balance)
 *   - Section contains an explicit column break (author intent wins)
 *   - Section uses unequal column widths (Word doesn't rebalance these)
 *   - No fragments on this page belong to the section
 */
export declare function balanceSectionOnPage(args: BalanceSectionOnPageArgs): {
    maxY: number;
} | null;
//# sourceMappingURL=column-balancing.d.ts.map