import { CellPosition, Position, UID, UnboundedZone, Zone, ZoneDimension } from "../types/misc";
/**
 * Convert from a cartesian reference to a (possibly unbounded) Zone
 *
 * Examples:
 *    "A1" ==> Top 0, Bottom 0, Left: 0, Right: 0
 *    "B1:B3" ==> Top 0, Bottom 3, Left: 1, Right: 1
 *    "B:B" ==> Top 0, Bottom undefined, Left: 1, Right: 1
 *    "B2:B" ==> Top 1, Bottom undefined, Left: 1, Right: 1, hasHeader: 1
 *    "Sheet1!A1" ==> Top 0, Bottom 0, Left: 0, Right: 0
 *    "Sheet1!B1:B3" ==> Top 0, Bottom 3, Left: 1, Right: 1
 *
 * @param xc the string reference to convert
 *
 */
export declare function toUnboundedZone(xc: string): UnboundedZone;
/**
 * Convert from a cartesian reference to a Zone.
 * Will return throw an error if given a unbounded zone (eg : A:A).
 *
 * Examples:
 *    "A1" ==> Top 0, Bottom 0, Left: 0, Right: 0
 *    "B1:B3" ==> Top 0, Bottom 2, Left: 1, Right: 1
 *    "Sheet1!A1" ==> Top 0, Bottom 0, Left: 0, Right: 0
 *    "Sheet1!B1:B3" ==> Top 0, Bottom 2, Left: 1, Right: 1
 *
 * @param xc the string reference to convert
 *
 */
export declare function toZone(xc: string): Zone;
export declare function isXcValid(xc: string): boolean;
/**
 * Check that the given string is a correct xc representation (ie a valid zone). The try-catch
 * added over the ixXcValid call is necessary because the function can throw an error if the
 * string is not convertible to a zone by the toUnboundedZone function.
 */
export declare function isXcRepresentation(xc: string): boolean;
/**
 * Check that the zone has valid coordinates and in
 * the correct order.
 */
export declare function isZoneValid(zone: Zone | UnboundedZone): boolean;
/**
 * Check that the zone properties are in the correct order.
 */
export declare function isZoneOrdered(zone: Zone | UnboundedZone): boolean;
/**
 * Convert from zone to a cartesian reference
 *
 */
export declare function zoneToXc(zone: Zone | UnboundedZone): string;
/**
 * Expand a zone after inserting columns or rows.
 *
 * Don't resize the zone if a col/row was added right before/after the row but only move the zone.
 */
export declare function expandZoneOnInsertion<Z extends UnboundedZone | Zone>(zone: Z, start: "left" | "top", base: number, position: "after" | "before", quantity: number): Z;
/**
 * Update the selection after column/row addition
 */
export declare function updateSelectionOnInsertion(selection: Zone, start: "left" | "top", base: number, position: "after" | "before", quantity: number): Zone;
/**
 * Update the selection after column/row deletion
 */
export declare function updateSelectionOnDeletion(zone: Zone, start: "left" | "top", elements: number[]): Zone;
/**
 * Reduce a zone after deletion of elements
 */
export declare function reduceZoneOnDeletion<Z extends UnboundedZone | Zone>(zone: Z, start: "left" | "top", elements: number[]): Z | undefined;
/**
 * Compute the union of multiple zones.
 */
export declare function union(...zones: Zone[]): Zone;
/**
 * Compute the union of multiple unbounded zones.
 */
export declare function unionUnboundedZones(...zones: UnboundedZone[]): UnboundedZone;
/**
 * Compute the intersection of two zones. Returns nothing if the two zones don't overlap
 */
export declare function intersection(z1: UnboundedZone, z2: Zone): Zone | undefined;
/**
 * Two zones are equal if they represent the same area, so we clearly cannot use
 * reference equality.
 */
export declare function isEqual(z1: UnboundedZone, z2: Zone): boolean;
/**
 * Return true if two zones overlap, false otherwise.
 */
export declare function overlap(z1: UnboundedZone, z2: Zone): boolean;
/**
 * Returns true if any two zones in the given list overlap.
 */
export declare function hasOverlappingZones(zones: Zone[]): boolean;
export declare function isInside(col: number, row: number, zone: Zone): boolean;
/**
 * Check if a zone is inside another
 */
export declare function isZoneInside(smallZone: Zone, biggerZone: Zone): boolean;
export declare function zoneToDimension(zone: Zone): ZoneDimension;
export declare function isOneDimensional(zone: Zone): boolean;
export declare function excludeTopLeft(zone: Zone): Zone[];
/**
 * Array of all positions in the zone.
 */
export declare function positions(zone: Zone): Position[];
/**
 * Array of all cell positions in the zone.
 */
export declare function cellPositions(sheetId: UID, zone: Zone): CellPosition[];
export declare function reorderZone<Z extends UnboundedZone | Zone>(zone: Z): Z;
/**
 * This function returns a zone with coordinates modified according to the change
 * applied to the zone. It may be possible to change the zone by resizing or moving
 * it according to different dimensions.
 *
 * @param zone the zone to modify
 * @param dimension the direction to change the zone among "columns", "rows" and
 * "both"
 * @param operation how to change the zone, modify its size "RESIZE" or modify
 * its location "MOVE"
 * @param by a number of how many units the change should be made. This parameter
 * takes the form of a two-number array when the dimension is "both"
 */
export declare function createAdaptedZone<Dimension extends "columns" | "rows" | "both", Z extends UnboundedZone | Zone>(zone: Z, dimension: Dimension, operation: "MOVE" | "RESIZE", by: Dimension extends "both" ? [number, number] : number): Z;
/**
 * Returns a Zone array with unique occurrence of each zone.
 * For each multiple occurrence, the occurrence with the largest index is kept.
 * This allows to always have the last selection made in the last position.
 * */
export declare function uniqueZones(zones: Zone[]): Zone[];
/**
 * This function will find all overlapping zones in an array and transform them
 * into an union of each one.
 * */
export declare function mergeOverlappingZones(zones: Zone[]): Zone[];
/**
 * This function will compare the modifications of selection to determine
 * a cell that is part of the new zone and not the previous one.
 */
export declare function findCellInNewZone(oldZone: Zone, currentZone: Zone): Position;
export declare function positionToZone(position: Position): Zone;
/** Transform a zone into a zone with only its top-left position */
export declare function zoneToTopLeft(zone: Zone): Zone;
export declare function isFullRow(zone: UnboundedZone): boolean;
export declare function isFullCol(zone: UnboundedZone): boolean;
/** Returns the area of a zone */
export declare function getZoneArea(zone: Zone): number;
/**
 * Checks if a single zone crosses any of the frozen panes based on the vertical and horizontal split.
 */
export declare function doesZoneCrossFrozenPane(zone: Zone, xSplit: number, ySplit: number): boolean;
/**
 * Checks if any of the given zones crosses any of the frozen panes.
 */
export declare function doesAnyZoneCrossFrozenPane(zones: Zone[], xSplit: number, ySplit: number): boolean;
export declare function boundUnboundedZone(unboundedZone: Readonly<UnboundedZone>, sheetSize: ZoneDimension): Readonly<Zone>;
/**
 * Check if the zones are continuous, ie. if they can be merged into a single zone without
 * including cells outside the zones
 * */
export declare function areZonesContinuous(zones: Zone[]): boolean;
/** Return all the columns in the given list of zones */
export declare function getZonesCols(zones: Zone[]): Set<number>;
/**
 * Returns one merged zone per column,
 * spanning the full vertical range across all input zones.
 */
export declare function getZonesByColumns(zones: Zone[]): Zone[];
/** Return all the rows in the given list of zones */
export declare function getZonesRows(zones: Zone[]): Set<number>;
export declare function unionPositionsToZone(positions: Position[]): Zone;
/**
 * Check if two zones are contiguous, ie. that they share a border
 */
export declare function areZoneContiguous(zone1: Zone, zone2: Zone): boolean;
/**
 * Merge contiguous and overlapping zones that are in the array into bigger zones
 */
export declare function mergeContiguousZones(zones: Zone[]): Zone[];
/**
 * Splits zone z2 by removing the overlapping zone z1 (fully inside z2).
 * Returns the remaining parts of z2 that don't overlap with z1.
 *
 * Diagram:
 * ┌──────────── z2 ─────────────┐
 * │              1              │
 * │--------─────────────--------│
 * │  2    |     z1      |    3  │
 * │--------─────────────--------│
 * │              4              │
 * └─────────────────────────────┘
 *
 * Input:
 *   z1 = { top: 2, bottom: 3, left: 2, right: 3 }
 *   z2 = { top: 1, bottom: 4, left: 1, right: 4 }
 *
 * Output:
 * [
 *   { top: 4, bottom: 4, left: 1, right: 4 },  // bottom
 *   { top: 2, bottom: 3, left: 4, right: 4 },  // right
 *   { top: 2, bottom: 3, left: 1, right: 1 },  // left
 *   { top: 1, bottom: 1, left: 1, right: 4 }   // top
 * ]
 */
export declare function splitZone(z1: Zone, z2: Zone): Zone[];
