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

if(!app.helpers) app.helpers = {}
/**
 * Mixing add-in methods to your view instance.
 * All of this should not be a helper, but inherited this from WindozDomContent, but not my framework anymore.
 */
app.helpers.helpers3D = {

    agentFromJSON(id, desc){ 
        let obj
        if(desc.type === 'Mesh') {
            const geom = new THREE[desc.geometry.type](...(desc.geometry.args || []))

            const matType = desc.material.type
            const matProps = { ...desc.material }
            for (const key in matProps) {
                if (key === 'type') continue
                if (typeof matProps[key] === 'string' && THREE[matProps[key]] !== undefined) {
                    matProps[key] = THREE[matProps[key]]
                }
            }
            // convert color strings like "0xffffaa" to numbers
            if (typeof matProps.color === 'string' && matProps.color.startsWith('0x')) {
                matProps.color = parseInt(matProps.color)
            }
            const mat = new THREE[matType](matProps)

            obj = new THREE.Mesh(geom, mat)
        } else if(desc.type === 'Group') {
            obj = new THREE.Group()
        } else {
            throw new Error("Unknown type: " + desc.type)
        }
        
        // Apply transforms
        if(desc.position) obj.position.set(...desc.position)
        if(desc.rotation) obj.rotation.set(...desc.rotation)
        if(desc.scale) obj.scale.set(...desc.scale)
                    
        // Recursively add children
        if(desc.children) {
            desc.children.forEach(childDesc => {
                const childId = (childDesc.childSuffix) ? `${id}_${childDesc.childSuffix}` : ''
                obj.add(this.agentFromJSON(childId, childDesc))
            })
        }
        obj.name = id
        return obj
    },

    cameraAutoFrame(object, camera, offset = 1.5, controls) {
        const box = new THREE.Box3().setFromObject(object)
        const size = new THREE.Vector3()
        const center = new THREE.Vector3()
        box.getSize(size)
        box.getCenter(center)
        
        const maxDim = Math.max(size.x, size.y, size.z)
        const fov = camera.fov * Math.PI / 180
        let cameraZ = maxDim / (2 * Math.tan(fov / 2)) * offset
        
        camera.position.copy(center)
        camera.position.z += cameraZ
        camera.lookAt(center)
        
        if (controls) {
            controls.target.copy(center)
            controls.update()
        }
    }

}