import { TextureLoader, Box3, Vector3, Group } from "three";

function assignParams(mesh, params){
    ['scale', 'rotation', 'position'].forEach(p=>params[p] && mesh[p].fromArray(params[p]));
    ['visible', 'name', 'fontSize', 'color', 'lineHeight', 'maxWidth', 'anchorX', 'anchorY'].forEach(p=>{
        if (params[p]!==undefined) mesh[p] = params[p];
    });
}

function assignMaterial(mesh, params){
    if (params.name && params.material){
        //let mp = params.material.metalness ? new MeshStandardMaterial(params.material) : new MeshBasicMaterial(params.material)
        Object.assign(mesh.material, params.material)
        if (params.dm){
            var dm = new TextureLoader().setPath(params.path).load(params.dm);
            mesh.material.map = dm;
        }
        if (params.nm){
            mesh.material.normalMap = new TextureLoader().setPath(params.path).load(params.nm);
        }
        if (params.em) {
            mesh.material.emissiveMap = new TextureLoader().setPath(params.path).load(params.em);
        }
        //mesh.material = mp;
        mesh.material.needsUpdate = true;
    }
}

function getBoundingBox(object){
    return new Box3().setFromObject(object);
}

function getBoundingBoxSize(bb){
    return new Vector3(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z);
}

function getBoundingBoxMaxLength(bb){
    let size = getBoundingBoxSize(bb)
    return Math.max(size.x, size.y, size.z)
}

function getBoundingBoxCenterPoint(bb, relativeTo){
    relativeTo = relativeTo || new Vector3(0,0,0)
    let size = getBoundingBoxSize(bb)
    return new Vector3(
        bb.min.x + (size.x)/2 - relativeTo.x, 
        bb.min.y + (size.y)/2 - relativeTo.y, 
        bb.min.z + (size.z)/2 - relativeTo.z
    )
}

function autoScale(object, mk = 1) {
    if (mk === null) return;
    let bb = getBoundingBox(object);
    let k = getBoundingBoxMaxLength(bb);
    object.scale.multiplyScalar(mk / k);
}

function wrapInGroup(object){
    if (object.isWrapper) return object;
    let group = new Group();
    group.userData.bbox = getBoundingBox(object);
    group.add(object);
    group.userData.object = object;
    group.isWrapper = true;
    return group;
}

function centerOrigin(object){
    let group = wrapInGroup(object);
    let position = getBoundingBoxCenterPoint(group.userData.bbox, object.position).negate();
    object.position.copy(position)
    return group;
}

function bottomOrigin(object){
    let group = centerOrigin(object);
    group.userData.object.position.y = -group.userData.bbox.min.y
    return group;
}

export { 
    assignParams, assignMaterial, autoScale, centerOrigin, wrapInGroup, bottomOrigin,
    getBoundingBox, getBoundingBoxSize, getBoundingBoxMaxLength, getBoundingBoxCenterPoint 
}