import Frame from "./frame.js";
import { BirdType } from "./sprites.js";

class Anim {
	/**
	 * @param {Frame[]} frames
	 * @param {number[]} durations
	 * @param {boolean} loop
	 */
	constructor(frames, durations, loop = true) {
		this.frames = frames;
		this.durations = durations;
		this.loop = loop;
		this.lastFrameIndex = -1;
		this.lastDirection = null;
		this.lastTimeStart = null;
	}

	getAnimationDuration() {
		return this.durations.reduce((a, b) => a + b, 0);
	}

	/**
	 * Get the current frame index based on elapsed time
	 * @param {number} time The elapsed time since animation start
	 * @returns {number} The index of the current frame
	 */
	getCurrentFrameIndex(time) {
		let totalDuration = 0;
		for (let i = 0; i < this.durations.length; i++) {
			totalDuration += this.durations[i];
			if (time < totalDuration) {
				return i;
			}
		}
		return this.frames.length - 1;
	}

	/**
	 * Clear the cached frame state
	 */
	#clearCache() {
		this.lastFrameIndex = -1;
		this.lastDirection = null;
	}

	/**
	 * Check if the frame needs to be redrawn
	 * @param {number} frameIndex The current frame index
	 * @param {number} direction The current direction
	 * @returns {boolean} Whether the frame needs to be redrawn
	 */
	#shouldRedraw(frameIndex, direction) {
		return frameIndex !== this.lastFrameIndex || direction !== this.lastDirection;
	}

	/**
	 * @param {CanvasRenderingContext2D} ctx
	 * @param {number} direction
	 * @param {number} timeStart The start time of the animation in milliseconds
	 * @param {number} canvasPixelSize The size of a canvas pixel in pixels
	 * @param {{ [key: string]: string }} colorScheme The color scheme to use for the animation
	 * @param {string[]} tags The tags to use for the animation
	 * @returns {boolean} Whether the animation is complete
	 */
	draw(ctx, direction, timeStart, canvasPixelSize, colorScheme, tags) {
		// Reset cache if animation was restarted
		if (this.lastTimeStart !== timeStart) {
			this.#clearCache();
			this.lastTimeStart = timeStart;
		}

		let time = Date.now() - timeStart;
		const duration = this.getAnimationDuration();
		
		if (this.loop) {
			time %= duration;
		}

		const currentFrameIndex = this.getCurrentFrameIndex(time);
		
		if (this.#shouldRedraw(currentFrameIndex, direction)) {
			this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, colorScheme, tags);
			this.lastFrameIndex = currentFrameIndex;
			this.lastDirection = direction;
		}
		
		// Return whether animation is complete (for non-looping animations)
		return !this.loop && time >= duration;
	}
}

export default Anim;