import { EventManager } from '@/lib/EventManager';

class GenericObject extends EventManager{
    emits = ['finish', 'interaction']
    #actions = [];
    constructor(engine, data){
        super();
        if (!data.description || data.exclude){
            this.maxPoints = 0;
        }
        return new Promise(async(resolve, reject)=>{
            this.source = await engine.load(data.$go.asset.name);
            this.object = engine.meshUtils.bottomOrigin(this.source.scene)

            if (data.asIndividuals){
                this.object.hasIndividualChildren = true;
                this.source.scene.traverse(o=>{
                    if (o.isMesh){
                        o.isIndividual = true;
                    }
                })
            }

            if (this.source?.animations?.length){
                let mix = this.source.animations.filter(a=>a.name.match(/\.mix/));
                if (!mix.length) mix = [this.source.animations[0]];
                mix.forEach(m=>{
                    this.#actions.push(engine.playAnimation(this.object, m));
                })
            }

            if (!data.exclude && (data.hud || data.description)){
                engine.clickable.add(this.object, async e=>{
                    if (engine.dashboard){
                        if (data.hud){
                            this.object.__onhud = !this.object.__onhud;
                            const filterNoHud = a=>a.getClip().name.match(/\.nohud/)
                            if (this.object._hud ){
                                this.#actions.filter(filterNoHud).forEach(a=>a.play());
                                engine.dashboard.detach(this.object);
                            }else{
                                this.#actions.filter(filterNoHud).forEach(a=>a.stop());
                                let bb = engine.meshUtils.getBoundingBox(this.object);
                                let scale = 0.5 * engine.dashboard.height/engine.meshUtils.getBoundingBoxMaxLength(bb);
                                let position = engine.meshUtils.getBoundingBoxCenterPoint(bb, this.object.position).multiplyScalar(scale).negate()
                                
                                let placement = {
                                    quaternion: { x:0, y:0, z:0, w:0 },
                                    position,
                                    scale: { 
                                        x: scale*this.object.scale.x, 
                                        y: scale*this.object.scale.y, 
                                        z: scale*this.object.scale.z
                                    }
                                }
                                await engine.dashboard.attach(this.object, {
                                    placement, rotate: true, plane: true
                                });
                            }
                        }
                        if (data.description){
                            engine.dashboard.updateText((!data.hud || this.object.__onhud) ? data.description : '', {
                                textScrolledCallback: (d)=>{
                                    d && this.dispatchEvent({type:'finish'})
                                },
                                hideOnFinish: true
                            })
                        }
                    }
                    this.dispatchEvent({type:'interaction'})
                });
            }

            resolve(this);
        })
    }
}

export {GenericObject}