import { AnimationMixer } from 'three';
import { PointerControls } from './PointerControls';
import { CharacterControls } from './CharacterControls';
import * as THREE from 'three';
import { getBoundingBox, getBoundingBoxCenterPoint, getBoundingBoxSize } from './MeshUtils';

class Hero{

    constructor(object, data){
        this.object = object;
        this.data = data;
        this.model = object.scene
    }

    init(gameEngine){
        this.gameEngine = gameEngine;
        gameEngine.camera.position.set(0,17,-30)
        gameEngine.camera.lookAt(new THREE.Vector3(this.model.position.x, 5, this.model.position.z))

        this.mixer = new AnimationMixer(this.model);
        gameEngine.mixers.push( this.mixer );

        this.animationsMap = {};
        this.object.animations.forEach(a=>{
            this.animationsMap[a.name] = this.mixer.clipAction(a);
        })  

        this.pointerControls = new PointerControls(gameEngine.camera, this.model, gameEngine.renderer.domElement);
        gameEngine.hero = this;

        let bb = getBoundingBox(this.model);
        let size = getBoundingBoxSize(bb);
        let center = getBoundingBoxCenterPoint(bb, this.model.position)

        let po = gameEngine.physics.add(this.model, 'kinematicPositionBased', false, undefined, 'capsule', { radius: size.x/2, halfHeight: size.y/2})
        po.collider.setTranslationWrtParent({x: center.x, y: center.y + size.y/2, z: center.z});
        //po.collider.setActiveEvents(RAPIER.ActiveEvents.COLLISION_EVENTS);

        this.characterControls = new CharacterControls(this.model, 
            this.animationsMap, gameEngine, 'idle', po, this.pointerControls)

        this.clock = new THREE.Clock()
        this.delta = 0

        this.ready = true;
    }

    lockControls(){
        this.pointerControls.controls.lock();
    }

    update(){
        if (this.gameEngine.renderer.xr.isPresenting) return;
        
        if (this.ready && !this.disableInput) {
            let pc = this.pointerControls;
            pc.update();
            let dlt = this.clock.getDelta();
            this.delta += dlt;
            //if (this.delta > 0.00001){
                this.characterControls.update(this.gameEngine.physics.world, this.delta, pc)
                this.gameEngine.physics.step()
                this.delta = 0;
            //}
        }
    }

    destroy(){
        delete this.gameEngine.hero;
        this.gameEngine.mixers.splice(this.gameEngine.mixers.indexOf(this.mixer), 1);
    }

}

export { Hero }