import BaseMachine from '../slotMachines/BaseMachine';
import { CanBeTinted, Entity } from '../types/Entity';
import BaseSystem from './BaseSystem';

/** Configuration settings for the tinting symbols behavior */
export interface TintingSymbolsSystemSettings
{
    color: number
}

export type TintingSymbolsSystemCompatibleEntity = Entity & CanBeTinted;

/** The system is responsible for tinting symbols on the screen It uses "tinting" to handle tinting state. */

export default class TintingSymbolsSystem extends BaseSystem<TintingSymbolsSystemSettings>
{
    static defaultSettings: TintingSymbolsSystemSettings = {
        color: 0x666666,
    };

    static override requiredFlags: string[] = [];
    static override requiredMaps: string[] = ['tinting', 'symbols'];
    static override requiredInputs: string[] = [];
    static override requiredMethods: string[] = [];
    static override requiredUtils: string[] = ['grid'];
    static override sharedSystemData: string[] = [];

    public state: string = 'stopped';

    constructor(machine: BaseMachine)
    {
        super(machine);
        this.setSettings(TintingSymbolsSystem.defaultSettings);
        this.initTintingMap();
    }

    onEnter(): void
    {
        // Do nothing
    }

    onLeave(): void
    {
        // Do nothing
    }

    update(_dt: number): void
    {
        this.machine.maps.tinting.forEach((tintState: boolean, i: number) =>
        {
            this.handleStateChanging(i, tintState);
        });
    }

    private handleStateChanging(symbolMapIndex: number, state: boolean)
    {
        const entityID = this.machine.maps.symbols[symbolMapIndex];

        if (!entityID) return;
        const entity: TintingSymbolsSystemCompatibleEntity = this.machine.getChildByName(entityID);

        if (!entity) return;
        const color = state ? this.settings.color : 0xffffff;

        entity.tint(color);
    }

    private initTintingMap(): void
    {
        this.machine.maps.tinting = this.createMap();
    }

    private createMap(): boolean[]
    {
        const { reels, slots } = this.machine.config;

        return new Array(slots * reels).fill(false);
    }
}
