/**
 *  http://stackoverflow.com/questions/3106666/intersection-of-line-segment-with-axis-aligned-box-in-c-sharp
 * @param {number} x0
 * @param {number} y0
 * @param {number} z0
 * @param {number} x1
 * @param {number} y1
 * @param {number} z1
 * @param {number} startX
 * @param {number} startY
 * @param {number} startZ
 * @param {number} endX
 * @param {number} endY
 * @param {number} endZ
 * @returns {boolean}
 */
function aabb3_intersects_line_segment(
    x0, y0, z0,
    x1, y1, z1,
    startX, startY, startZ,
    endX, endY, endZ
) {

    let boxExtentsX,
        boxExtentsY,
        boxExtentsZ,
        diffX,
        diffY,
        diffZ,
        dirX,
        dirY,
        dirZ,
        centerX,
        centerY,
        centerZ;
    //
    let a, b, c;

    dirX = 0.5 * (endX - startX);
    boxExtentsX = (x1 - x0) / 2;
    centerX = x0 + boxExtentsX;
    diffX = (0.5 * (endX + startX)) - centerX;
    a = Math.abs(dirX);
    if (Math.abs(diffX) > boxExtentsX + a) return false;
    //
    dirY = 0.5 * (endY - startY);
    boxExtentsY = (y1 - y0) / 2;
    centerY = y0 + boxExtentsY;
    diffY = (0.5 * (endY + startY)) - centerY;
    b = Math.abs(dirY);
    if (Math.abs(diffY) > boxExtentsY + b) return false;
    //
    dirZ = 0.5 * (endZ - startZ);
    boxExtentsZ = (z1 - z0) / 2;
    centerZ = z0 + boxExtentsZ;
    diffZ = (0.5 * (endZ + startZ)) - centerZ;
    c = Math.abs(dirZ);
    if (Math.abs(diffZ) > boxExtentsZ + c) return false;

    //Dir.y = 0.5f * (segment.mP1.y - segment.mP0.y);
    //BoxExtents.y = aabb.GetExtents(1);
    //Diff.y = (0.5f * (segment.mP1.y + segment.mP0.y)) - aabb.GetCenter(1);
    //b = fabsf(Dir.y);
    //if(fabsf(Diff.y)>BoxExtents.y + b)	return false;

    let f;
    f = dirY * diffZ - dirZ * diffY;
    if (Math.abs(f) > boxExtentsY * c + boxExtentsZ * b) return false;
    f = dirZ * diffX - dirX * diffZ;
    if (Math.abs(f) > boxExtentsX * c + boxExtentsZ * a) return false;
    f = dirX * diffY - dirY * diffX;
    if (Math.abs(f) > boxExtentsX * b + boxExtentsY * a) return false;

    return true;
}

export { aabb3_intersects_line_segment };
