// import { Mesh } from "three";
import { Constants } from "../Constants";
export class Utils {
    static addCssUnits(d) {
        if (!this.cssUnits.some(u => {
            return d.includes(u);
        })) {
            d += "px"; // default to px
        }
        return d;
    }
    static getFileExtension(file) {
        return file.substring(file.lastIndexOf(".") + 1);
    }
    static getFileEndCharacters(file, n) {
        return file.slice(file.length - n);
    }
    static getGeometryCenter(geometry) {
        let geom;
        if (geometry instanceof THREE.BufferGeometry) {
            geom = new THREE.Geometry().fromBufferGeometry(geometry);
        }
        else {
            geom = geometry;
        }
        geom.computeBoundingSphere();
        return geom.boundingSphere.center;
    }
    static getSceneDistanceFromMesh(mesh, zoomFactor, fov) {
        if (mesh) {
            const sphere = mesh.geometry.boundingSphere;
            return (zoomFactor * sphere.radius) / Math.tan((fov * Math.PI) / 180);
        }
        return null;
    }
    static getSceneDistanceFromModel(model, zoomFactor, fov) {
        if (model) {
            const box = Utils.getBoundingBox(model);
            const sphere = new THREE.Sphere();
            box.getBoundingSphere(sphere);
            return (zoomFactor * sphere.radius) / Math.tan((fov * Math.PI) / 180);
        }
        return null;
    }
    static getCameraStateFromMesh(mesh, sceneDistance) {
        if (mesh) {
            const geom = mesh.geometry;
            const meshCenter = this.getGeometryCenter(geom);
            const position = new THREE.Vector3();
            position.copy(meshCenter);
            position.z += sceneDistance;
            return {
                target: meshCenter,
                position
            };
        }
        return null;
    }
    static getCameraStateFromModel(model, sceneDistance) {
        if (model) {
            const box = Utils.getBoundingBox(model);
            const center = new THREE.Vector3();
            box.getCenter(center);
            const position = new THREE.Vector3();
            position.y = center.y;
            position.z += sceneDistance;
            return {
                target: center,
                position
            };
        }
        return null;
    }
    static getCameraPositionFromNode(node, radius, cameraTarget) {
        if (!node) {
            return null;
        }
        const pos = new THREE.Vector3();
        pos.copy(AFRAME.utils.coordinates.parse(node.position));
        // (Position -> Target)
        const dir = pos
            .clone()
            .sub(cameraTarget.clone())
            .normalize();
        const camPos = new THREE.Vector3();
        camPos.copy(pos);
        // Add {defaultZoom} intervals of dir to camPos
        camPos.add(dir.clone().multiplyScalar(radius * Constants.zoomFactor));
        return camPos;
    }
    static getNearFromSceneDistance(sceneDistance) {
        if (sceneDistance) {
            return sceneDistance * (1.0 - Constants.camera.nearFactor);
        }
        else {
            return null;
        }
    }
    static getFarFromSceneDistance(sceneDistance) {
        if (sceneDistance) {
            return sceneDistance * 100;
        }
        else {
            return null;
        }
    }
    static getBoundingBox(obj) {
        return new THREE.Box3().setFromObject(obj);
    }
    static normalise(num, min, max) {
        return (num - min) / (max - min);
    }
    static reverseNumber(num, min, max) {
        return max + min - num;
    }
}
Utils.cssUnits = [
    "%",
    "ch",
    "cm",
    "em",
    "ex",
    "in",
    "mm",
    "pc",
    "pt",
    "px",
    "rem",
    "vh",
    "vmax",
    "vmin",
    "vw"
];
