import * as THREE from 'three' //'/app/thirdparty/Three/three.module.js'

export class AgentPreview{

    constructor(canvasEl, agentSprites){
        Object.assign(this, app.helpers.helpers3D)
        this.agentSprites = app.Assets.Store.json.agentSprites
        this.canvasEl = canvasEl
        this.agentSprites = agentSprites
        this.currentAgentObj = null
        this.renderer = null
        this._animation = false
        this.initScene()
    }

    initScene(){
        // Scene
        this.scene = new THREE.Scene()

        // Camera
        this.camera = new THREE.PerspectiveCamera(75, this.canvasEl.clientWidth / this.canvasEl.clientHeight, 0.1, 1000)
        this.camera.position.set(3, 3, 5)
        this.camera.lookAt(0, 0, 0)
        this.camera.layers.enable(1)
        this.camera.layers.enable(2)

        // Lights
        const light = new THREE.DirectionalLight(0xffffff, 1)
        light.position.set(5, 5, 5)
        light.intensity = 2
        this.scene.add(light)
        this.scene.add(new THREE.AmbientLight(0xffffff, 0.4))

        this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl })
    }

    startRendering(){
        //this.renderer.addControls()       
        this.renderer.render(this.scene, this.camera)
    }

    setAgent(id){ 
        if(this.pivot && (this.scene.children.includes(this.pivot))){
            this.scene.remove(this.pivot)
        }
        const agentSprite = this.agentSprites.find(item => item.atp_id==id)       
        if(!agentSprite) return
        this.currentAgentObj = this.agentFromJSON('previewedAgent', agentSprite.asp_3d)
        
        this.pivot = this.makePivotAtGeomCenter(this.currentAgentObj, this.scene)
        this.cameraAutoFrame(this.pivot, this.camera, 1.5)

        // After creating the pivot, so axes do not unbalance the center, 
        // and after cameraFraming so axes we frame on the object, no matter the axes
        this.currentAgentObj.add(new THREE.AxesHelper(2))
    }

    set animation(value){
        this._animation = value
        if(value) this._animate()
    }

    get animation(){
        return(this._animation)
    }

    _animate = () => {  // to avoid having to bind(this) in requestAnimationFrame, because one bound fn per frame = continuous GC load
        requestAnimationFrame(this._animate)
        if(this.pivot && this.animation){
            this.pivot.rotation.x += 0.005
            this.pivot.rotation.y += 0.01
        }
        this.renderer.render(this.scene, this.camera)
    }
}

// Make this module available to common JS
if(!app.LoadedModules) app.LoadedModules = {}
app.LoadedModules.AgentPreview = AgentPreview

