import { v3_dot } from "../../../vec3/v3_dot.js";
import { v3_length_sqr } from "../../../vec3/v3_length_sqr.js";
import { query_edge_other_vertex } from "../query/query_edge_other_vertex.js";
import { query_face_next_vertex } from "../query/query_face_next_vertex.js";
import { query_face_prev_vertex } from "../query/query_face_prev_vertex.js";

/**
 * @see https://github.com/blender/blender/blob/594f47ecd2d5367ca936cf6fc6ec8168c2b360d0/source/blender/bmesh/tools/bmesh_decimate_collapse.c#L164
 * @param {TopoEdge} edge
 * @param {TopoVertex} target
 * @returns {boolean}
 */
export function tm_edge_collapse_is_degenerate_flip(edge, target) {
    const victim = query_edge_other_vertex(edge, target);

    const victim_faces = victim.faces;
    const victim_face_count = victim_faces.length;

    for (let i = 0; i < victim_face_count; i++) {
        const face = victim_faces[i];

        // get a vertex that's next after victim vertex in order
        const next_vertex = query_face_next_vertex(face, victim);
        const prev_vertex = query_face_prev_vertex(face, victim);

        if (next_vertex === target || prev_vertex === target) {
            // face attached to collapsing edge, ignore
            continue;
        }

        const vo_x = prev_vertex.x - next_vertex.x;
        const vo_y = prev_vertex.y - next_vertex.y;
        const vo_z = prev_vertex.z - next_vertex.z;

        const vv_x = prev_vertex.x - victim.x;
        const vv_y = prev_vertex.y - victim.y;
        const vv_z = prev_vertex.z - victim.z;

        const vt_x = prev_vertex.x - target.x;
        const vt_y = prev_vertex.y - target.y;
        const vt_z = prev_vertex.z - target.z;

        // cross( other, victim )
        const vx_ov_x = vo_y * vv_z - vo_z * vv_y;
        const vx_ov_y = vo_z * vv_x - vo_x * vv_z;
        const vx_ov_z = vo_x * vv_y - vo_y * vv_x;

        // cross( other, target )
        const vx_ot_x = vo_y * vt_z - vo_z * vt_y;
        const vx_ot_y = vo_z * vt_x - vo_x * vt_z;
        const vx_ot_z = vo_x * vt_y - vo_y * vt_x;

        const dot = v3_dot(vx_ov_x, vx_ov_y, vx_ov_z, vx_ot_x, vx_ot_y, vx_ot_z);

        const squared_distance_sum = v3_length_sqr(vx_ov_x, vx_ov_y, vx_ov_z)
            + v3_length_sqr(vx_ot_x, vx_ot_y, vx_ot_z);

        if (dot <= squared_distance_sum * 0.000001) {
            return true;
        }

    }

    return false;
}
