import type { EventEmitter } from '@visactor/vutils';
import type { AnimateMode, AnimateStatus, AnimateStepType } from '../common/enums';
import type { Releaseable } from './common';
import type { IGraphic } from './graphic';
export interface Timeline {
    AnimateList: IAnimate[];
}
export type EasingTypeStr = 'linear' | 'quadIn' | 'quadOut' | 'quadInOut' | 'quadInOut' | 'cubicIn' | 'cubicOut' | 'cubicInOut' | 'quartIn' | 'quartOut' | 'quartInOut' | 'quintIn' | 'quintOut' | 'quintInOut' | 'backIn' | 'backOut' | 'backInOut' | 'circIn' | 'circOut' | 'circInOut' | 'bounceOut' | 'bounceIn' | 'bounceInOut' | 'elasticIn' | 'elasticOut' | 'elasticInOut' | 'sineIn' | 'sineOut' | 'sineInOut' | 'expoIn' | 'expoOut' | 'expoInOut' | 'easeInOutQuad' | 'easeOutElastic' | 'easeInOutElastic' | '';
export type EasingTypeFunc = (t: number) => number;
export type EasingType = EasingTypeStr | EasingTypeFunc;
export type IAnimateStepType = keyof typeof AnimateStepType;
export interface IStep {
    type: IAnimateStepType;
    prev?: IStep;
    duration: number;
    position: number;
    next?: IStep;
    props?: any;
    parsedProps?: any;
    propKeys?: string[];
    easing?: EasingTypeFunc;
    customAnimate?: ICustomAnimate;
    append: (step: IStep) => void;
    getLastProps: () => any;
}
export interface IStepConfig {
    tempProps?: boolean;
    noPreventAttrs?: boolean;
}
export interface IAnimateTarget {
    onAnimateBind?: (animte: IAnimate | ISubAnimate) => void;
    onAddStep?: (step: IStep) => void;
    onStep: (subAnimate: ISubAnimate, animate: IAnimate, step: IStep, ratio: number, end: boolean) => void;
    stepInterpolate: (subAnimate: ISubAnimate, animate: IAnimate, nextAttributes: Record<string, any>, step: IStep, ratio: number, end: boolean, nextProps: Record<string, any>, lastProps?: Record<string, any>, nextParsedProps?: any, propKeys?: string[]) => void;
    getComputedAttribute: (name: string) => any;
    getDefaultAttribute: (name: string) => any;
    onStop: (props?: Record<string, any>) => void;
    animates: Map<string | number, IAnimate>;
    [key: string]: any;
}
export interface ICustomAnimate {
    duration: number;
    easing: EasingType;
    step?: IStep;
    mode?: AnimateMode;
    bind: (target: IAnimateTarget, subAni: ISubAnimate) => void;
    onBind: () => void;
    onFirstRun: () => void;
    onStart: () => void;
    onEnd: () => void;
    onUpdate: (end: boolean, ratio: number, out: Record<string, any>) => void;
    update: (end: boolean, ratio: number, out: Record<string, any>) => void;
    getEndProps: () => Record<string, any> | void;
    getFromProps: () => Record<string, any> | void;
    getMergedEndProps: () => Record<string, any> | void;
}
export interface IAnimate {
    readonly id: string | number;
    status: AnimateStatus;
    interpolateFunc: (key: string, ratio: number, from: any, to: any, nextAttributes: any) => boolean;
    _onStart?: (() => void)[];
    _onFrame?: ((step: IStep, ratio: number) => void)[];
    _onEnd?: (() => void)[];
    _onRemove?: (() => void)[];
    getStartProps: () => Record<string, any>;
    getEndProps: () => Record<string, any>;
    setTimeline: (timeline: ITimeline) => void;
    readonly timeline: ITimeline;
    bind: (target: IAnimateTarget) => this;
    to: (props: Record<string, any>, duration: number, easing: EasingType, params?: IStepConfig) => this;
    from: (props: Record<string, any>, duration: number, easing: EasingType, params?: IStepConfig) => this;
    pause: () => void;
    resume: () => void;
    onStart: (cb: () => void) => void;
    onEnd: (cb: () => void) => void;
    onFrame: (cb: (step: IStep, ratio: number) => void) => void;
    preventAttr: (key: string) => void;
    preventAttrs: (key: string[]) => void;
    validAttr: (key: string) => boolean;
    runCb: (cb: (a: IAnimate, step: IStep) => void) => IAnimate;
    customInterpolate: (key: string, ratio: number, from: any, to: any, target: IAnimateTarget, ret: Record<string, any>) => boolean;
    play: (customAnimate: ICustomAnimate) => this;
    stop: (type?: 'start' | 'end' | Record<string, any>) => void;
    release: () => void;
    getDuration: () => number;
    getStartTime: () => number;
    wait: (delay: number) => this;
    afterAll: (list: IAnimate[]) => this;
    after: (animate: IAnimate) => this;
    parallel: (animate: IAnimate) => this;
    reversed: (r: boolean) => IAnimate;
    loop: (n: number) => IAnimate;
    bounce: (b: boolean) => IAnimate;
    nextAnimate?: IAnimate;
    prevAnimate?: IAnimate;
    advance: (delta: number) => void;
    startAt: (t: number) => IAnimate;
}
export interface ISubAnimate {
    getLastStep: () => IStep;
    animate: IAnimate;
    getLastPropByName: (name: string, step: IStep) => any;
}
export interface BaseAnimateConfig {
    id?: number | string;
    interpolate?: (key: string, ratio: number, from: any, to: any, nextAttributes: any) => boolean;
    onStart?: () => void;
    onFrame?: (step: IStep, ratio: number) => void;
    onEnd?: () => void;
    onRemove?: () => void;
}
export interface MorphingAnimateConfig extends Omit<BaseAnimateConfig, 'interpolate'> {
    duration?: number;
    easing?: EasingType;
    delay?: number;
}
export interface MultiMorphingAnimateConfig extends MorphingAnimateConfig {
    splitPath?: 'clone' | ((graphic: IGraphic, count: number, needAppend?: boolean) => IGraphic[]);
    individualDelay?: (index: number, count: number, fromGraphic: IGraphic, toGraphic: IGraphic) => number;
}
export interface ITimeline {
    id: number;
    animateCount: number;
    addAnimate: (animate: IAnimate) => void;
    removeAnimate: (animate: IAnimate, release?: boolean) => void;
    tick: (delta: number) => void;
    clear: () => void;
    pause: () => void;
    resume: () => void;
}
export interface ITickHandler extends Releaseable {
    avaliable: () => boolean;
    tick: (interval: number, cb: (handler: ITickHandler) => void) => void;
    tickTo?: (t: number, cb: (handler: ITickHandler, params?: {
        once: boolean;
    }) => void) => void;
    getTime: () => number;
}
export interface ITickerHandlerStatic {
    Avaliable: () => boolean;
    new (): ITickHandler;
}
export interface ITicker extends EventEmitter {
    setFPS?: (fps: number) => void;
    setInterval?: (interval: number) => void;
    getFPS?: () => number;
    getInterval?: () => number;
    tick: (interval: number) => void;
    tickAt?: (time: number) => void;
    pause: () => boolean;
    resume: () => boolean;
    start: (force?: boolean) => boolean;
    stop: () => void;
    addTimeline: (timeline: ITimeline) => void;
    remTimeline: (timeline: ITimeline) => void;
    trySyncTickStatus: () => void;
    getTimelines: () => ITimeline[];
    release: () => void;
    autoStop: boolean;
}
