import { EventEmitter } from 'events';
/**
 * A TimeFrame is a snapshot of data at a given time. The time is most likely a timestamp (ms)
 * and the data could be anything.
 */
export type TimeFrame<T> = {
    time: number;
    data: T;
};
/**
 * Fired as "tick" event by {@link TimeFrameAnimation} and derived classes
 * with the timestamp of the currently displayed state.
 *
 * @event
 */
export type TickEvent = {
    /**
     * Current time
     */
    time: number;
};
/**
 * An instance of TimeFrameAnimation provides methods and containers to manage animation
 * of provided TimeFrames
 * Fires {@link TickEvent}
 */
declare class TimeFrameAnimation<T> extends EventEmitter {
    private frames;
    private time;
    private animationSpeed;
    private lastTickTime;
    /**
     * Add a new TimeFrame information to the animation. If the frame container is not empty,
     * then the provided TimeFrame data will be added at the corresct position based on its time.
     * @param time
     * @param data
     */
    protected addFrame(time: number, data: T): void;
    /**
     * Remove a frame using its time as an ID
     * @param time
     * @returns
     */
    protected removeFrame(time: number): TimeFrame<T>[];
    /**
     * Call a function for each TimeFrame of the animation
     * @param action
     */
    protected forEachFrame(action: (frame: TimeFrame<T>) => void): void;
    /**
     * Get the time of the first TimeFrame (always the begining of the animation).
     * If the frame container is empty, returns Infinity
     */
    getAnimationStart(): number;
    /**
     * Get the animation start as a Date object
     * @returns
     */
    getAnimationStartDate(): Date;
    /**
     * Get the end time of the animation or -Infinity if empty.
     */
    getAnimationEnd(): number;
    /**
     * Get the animation end as a date object
     * @returns
     */
    getAnimationEndDate(): Date;
    /**
     * Get the current time of the animation
     */
    getAnimationTime(): number;
    /**
     * Get the current time of the animation as a Date object
     * @returns
     */
    getAnimationTimeDate(): Date;
    /**
     * Change the visualization to a specific time. Does not stop animation.
     */
    setAnimationTime(time: number): void;
    private clampAnimation;
    /**
     * Animate by a factor of real life speed.
     * Exampe, if `factor` is `10`, then the animation will play at 10 times the real life speed.
     * @param factor
     */
    animateByFactor(factor: number): void;
    /**
     * Changes the speed of the animation. `0` to stop.
     * The speed is in number of real world milliseconds per animation second.
     * Example: if timePerSecond is set to 10*1000, then the animation will run
     * 10x of real world speed.
     */
    animate(timePerSecond: number): void;
    /**
     * Get the speed of the animation.
     * The speed is in number of real world seconds per animation second.
     */
    getAnimationSpeed(): number;
    /**
     * Tells whether the animation is currently playing
     * @returns
     */
    isPlaying(): boolean;
    /**
     * Make the animation time progress based on the current timestamps.
     */
    protected animationTick(): void;
    /**
     * Find the index of TimeFrame whose time is just immediately below targetTime
     * @param targetTime
     * @returns
     */
    private findSmallerFrameIndex;
    /**
     * Based on the current animation time, retrieve the frame immediately before (frameA),
     * the frame immediately after (frameB) and the mix.
     * The mixe value is in the interval [0, 1], where close to `0` means the current time
     * is close to frameA and close to `1` means the current time is close to frameB. The mix
     * value is provided so that linear interpolation of data can be performed.
     * @returns
     */
    protected getCurrentFrames(): {
        frameA: TimeFrame<T> | null;
        frameB: TimeFrame<T> | null;
        mix: number;
    };
    /**
     * Providing a TimeFrame (time + data), get the TimeFrame from the annimation that is
     * directly after (when `direction` is positive) or immediately before (when `direction` is negative)
     * @param frame
     * @param direction
     * @returns
     */
    protected getNextFrame(frame: TimeFrame<T>, direction: number): TimeFrame<T> | null;
}
export { TimeFrameAnimation };
