import { eventsBetween } from "./AnimationEvents.js";
export class AnimationAction {
    clip;
    time = 0;
    weight = 1;
    timeScale = 1;
    loopMode = "repeat";
    playing = false;
    paused = false;
    pingPongForward = true;
    fadeDuration = 0;
    fadeElapsed = 0;
    fadeStartWeight = 1;
    fadeTargetWeight = 1;
    constructor(clip) {
        this.clip = clip;
    }
    play() {
        this.playing = true;
        this.paused = false;
        return this;
    }
    pause() {
        this.paused = true;
        return this;
    }
    stop() {
        this.playing = false;
        this.paused = false;
        this.time = 0;
        return this;
    }
    setWeight(weight) {
        if (!Number.isFinite(weight) || weight < 0) {
            throw new Error("AnimationAction weight must be finite and non-negative.");
        }
        this.weight = weight;
        return this;
    }
    setTimeScale(timeScale) {
        if (!Number.isFinite(timeScale) || timeScale < 0) {
            throw new Error("AnimationAction timeScale must be finite and non-negative.");
        }
        this.timeScale = timeScale;
        return this;
    }
    setLoop(loopMode) {
        this.loopMode = loopMode;
        return this;
    }
    reset() {
        this.time = 0;
        this.pingPongForward = true;
        return this;
    }
    seek(time) {
        if (!Number.isFinite(time) || time < 0) {
            throw new Error("AnimationAction seek time must be finite and non-negative.");
        }
        this.time = this.clip.duration > 0 ? Math.min(time, this.clip.duration) : 0;
        return this;
    }
    fadeTo(weight, duration) {
        if (!Number.isFinite(duration) || duration < 0 || !Number.isFinite(weight) || weight < 0) {
            throw new Error("AnimationAction fade target and duration must be valid.");
        }
        this.fadeStartWeight = this.weight;
        this.fadeTargetWeight = weight;
        this.fadeDuration = duration;
        this.fadeElapsed = 0;
        if (duration === 0) {
            this.weight = weight;
        }
        return this;
    }
    update(delta) {
        if (!Number.isFinite(delta) || delta < 0) {
            throw new Error("AnimationAction delta must be finite and non-negative.");
        }
        if (this.fadeDuration > 0) {
            this.fadeElapsed = Math.min(this.fadeDuration, this.fadeElapsed + delta);
            const t = this.fadeElapsed / this.fadeDuration;
            this.weight = this.fadeStartWeight + (this.fadeTargetWeight - this.fadeStartWeight) * t;
            if (this.fadeElapsed === this.fadeDuration) {
                this.fadeDuration = 0;
            }
        }
        if (!this.playing || this.paused || this.clip.duration === 0) {
            return [];
        }
        const previous = this.time;
        const scaledDelta = delta * this.timeScale;
        let next = previous + scaledDelta;
        let looped = false;
        if (this.loopMode === "repeat") {
            while (next > this.clip.duration) {
                next -= this.clip.duration;
                looped = true;
            }
        }
        else if (this.loopMode === "once") {
            next = Math.min(next, this.clip.duration);
            if (next === this.clip.duration) {
                this.playing = false;
            }
        }
        else {
            if (this.pingPongForward) {
                while (next > this.clip.duration) {
                    next = this.clip.duration - (next - this.clip.duration);
                    this.pingPongForward = false;
                    looped = true;
                }
            }
            else {
                next = previous - scaledDelta;
                while (next < 0) {
                    next = -next;
                    this.pingPongForward = true;
                    looped = true;
                }
            }
        }
        this.time = next;
        if (this.clip.events.length === 0) {
            return [];
        }
        return eventsBetween(this.clip.events, this.clip.name, previous, next, this.clip.duration, looped);
    }
    snapshot() {
        return {
            clipName: this.clip.name,
            duration: this.clip.duration,
            time: this.time,
            weight: this.weight,
            timeScale: this.timeScale,
            playing: this.playing,
            paused: this.paused,
            loopMode: this.loopMode
        };
    }
}
//# sourceMappingURL=AnimationAction.js.map