/** @internal NOTE: Internal APIs. Subject to change. Use of these APIs in production applications is not supported. */ /** */

import { Vector3, Scene, Mesh, DynamicTexture, StandardMaterial, Color3 } from './babylonjs-import';
import { TransformNode, MeshBuilder } from './babylonjs-import';

export function createAxis(
    name: string,
    pos: Vector3,
    size: number,
    scene: Scene,
    options: {
        axisArrows?: boolean;
        axisText?: boolean;
        lineSize?: number;
    } = {}
): TransformNode {
    const worldAxis = new TransformNode(name, scene);
    worldAxis.position = pos;
    pos = Vector3.Zero();

    function makeTextPlane(text: string, color: string, size: number): Mesh {
        const dynamicTexture = new DynamicTexture(name + ':DynamicTexture', 50, scene, true);
        dynamicTexture.hasAlpha = true;
        dynamicTexture.drawText(text, 5, 40, 'bold 36px Arial', color, 'transparent', true);
        const plane = MeshBuilder.CreatePlane(name + ':TextPlane', { size }, scene);
        plane.billboardMode = 7;
        plane.parent = worldAxis;
        const m = new StandardMaterial(name + ':TextPlaneMaterial', scene);
        plane.material = m;
        m.backFaceCulling = false;
        m.specularColor = new Color3(0, 0, 0);
        m.diffuseTexture = dynamicTexture;
        m.disableDepthWrite = true;
        return plane;
    }
    let points = [pos, pos.add(new Vector3(size, 0, 0))];
    if (options?.axisArrows) {
        points.push(
            ...[
                pos.add(new Vector3(size * 0.95, 0.05 * size, 0)),
                pos.add(new Vector3(size, 0, 0)),
                pos.add(new Vector3(size * 0.95, -0.05 * size, 0))
            ]
        );
    }

    const axisX = MeshBuilder.CreateLines(name + ':axisX', { points }, scene);

    axisX.parent = worldAxis;
    axisX.color.set(1, 0, 0);

    if (options?.axisText) {
        const xChar = makeTextPlane('X', 'red', size / 10);
        xChar.position = pos.add(new Vector3(0.9 * size, -0.05 * size, 0));
    }

    points = [pos, pos.add(new Vector3(0, size, 0))];
    if (options.axisArrows) {
        points.push(
            ...[
                pos.add(new Vector3(-0.05 * size, size * 0.95, 0)),
                pos.add(new Vector3(0, size, 0)),
                pos.add(new Vector3(0.05 * size, size * 0.95, 0))
            ]
        );
    }
    const axisY = MeshBuilder.CreateLines(name + ':axisY', { points }, scene);
    axisY.parent = worldAxis;
    axisY.color.set(0, 1, 0);

    if (options.axisText) {
        const yChar = makeTextPlane('Y', 'green', size / 10);
        yChar.position = pos.add(new Vector3(0, 0.9 * size, -0.05 * size));
    }
    points = [pos, pos.add(new Vector3(0, 0, size))];
    if (options.axisArrows) {
        points.push(
            ...[
                pos.add(new Vector3(0, -0.05 * size, size * 0.95)),
                pos.add(new Vector3(0, 0, size)),
                pos.add(new Vector3(0, 0.05 * size, size * 0.95))
            ]
        );
    }
    const axisZ = MeshBuilder.CreateLines(name + ':axisZ', { points }, scene);
    axisZ.parent = worldAxis;
    axisZ.color.set(0, 0, 1);

    if (options.axisText) {
        const zChar = makeTextPlane('Z', 'blue', size / 10);
        zChar.position = pos.add(new Vector3(0, 0.05 * size, 0.9 * size));
    }
    return worldAxis;
}
