import { DateAdapter } from '../date-adapter';
import { DateTime, IDateAdapter } from '../date-time';
import { CollectionIterator, ICollectionsArgs, IOccurrencesArgs, OccurrenceIterator } from '../iterators';
import { DateInput } from '../utilities';
import { IRunArgs, IRunnable } from './runnable';
export declare type DateAdapterFor<S> = S extends IOccurrenceGenerator<infer A> ? A : never;
export interface IOccurrenceGenerator<T extends typeof DateAdapter> extends IRunnable<T> {
    readonly dateAdapter: T;
    readonly timezone: string | null;
    occurrences(args: IOccurrencesArgs<T>): OccurrenceIterator<T>;
    collections(args: ICollectionsArgs<T>): CollectionIterator<T>;
    occursBetween(start: DateInput<T>, end: DateInput<T>, options: {
        excludeEnds?: boolean;
    }): boolean;
    occursOn(args: {
        date: DateInput<T>;
    }): boolean;
    occursOn(args: {
        weekday: IDateAdapter.Weekday;
        after?: DateInput<T>;
        before?: DateInput<T>;
        excludeEnds?: boolean;
    }): boolean;
    occursAfter(date: DateInput<T>, options: {
        excludeStart?: boolean;
    }): boolean;
    occursBefore(date: DateInput<T>, options: {
        excludeStart?: boolean;
    }): boolean;
    pipe(...operators: unknown[]): IOccurrenceGenerator<T>;
    /**
     * Allows setting the timezone associated with this `IOccurrenceGenerator`.
     * If `keepLocalTime === true`, then any `Rule` objects associated
     * with this occurrence generator will be changed so that their `start` time
     * is in this timezone while retaining the same local time. This fundamentally changes
     * the rule. Similarly, any `Dates` objects associated with this occurrence generator
     * will have their underlying dates updated so that they are in this timezone while
     * retaining the same local time (fundamentally changing the dates).
     *
     * You might use `keepLocalTime === true` if this occurrence generator was created in
     * another timezone with `timezone === null`. In this case, you may wish to specify the timezone
     * for the occurrence generator while retaining the local time associated with the underlying
     * `Rule` / `Dates`.
     */
    set(prop: 'timezone', value: string | null, options?: {
        keepLocalTime?: boolean;
    }): IOccurrenceGenerator<T>;
}
export declare abstract class OccurrenceGenerator<T extends typeof DateAdapter> implements IRunnable<T>, IOccurrenceGenerator<T> {
    abstract readonly isInfinite: boolean;
    abstract readonly hasDuration: boolean;
    /**
     * The maximum duration of this generators occurrences. Necessary
     * as part of the logic processing. By default it is 0.
     */
    readonly maxDuration: number;
    readonly timezone: string | null;
    readonly dateAdapter: T;
    /** Returns the first occurrence or, if there are no occurrences, null. */
    readonly firstDate: InstanceType<T> | null;
    /** If generator is infinite, returns `null`. Otherwise returns the end date */
    readonly lastDate: InstanceType<T> | null;
    constructor(args: {
        dateAdapter?: T;
        timezone?: string | null;
        maxDuration?: number;
    });
    abstract pipe(...operators: unknown[]): OccurrenceGenerator<T>;
    abstract set(prop: 'timezone', value: string | null, options?: {
        keepLocalTime?: boolean;
    }): OccurrenceGenerator<T>;
    /**
     * Processes the object's rules/dates and returns an iterable for the occurrences.
     *
     * Options object:
     * - `start` the date to begin iteration on
     * - `end` the date to end iteration on
     * - `take` the max number of dates to take before ending iteration
     * - `reverse` whether to iterate in reverse or not
     *
     * Examples:
     *
     ```
     const iterator = schedule.occurrences({ start: new Date(), take: 5 })
     
     for (const date of iterator) {
       // do stuff
     }
  
     iterator.toArray() // returns Date array
     iterator.next().value // returns next Date
     ```
     *
     */
    occurrences(args?: IOccurrencesArgs<T>): OccurrenceIterator<T>;
    /**
     * Iterates over the object's occurrences and bundles them into collections
     * with a specified granularity (default is `"INSTANTANIOUS"`). Make sure to
     * read about each option & combination of options below.
     *
     * Options object:
     *   - start?: DateAdapter
     *   - end?: DateAdapter
     *   - take?: number
     *   - reverse?: NOT SUPPORTED
     *   - granularity?: CollectionsGranularity
     *   - weekStart?: IDateAdapter.Weekday
     *   - incrementLinearly?: boolean
     *
     * Returned `Collection` object:
     *
     *   - `dates` property containing an array of DateAdapter objects.
     *   - `granularity` property containing the granularity.
     *     - `CollectionsGranularity` type extends `RuleOptions.Frequency` type by adding
     *       `"INSTANTANIOUS"`.
     *   - `periodStart` property containing a DateAdapter equal to the period's
     *     start time.
     *   - `periodEnd` property containing a DateAdapter equal to the period's
     *     end time.
     *
     * #### Details:
     *
     * `collections()` always returns full periods. This means that the `start` argument is
     * transformed to be the start of whatever period the `start` argument is in, and the
     * `end` argument is transformed to be the end of whatever period the `end` argument is
     * in.
     *
     * - Example: with granularity `"YEARLY"`, the `start` argument will be transformed to be the
     *   start of the year passed in the `start` argument, and the `end` argument will be transformed
     *   to be the end of the year passed in the `end` argument.
     *
     * By default, the `periodStart` value of `Collection` objects produced by this method does not
     * necessarily increment linearly. A collection will *always* contain at least one date,
     * so the `periodStart` from one collection to the next can "jump". This can be changed by
     * passing the `incrementLinearly: true` option. With this argument, `collections()` will
     * return `Collection` objects for each period in linear succession, even if a collection object
     * has no dates associated with it, so long as the object generating occurrences still has upcoming occurrences.
     *
     * - Example 1: if your object's first occurrence is 2019/2/1 (February 1st) and you call
     *   `collection({granularity: 'DAILY', start: new Date(2019,0,1)})`
     *   (so starting on January 1st), the first Collection produced will have a `periodStart` in February.
     *
     * - Example 2: if your object's first occurrence is 2019/2/1 (February 1st) and you call
     *   `collection({incrementLinearly: true, granularity: 'DAILY', start: new Date(2019,0,1)})`
     *   (so starting on January 1st), the first collection produced will have a `Collection#periodStart`
     *   of January 1st and have `Collection#dates === []`. Similarly, the next 30 collections produced
     *   (Jan 2nd - 31st) will all contain an empty array for the `dates` property. Then the February 1st
     *   `Collection` will contain dates.
     *
     * When giving a `take` argument to `collections()`, you are specifying
     * the number of `Collection` objects to return (rather than occurrences).
     *
     * When choosing a granularity of `"WEEKLY"`, the `weekStart` option is required.
     *
     * When choosing a granularity of `"MONTHLY"`:
     *
     * - If the `weekStart` option *is not* present, will generate collections with
     *   the `periodStart` and `periodEnd` at the beginning and end of each month.
     *
     * - If the `weekStart` option *is* present, will generate collections with the
     *   `periodStart` equal to the start of the first week of the month, and the
     *   `periodEnd` equal to the end of the last week of the month. This behavior could be
     *   desired when rendering opportunities in a calendar view, where the calendar renders
     *   full weeks (which may result in the calendar displaying dates in the
     *   previous or next months).
     *
     */
    collections(args?: ICollectionsArgs<T>): CollectionIterator<T>;
    /**
     * Returns true if an occurrence starts on or between the provided start/end
     * datetimes. If the `excludeEnds` option is provided, then occurrences
     * equal to the start/end times are ignored.
     *
     * If the occurrence generator has a duration, and `excludeEnds !== true`,
     * and a `maxDuration` argument is supplied (either in the constructor or
     * here), then any occurrence that's time overlaps with the start/end times
     * return true.
     */
    occursBetween(startInput: DateInput<T>, endInput: DateInput<T>, options?: {
        excludeEnds?: boolean;
        maxDuration?: number;
    }): boolean;
    /**
     * Checks to see if an occurrence exists which equals the given date.
     *
     * If this occurrence generator has a duration, and a `maxDuration`
     * argument is supplied (either in the constructor or here),
     * then `occursOn()` will check to see if an occurrence is happening
     * during the given datetime.
     *
     * Additionally, if this occurrence generator has a duration, then a maxDuration
     * argument must be provided. This argument should be the max number of milliseconds
     * that an occurrence's duration can be. When you create an occurrence
     * generator, you can specify the maxDuration at that time.
     */
    occursOn(args: {
        date: DateInput<T>;
        maxDuration?: number;
    }): boolean;
    /**
     * Checks to see if an occurrence exists with a weekday === the `weekday` argument.
     * **If there are infinite occurrences, you must include a `before` argument with
     * the `weekday` argument.** Does not currently consider occurrence duration.
     *
     * Optional arguments:
     *
     * - `after` and `before` arguments can be provided which limit the
     *   possible occurrences to ones *after or equal* or *before or equal* the given dates.
     *   - If `excludeEnds` is `true`, then the after/before arguments become exclusive rather
     *       than inclusive.
     */
    occursOn(args: {
        weekday: IDateAdapter.Weekday;
        after?: DateInput<T>;
        before?: DateInput<T>;
        excludeEnds?: boolean;
    }): boolean;
    /**
     * Returns true if an occurrence starts after the provided datetime.
     * If the `excludeStart` option is provided, then occurrences
     * equal to the provided datetime are ignored.
     *
     * If the occurrence generator has a duration, and `excludeStart !== true`,
     * and a `maxDuration` argument is supplied (either in the constructor or
     * here), then any occurrence that's end time is after/equal to the provided
     * datetime return true.
     */
    occursAfter(date: DateInput<T>, options?: {
        excludeStart?: boolean;
        maxDuration?: number;
    }): boolean;
    /**
     * Returns true if an occurrence starts before the provided datetime.
     * If the `excludeStart` option is provided, then occurrences
     * equal to the provided datetime are ignored.
     *
     * If the occurrence generator has a duration, and `excludeStart` is
     * also provided, then this will only return true if an occurrence
     * both starts and ends before the provided datetime.
     */
    occursBefore(date: DateInput<T>, options?: {
        excludeStart?: boolean;
    }): boolean;
    protected normalizeOccurrencesArgs(rawArgs: IOccurrencesArgs<T>): {
        start: DateTime;
        end: DateTime;
        take?: number | undefined;
        reverse?: boolean | undefined;
    };
    protected normalizeCollectionsArgs(rawArgs: ICollectionsArgs<T>): {
        start: DateTime;
        end: DateTime;
        granularity?: "INSTANTANIOUSLY" | "MILLISECONDLY" | "SECONDLY" | "MINUTELY" | "HOURLY" | "DAILY" | "WEEKLY" | "MONTHLY" | "YEARLY" | undefined;
        weekStart?: "SU" | "MO" | "TU" | "WE" | "TH" | "FR" | "SA" | undefined;
        incrementLinearly?: boolean | undefined;
        take?: number | undefined;
        reverse?: boolean | undefined;
    };
    protected normalizeOccursOnArgs(rawArgs?: {
        date?: DateInput<T>;
        weekday?: IDateAdapter.Weekday;
        after?: DateInput<T>;
        before?: DateInput<T>;
        excludeEnds?: boolean;
        excludeDates?: Array<DateInput<T>>;
        maxDuration?: number;
    }): {
        date: DateTime;
        after: DateTime;
        before: DateTime;
        excludeDates: DateTime[] | undefined;
        weekday?: "SU" | "MO" | "TU" | "WE" | "TH" | "FR" | "SA" | undefined;
        excludeEnds?: boolean | undefined;
        maxDuration?: number | undefined;
    };
    protected normalizeRunArgs(args: IRunArgs): {
        start: DateTime;
        end: DateTime;
        take?: number | undefined;
        reverse?: boolean | undefined;
    };
    protected normalizeDateInput(date: DateInput<T>): DateTime;
    protected normalizeDateInput(date?: DateInput<T>): undefined;
    protected normalizeDateInputToAdapter(date: DateInput<T>): InstanceType<T>;
    protected normalizeDateInputToAdapter(date?: DateInput<T>): undefined;
    protected normalizeRunOutput(date: DateTime): DateTime;
    private getMaxDuration;
}
//# sourceMappingURL=occurrence-generator.d.ts.map