//


import { max2 } from "../../../math/max2.js";
import Quaternion from "../../Quaternion.js";
import Vector3 from "../../Vector3.js";
import { quat3_createFromAxisAngle } from "../quaternion/quat3_createFromAxisAngle.js";

const tangent = new Vector3();

const q = new Quaternion();

const a_n_0 = new Vector3();
const a_n_1 = new Vector3();
const b_n_0 = new Vector3();
const b_n_1 = new Vector3();

/**
 *
 * @param {ConicRay} result
 * @param {ConicRay} a
 * @param {ConicRay} b
 */
export function compute_bounding_cone_of_2_cones(result, a, b) {
    const directional_angular_distance = a.direction.angleTo(b.direction); //TODO this can be simplified, as angleTo uses dot product which we already have

    if (directional_angular_distance <= 0.0001) {
        // vectors point in the same direction
        result.direction.copy(a.direction);
        result.angle = max2(a.angle, b.angle);
        return;
    } else if (directional_angular_distance >= Math.PI - 0.0001) {
        // vectors point in opposite directions
        // this degenerates result to a sphere
        result.direction.copy(a.direction);
        result.angle = Math.PI;
        return;
    }

    const individual_angle_absolute_delta = Math.abs(a.angle - b.angle);

    if (directional_angular_distance <= individual_angle_absolute_delta) {
        // one cone is fully contained within another
        if (a.angle > b.angle) {
            result.copy(a);
        } else {
            result.copy(b);
        }
        return;
    }

    // compute normal vectors bounding each cone in the common plane
    tangent.crossVectors(a.direction, b.direction);

    const a_half_angle = a.angle;

    quat3_createFromAxisAngle(tangent, a_half_angle, q);
    a_n_0.copy(a.direction);
    a_n_0.applyQuaternion(q);

    quat3_createFromAxisAngle(tangent, -a_half_angle, q);
    a_n_1.copy(a.direction);
    a_n_1.applyQuaternion(q);

    const b_half_angle = b.angle;

    quat3_createFromAxisAngle(tangent, b_half_angle, q);
    b_n_0.copy(b.direction);
    b_n_0.applyQuaternion(q);

    quat3_createFromAxisAngle(tangent, -b_half_angle, q);
    b_n_1.copy(b.direction);
    b_n_1.applyQuaternion(q);

    // find which pair of normals is outer with respect to the newly formed cone
    let a_n_outer;
    if (a_n_0.dot(b.direction) > a_n_1.dot(b.direction)) {
        a_n_outer = a_n_1;
    } else {
        a_n_outer = a_n_0;
    }

    let b_n_outer;
    if (b_n_0.dot(a.direction) > b_n_1.dot(a.direction)) {
        b_n_outer = b_n_1;
    } else {
        b_n_outer = b_n_0;
    }

    result.angle = a_n_outer.angleTo(b_n_outer) / 2;
    result.direction.slerpVectors(a_n_outer, b_n_outer, 0.5);

}
