import * as THREE from 'three';
import '../../chipper/js/browser/initialize-globals.js';
import '../../globals.js';
import Vector3 from '../../dot/js/Vector3.js';
import asyncLoader from '../../phet-core/js/asyncLoader.js';
import { Utils } from '../../scenery/js/imports.js';
import mobius from './mobius.js';
// {THREE.TextureLoader|null} - "singleton" for the texture loader
let textureLoader = null;
const scratchFloatArray = new Float32Array(128);
const ThreeUtils = {
    /**
     * Converts a Vector3 to a THREE.Vector3
     */
    vectorToThree(vector) {
        return new THREE.Vector3(vector.x, vector.y, vector.z);
    },
    /**
     * Converts a THREE.Vector3 to a Vector3
     */
    threeToVector(vector) {
        return new Vector3(vector.x, vector.y, vector.z);
    },
    /**
     * Converts a Color to a THREE.Color
     */
    colorToThree(color) {
        return new THREE.Color(color.toNumber());
    },
    /**
     * Returns an array of [ x, y, z, ... ] vertices for a quad pointed towards the camera.
     *
     * @param bounds2 - x,y
     * @param z
     */
    frontVertices(bounds2, z) {
        return scratchFloatArray.slice(0, ThreeUtils.writeFrontVertices(scratchFloatArray, 0, bounds2, z));
    },
    /**
     * Returns an array of [ x, y, z, ... ] vertices for a quad pointed up.
     *
     * @param bounds2 - x,z
     * @param y
     */
    topVertices(bounds2, y) {
        return scratchFloatArray.slice(0, ThreeUtils.writeTopVertices(scratchFloatArray, 0, bounds2, y));
    },
    /**
     * Returns an array of [ x, y, z, ... ] vertices for a quad pointed towards the right.
     *
     * @param bounds2 - z,y
     * @param x
     */
    rightVertices(bounds2, x) {
        return scratchFloatArray.slice(0, ThreeUtils.writeRightVertices(scratchFloatArray, 0, bounds2, x));
    },
    /**
     * Returns an array of [ x, y, z, ... ] vertices for a quad pointed towards the left.
     *
     * @param Bounds2 bounds2 - z,y
     * @param number x
     */
    leftVertices(bounds2, x) {
        return scratchFloatArray.slice(0, ThreeUtils.writeLeftVertices(scratchFloatArray, 0, bounds2, x));
    },
    /**
     * Writes a single triangle into a buffer, returning the new index location. Assumes vertices in counterclockwise
     * order.
     *
     * Writes 9 entries into the array.
     *
     * @returns - The index for the next write
     */
    writeTriangle(array, index, x0, y0, z0, x1, y1, z1, x2, y2, z2) {
        array[index + 0] = x0;
        array[index + 1] = y0;
        array[index + 2] = z0;
        array[index + 3] = x1;
        array[index + 4] = y1;
        array[index + 5] = z1;
        array[index + 6] = x2;
        array[index + 7] = y2;
        array[index + 8] = z2;
        return index + 9;
    },
    /**
     * Writes a single quad into a buffer, returning the new index location. Assumes verties in counterclockwise order.
     *
     * Writes 18 entries into the array.
     *
     * @returns - The index for the next write
     */
    writeQuad(array, index, x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3) {
        index = ThreeUtils.writeTriangle(array, index, x0, y0, z0, x1, y1, z1, x2, y2, z2);
        index = ThreeUtils.writeTriangle(array, index, x0, y0, z0, x2, y2, z2, x3, y3, z3);
        return index;
    },
    /**
     * Writes a single front-facing quad into a buffer, returning the new index location. Assumes verties in
     * counterclockwise order.
     *
     * Writes 18 entries into the array.
     *
     * @returns - The index for the next write
     */
    writeFrontVertices(array, index, bounds2, z) {
        return ThreeUtils.writeQuad(array, index, bounds2.minX, bounds2.maxY, z, bounds2.minX, bounds2.minY, z, bounds2.maxX, bounds2.minY, z, bounds2.maxX, bounds2.maxY, z);
    },
    /**
     * Writes a single up-facing quad into a buffer, returning the new index location. Assumes verties in
     * counterclockwise order.
     *
     * Writes 18 entries into the array.
     *
     * @param array
     * @param index
     * @param bounds2 - x,z
     * @param y
     * @returns - The index for the next write
     */
    writeTopVertices(array, index, bounds2, y) {
        return ThreeUtils.writeQuad(array, index, bounds2.minX, y, bounds2.maxY, bounds2.maxX, y, bounds2.maxY, bounds2.maxX, y, bounds2.minY, bounds2.minX, y, bounds2.minY);
    },
    /**
     * Writes a single right-facing quad into a buffer, returning the new index location. Assumes verties in
     * counterclockwise order.
     *
     * Writes 18 entries into the array.
     *
     * @param array
     * @param index
     * @param bounds2 - z,y
     * @param x
     * @returns - The index for the next write
     */
    writeRightVertices(array, index, bounds2, x) {
        return ThreeUtils.writeQuad(array, index, x, bounds2.minY, bounds2.maxX, x, bounds2.minY, bounds2.minX, x, bounds2.maxY, bounds2.minX, x, bounds2.maxY, bounds2.maxX);
    },
    /**
     * Writes a single left-facing quad into a buffer, returning the new index location. Assumes verties in
     * counterclockwise order.
     *
     * Writes 18 entries into the array.
     *
     * @param array
     * @param index
     * @param bounds2 - z,y
     * @param x
     * @returns - The index for the next write
     */
    writeLeftVertices(array, index, bounds2, x) {
        return ThreeUtils.writeQuad(array, index, x, bounds2.minY, bounds2.maxX, x, bounds2.maxY, bounds2.maxX, x, bounds2.maxY, bounds2.minX, x, bounds2.minY, bounds2.minX);
    },
    /**
     * Returns a THREE.TextureLoader instance (using a singleton so we don't create more than we need).
     */
    get textureLoader() {
        if (!textureLoader) {
            textureLoader = new THREE.TextureLoader();
        }
        return textureLoader;
    },
    /**
     * Returns a THREE.Texture for a given HTMLImageElement.
     */
    imageToTexture(image, waitForLoad) {
        if (waitForLoad) {
            return ThreeUtils.textureLoader.load(image.src, asyncLoader.createLock());
        }
        else {
            return ThreeUtils.textureLoader.load(image.src);
        }
    },
    /**
     * Checks if webgl is enabled by the browser.
     */
    isWebGLEnabled() {
        return phet.chipper.queryParameters.webgl && Utils.isWebGLSupported;
    }
};
mobius.register('ThreeUtils', ThreeUtils);
export default ThreeUtils;
//# sourceMappingURL=ThreeUtils.js.map