/**
 * Various utility functions for manipulating (sets of) ranges
 */
import { BibleRef, BibleVerse, BibleRange, BibleRefLibData } from './BibleRef';
import { Versification } from './Versification';
export interface RangeManipFunctions {
    splitByBook(refs: BibleRef | BibleRef[], expand_verses?: boolean): BibleRef[];
    splitByChapter(refs: BibleRef | BibleRef[], expand_verses?: boolean): BibleRef[];
    splitByVerse(refs: BibleRef | BibleRef[]): BibleVerse[];
    iterateByBook(refs: BibleRef | BibleRef[], expand_verses?: boolean): Iterable<BibleRef>;
    iterateByChapter(refs: BibleRef | BibleRef[], expand_verses?: boolean): Iterable<BibleRef>;
    iterateByVerse(refs: BibleRef | BibleRef[]): Iterable<BibleVerse>;
    groupByBook(refs: BibleRef | BibleRef[]): RefsByBook[];
    groupByChapter(refs: BibleRef | BibleRef[]): RefsByChapter[];
    groupByLevel(refs: BibleRef | BibleRef[], options?: RefsByLevelOptions): RefsByLevel;
    makeRange(book: string, chapter?: number): BibleRange;
    makeBookRange(book_start: string, book_end: string): BibleRange;
    nextChapter(ref: BibleRef, constrain_book?: boolean): BibleRange | null;
    previousChapter(ref: BibleRef, constrain_book?: boolean): BibleRange | null;
    nextBook(ref: BibleRef): BibleRange | null;
    previousBook(ref: BibleRef): BibleRange | null;
    nextVerse(ref: BibleRef, opts?: {
        constrain_book?: boolean;
        constrain_chapter?: boolean;
    }): BibleVerse | null;
    previousVerse(ref: BibleRef, opts?: {
        constrain_book?: boolean;
        constrain_chapter?: boolean;
    }): BibleVerse | null;
    isFullBook(ref: BibleRef): boolean;
    isFullChapter(ref: BibleRef): boolean;
}
/**
 * Creates a [[BibleRange]] representing either an entire book, or
 * an entire chapter
 * @note This function will throw if the specified book is not a
 * valid book ID, or if the specified chapter is too high
 *
 * @param this - Any object with a `versification` field
 */
export declare function makeRange(this: BibleRefLibData, book: string, chapter?: number): BibleRange;
/**
 * Creates a [[BibleRange]] representing a number of complete books, starting
 * at chapter 1 verse 1 of `book_start`, and ending at the final chapter/verse
 * of book_end
 *
 * @note book_end can be left undefined in which case it will be assumed to be
 * equal to book_start. Useful for code where book_end is a variable since
 * caller doesn't know if book_end will be defined
 */
export declare function makeBookRange(this: BibleRefLibData, book_start: string, book_end?: string): BibleRange;
/**
 * Splits an array of ranges such that any input range spanning multiple
 * books is subdivided into multiple smaller ranges, one for each book
 * @param refs - The list of refs to be split
 * @param expand_verses - If set then even single verses will be represented
 * as ranges of length 1, ensuring all returned objects have the same schema
 */
export declare function splitByBook(this: BibleRefLibData, refs: BibleRef | BibleRef[], expand_verses?: boolean): BibleRef[];
/**
 * Splits an array of ranges such that any input range spanning multiple
 * chapters is subdivided into multiple smaller ranges, one for each chapter
 * @param refs - The list of refs to be split
 * @param expand_verses - If set then even single verses will be represented
 * as ranges of length 1, ensuring all returned objects have the same schema.
 */
export declare function splitByChapter(this: BibleRefLibData, refs: BibleRef | BibleRef[], expand_verses?: boolean): BibleRef[];
/**
 * Splits an array of ranges to form an array of individual verses
 * @param refs - The list of refs to be split
 */
export declare function splitByVerse(this: BibleRefLibData, refs: BibleRef | BibleRef[]): BibleVerse[];
/**
 * Returns an iterator that traverses over the objects that would have been
 * returned by `splitByBook`
 */
export declare function iterateByBook(this: BibleRefLibData, refs: BibleRef | BibleRef[], expand_verses?: boolean): Iterable<BibleRef>;
/**
 * Returns an iterator that traverses over the objects that would have been
 * returned by `splitByChapter`
 */
export declare function iterateByChapter(this: BibleRefLibData, refs: BibleRef | BibleRef[], expand_verses?: boolean): Iterable<BibleRef>;
/**
 * Returns an iterator that traverses over the objects that would have been
 * returned by `splitByVerse`
 */
export declare function iterateByVerse(this: BibleRefLibData, refs: BibleRef | BibleRef[]): Iterable<BibleVerse>;
/**
 * Given a BibleRef, returns a new BibleVerse which represents the next verse after
 * the last verse in the input ref
 * @param opts.constrain_book - If set, will not cross book boundaries to find another verse
 * @param opts.constrain_chapter - If set, will not cross chapter boundaries to find another verse
 */
export declare function nextVerse(this: BibleRefLibData, ref: BibleRef, opts?: {
    constrain_book?: boolean;
    constrain_chapter?: boolean;
}): BibleVerse | null;
/**
 * Given a BibleRef, returns a new BibleVerse which represents the verse preceeding
 * the first verse in the input ref
 * @param opts.constrain_book - If set, will not cross book boundaries to find another verse
 * @param opts.constrain_chapter - If set, will not cross chapter boundaries to find another verse
 */
export declare function previousVerse(this: BibleRefLibData, ref: BibleRef, opts?: {
    constrain_book?: boolean;
    constrain_chapter?: boolean;
}): BibleVerse | null;
/**
 * Given a BibleRef, returns a new BibleRef which represents the next chapter
 * after the last verse in the input ref.
 * @param constrain_book - If true, will not cross book boundaries to find another chapter
 * @return BibleRef or null if there is no next chapter
 */
export declare function nextChapter(this: BibleRefLibData, ref: BibleRef, constrain_book?: boolean): BibleRange | null;
/**
 * Returns BibleRef representing the range of verses making up the chapter
 * BEFORE the first verse of the input ref
 * @param constrain_book - If true, will not cross book boundaries to find another chapter
 * @return BibleRef or null if there is no previous chapter
 */
export declare function previousChapter(this: BibleRefLibData, ref: BibleRef, constrain_book?: boolean): BibleRange | null;
/**
 * Given a BibleRef, returns a new BibleRef which represents the range of verses making up
 * the next book after the book containing the last verse in the input range
 * @return BibleRef or null if there is no next book (IE: input is revelation)
 */
export declare function nextBook(this: BibleRefLibData, ref: BibleRef): BibleRange | null;
/**
 * Given a BibleRef, returns a new BibleRef which represents the range of verses making up
 * the book before the book containing the first verse in the input range
 * @return BibleRef or null if there is no previous book (IE: input is genesis)
 */
export declare function previousBook(this: BibleRefLibData, ref: BibleRef): BibleRange | null;
/**
 * Determines if a [[BibleRef]] is in fact just a single [[BibleRange]] which represents **exactly**
 * the entirety of a single book - no more, no less
 * @return Boolean representing decision
 */
export declare function isFullBook(this: BibleRefLibData, ref: BibleRef): boolean;
/**
 * Determines if a [[BibleRef]] is in fact just a single [[BibleRange]] which represents **exactly**
 * the entirety of a single chapter - no more, no less
 * @return Boolean representing decision
 */
export declare function isFullChapter(this: BibleRefLibData, ref: BibleRef): boolean;
/**
 * Bucket of BibleRefs with a common Book
 * @see [[groupByBook]]
 */
export interface RefsByBook {
    /** The book common to all references in this bucket */
    book: string;
    /** The set of [[BibleRef]]s in this bucket */
    references: BibleRef[];
}
/**
 * Groups a list of references into buckets split by book
 *
 * Returns list of [[RefsByBook]] representing the buckets that the input references have been
 * sorted into. Returns list will be in order from the bucket for the first book to the last book,
 * however the individual references within each bucket will maintain their order relative to
 * the input array - hence input order matters. Pre-sort if desired.
 */
export declare function groupByBook(this: BibleRefLibData, refs: BibleRef[] | BibleRef): RefsByBook[];
/**
 * Bucket of BibleRefs with a common Book and chapter
 * @see [[groupByChapter]]
 */
export interface RefsByChapter {
    /** The book common to all references in this bucket */
    book: string;
    /** The chapter common to all references in this bucket */
    chapter: number;
    /** The set of [[BibleRef]]s in this bucket */
    references: BibleRef[];
}
/**
 * Groups a list of references into buckets split by book, chapter
 *
 * Returns list of [[RefsByChapter]] representing the buckets that the input references have been
 * sorted into. Returns list will be in order from the bucket for the first book to the last book,
 * however the individual references within each bucket will maintain their order relative to
 * the input array - hence input order matters. Pre-sort if desired.
 */
export declare function groupByChapter(this: BibleRefLibData, refs: BibleRef[] | BibleRef): RefsByChapter[];
export interface RefsByLevel {
    books: BibleRange[];
    chapters: BibleRange[];
    verses: BibleVerse[];
}
export interface RefsByLevelOptions {
    /**
     * If true, then smaller levels will create entries in larger levels
     *
     * For example:
     * - Gen.1.1 -> { books: [ Gen ], chapters: [ Gen.1 ], verses: [ Gen.1.1 ] }
     * - Gen.1   -> { books: [ Gen ], chapters: [ Gen.1 ], verses: [] }
     * - Gen     -> { books: [ Gen ], chapters: [],        verses: [] }
     *
     * Multiple verses will be combined into a single chapter entry, and multiple
     * chapters will be combined into a single book entry
     *
     * If set then the following will hold: ---subset of---> chapters ---subset of---> books
     *
     * If `disperse` is also set, then all arrays will represent the same set of Bible references,
     * but with different organizations of data structures
     */
    consolidate?: boolean;
    /**
     * If true, then larger levels will create entries in smaller levels
     *
     * For example:
     * - Gen.1.1 -> { books: [],      chapters: [],                           verses: [ Gen.1.1 ] },
     * - Gen.1   -> { books: [],      chapters: [ Gen.1 ],                    verses: [ Gen.1.1, Gen.1.2, Gen.1.3, ... ] }
     * - Gen     -> { books: [ Gen ], chapters: [ Gen.1, Gen.2, Gen.3, ... ], verses: [ Gen.1.1, Gen.1.2, Gen.1.3, ... ] }
     *
     * A chapter/verse contained by multiple higher level ranges will only be added once
     *
     * If set then the following will hold: ---subset of--> chapters ---subset of---> verses
     *
     * If `consolidate` is also set, then all arrays will represent the same set of Bible references,
     * but with different organizations of data structures
     */
    disperse?: boolean;
}
/**
 * Sorts a list of references into seperate lists for full books, full chapters,
 * and individual verses
 *
 * For example, Gen, Exo.1, Lev.1.1 would be grouped into the object:
 * {
 *   books    : [ Gen ],
 *   chapters : [ Exo.1 ],
 *   verses   : [ Lev.1.1 ],
 * }
 *
 * The `books` and `chapters` array will contain only [[BibleRange]]s, where as `verses` will
 * contain only [[BibleVerse]]s
 *
 * The output arrays will be de-deuplicated when multiple inputs would create the same output,
 * and arrays will be sorted into verse order - hence input order is not important
 */
export declare function groupByLevel(this: BibleRefLibData, refs: BibleRef[] | BibleRef, options?: RefsByLevelOptions): RefsByLevel;
export declare function _makeBookRange(v: Versification, book_start: string, book_end?: string): BibleRange;
