import { ITrackEntry } from 'pixi-spine';
import { MaskData, Rectangle } from 'pixi.js';
import { CanBeBlocked, CanBeBlurred, CanBeLanded, CanBeMasked, CanPlayBouncing, CanPlayIdle, CanPlayWin } from '../types/Entity';
import Symbol from './Symbol';

export default class ReelSymbol extends Symbol implements
  CanPlayIdle, CanPlayBouncing, CanBeBlocked, CanPlayWin, CanBeBlurred, CanBeLanded, CanBeMasked
{
    public isBlocked: boolean = false;
    public isLanded: boolean = false;
    public isBlurred: boolean = false;
    public blurEnabled: boolean = false;
    public isMasked: boolean = false;
    private filterAreaRect?: Rectangle;

    /**
     * Triggers the idle animation for the symbol and returns a function to check its progress.
     * @returns A function to check the animation progress.
     */
    public idle(): ITrackEntry
    {
        return this.spine.state.setAnimation(0, 'idle', false);
    }

    /**
     * Triggers the bounce animation and returns a function to check its progress.
     * @returns A function to check the animation progress.
     */
    public bounce(): ITrackEntry
    {
        return this.spine.state.setAnimation(0, 'bounce', false);
    }

    /**
     * Triggers the win animation and returns a function to check its progress.
     * @returns A function to check the animation progress.
     */
    public win(): ITrackEntry
    {
        return this.spine.state.setAnimation(0, 'win', false);
    }

    public anticipate()
    {
        return this.spine.state.setAnimation(0, 'anticipation', false);
    }

    /** Updates the blur clipping area to match the applied mask bounds. */
    private updateBlurClipping(): void
    {
        if (!this.blurEnabled || !this.isMasked)
        {
            this.filterArea = null;
            this.filterAreaRect = undefined;
            return;
        }

        const mask = this.mask;

        if (!mask || mask instanceof MaskData)
        {
            this.filterArea = null;
            return;
        }

        const maskBounds = mask.getBounds(true);

        if (!maskBounds.width || !maskBounds.height)
        {
            this.filterArea = null;
            return;
        }

        if (!this.filterAreaRect)
        {
            this.filterAreaRect = maskBounds.clone();
        }
        else
        {
            this.filterAreaRect.copyFrom(maskBounds);
        }

        this.filterArea = this.filterAreaRect;
    }

    /** @inheritdoc */
    public override update(dt: number): void
    {
        super.update(dt);
        this.updateBlurClipping();
    }
}
