import { is } from '@pilotlab/is';
import Debug from '@pilotlab/debug';
import ActivatableBase from './activatableBase';


export class ActivatableCollection<TActivationTarget, TActivatable extends ActivatableBase<any>> {
    constructor(target?:TActivationTarget, isActivateOnAdd:boolean = true) {
        if (is.notEmpty(target)) this.p_target = target;
        this.p_isActivateOnAdd = isActivateOnAdd;
    }


    protected p_collectionName:string = 'activatable'; // Used for debugging
    protected p_map:Map<string, TActivatable> = new Map<string, TActivatable>();


    get target():TActivationTarget { return this.p_target; }
    set target(value:TActivationTarget) { this.p_target = value; }
    protected p_target:TActivationTarget;


    get isActivateOnAdd():boolean { return this.p_isActivateOnAdd; }
    set isActivateOnAdd(value:boolean) { this.p_isActivateOnAdd = value; }
    protected p_isActivateOnAdd:boolean = true;


    add(value:TActivatable):void {
        //----- Don't add the same value twice.
        if (this.p_map.has(value.name)) return;

        if (this.p_isActivateOnAdd) value.activate(this.p_target);
        this.p_map.set(value.name, value);
    }


    get(name:string):TActivatable { return this.p_map.get(name); }


    remove(name:string):void {
        let value:TActivatable = this.p_map.get(name);
        if (is.notEmpty(value)) value.deactivate();
        this.p_map.delete(name);
    }


    clear():void { this.p_map.clear(); }


    forEach(callback:(key:string, value:TActivatable) => boolean):void {
        this.p_map.forEach((value2:TActivatable, key2:string):boolean => {
            return callback(key2, value2);
        });
    }


    activateAll(...args:any[]):void {
        this.p_isActivateOnAdd = true;
        this.p_map.forEach((value:TActivatable, key:string):boolean => {
            value.activate(this.p_target, ...args);
            return true;
        });
    }


    deactivateAll(...args:any[]):void {
        this.p_isActivateOnAdd = false;
        this.p_map.forEach((value:TActivatable, key:string):boolean => {
            value.deactivate(...args);
            return true;
        });
    }


    log():void {
        Debug.log(this.p_collectionName + ':');
        this.p_map.forEach((value:TActivatable, key:string):boolean => {
            Debug.log('    ' + key);
            return true;
        });
    }
} // End class


export default ActivatableCollection;
