import { GCPMContext } from "./gcpm";
import { Process, Processor, ProcessorEvents, ProcessorOptions } from "./process";
import { events, rects } from "./util";
import { Point } from "./util/ranges";
import { Unbreakable } from "./breaks";
import { Fragmentor } from "./fragments";
import Mutations from "./mutations";
export declare class Box {
    range: Range;
    inlinesRange?: Range;
    unbreakable?: Unbreakable;
    avoidBreakBefore: boolean;
    avoidBreakAfter: boolean;
    mainBlock?: HTMLElement;
    floats?: Float[];
    bottomOffset?: BottomOffset;
    startBlock: HTMLElement;
    endBlock: HTMLElement;
    bottom?: number;
    top?: number;
    inlinesRangeRect?: ClientRect;
    inlinesStartBoundary?: boolean;
    inlineStart: number;
    hasInlineBlocks: boolean;
    isRepeated?: boolean;
}
export interface LayoutContextEvents extends ProcessorEvents {
    'float-move': {
        float: Float;
        area: HTMLElement;
        areaBody: HTMLElement;
        areaBodyRect: ClientRect;
        newAreaBodyRect: ClientRect;
    };
    'body-bottom-change': {
        oldBottom: number;
        newBottom: number;
    };
}
export declare class LayoutContext extends events.EventEmitter<LayoutContextEvents> {
    root: HTMLElement;
    body: HTMLElement;
    areas: Areas;
    parentCtx?: LayoutContext;
    boxes: Box[];
    floats: Float[];
    overflowPoint: Point;
    overflowBox: Box;
    breakPoint?: Point;
    breakedBox?: Box;
    bottomOffsets: Map<HTMLElement, BottomOffset>;
    mutations: Mutations;
    _bodyBottom: number;
    constructor(root: HTMLElement, body: HTMLElement, areas: Areas, parentCtx?: LayoutContext);
    get bodyBottom(): number;
    set bodyBottom(val: number);
}
export declare type FloatAlignment = "auto" | "none" | "baseline" | "block-start-edge" | "block-end-edge" | "inline-start-edge" | "inline-end-edge";
export declare type Areas = {
    [areaName: string]: HTMLElement;
};
export interface Float {
    base: HTMLElement | SVGSVGElement;
    call: HTMLElement | SVGSVGElement;
    body: HTMLElement | SVGSVGElement;
    areaName: string;
    alignment: FloatAlignment;
}
export interface LayoutProcessorOptions extends ProcessorOptions {
    plugins: (string | [string, any])[] | {
        [name: string]: Record<string, unknown>;
    };
}
export interface LayoutProcessorEvents extends ProcessorEvents {
    'contents-start': Record<string, never>;
    'contents-end': Record<string, never>;
    'overflow-detected': {
        layoutContext: LayoutContext;
    };
    'no-overflow': {
        layoutContext: LayoutContext;
    };
    'no-break-point': {
        layoutContext: LayoutContext;
    };
    'valid-break-point': {
        layoutContext: LayoutContext;
    };
    'new-break-point-to-valid': {
        layoutContext: LayoutContext;
    };
}
export declare type LayoutProcessResult = {
    boxes: Box[];
    floats: Float[];
    overflowPoint: Point;
    overflowBox?: Box;
} | {
    breakPoint: Point;
};
export interface BottomOffset {
    after: number;
    inside: number;
    currentMargin: number;
}
export declare abstract class LayoutProcessor<Options extends LayoutProcessorOptions = LayoutProcessorOptions, Events extends LayoutProcessorEvents = LayoutProcessorEvents> extends Processor<Options, Events> {
    static defaultOptions: {
        plugins: (string | [string, any])[] | {
            [name: string]: Record<string, unknown>;
        };
        logLevel: "error" | "warn" | "info" | "debug";
        pluginsUri: string;
    };
    source: HTMLElement;
    doc: HTMLDocument;
    subProcessors: SubProcessor[];
    gcpmContext: GCPMContext;
    layoutContext: LayoutContext;
    avoidBreakTypes: string[];
    logNoValidBreakPoint: boolean;
    get mutations(): Mutations;
    protected constructor(source: HTMLElement, options?: Partial<Options>);
    addSubProcessor(subProcessor: SubProcessor): this;
    contentsProcess(root: HTMLElement, areas: Areas, parentCtx?: LayoutContext): Process;
    boxesProcess(root: HTMLElement): Process;
    createLayoutContext(root: HTMLElement, areas: Areas, parentCtx: LayoutContext): LayoutContext;
    fixWidth(elem: HTMLElement, style: CSSStyleDeclaration, ctx: LayoutContext): void;
}
export declare function updateBottomOffsets(bottomOffsets: BottomOffset[], style: CSSStyleDeclaration, customStyle: CSSStyleDeclaration): BottomOffset;
export declare function testBoxOverflow(box: Box, bodyBottom: number): Point;
export declare function testInlineOverflow(box: Box, bodyBottom: number, maxBottom?: number): Point;
export declare function testLinesOverflow(box: Box, lines: rects.Rect[], maxBottom: number): Point;
export declare function testAvoidBreakInside(fromNode: Node, ctx: LayoutContext, avoidBreakValues: string[], breakPoint?: Point, heightAtBreakElem?: boolean): Element | false;
export declare function moveFloat(float: Float, ctx: LayoutContext, gcpmContext: GCPMContext, box?: Box): boolean;
export declare function removeFloats(floats: Float[], stopPoint?: Point): void;
export interface SubProcessorContext {
    currentElement: HTMLElement;
    currentCustomStyle: CSSStyleDeclaration;
    currentStyle: CSSStyleDeclaration;
    nodes: TreeWalker;
    currentBox: Box;
    layoutContext: LayoutContext;
    areas: Areas;
}
export interface SubFragmentor {
    parentFragmentor: Fragmentor<any>;
}
export declare function isSubFragmentor(object: any): object is SubFragmentor;
export declare type SubProcessor = (this: LayoutProcessor, ctx: SubProcessorContext) => false | Promise<false | LayoutProcessResult>;
