# -*- coding: utf-8 -*-
"""Geometry utility functions for TopoFix.

Core computational geometry algorithms used by topology checks.

Scientific basis:
    Point-on-Segment test uses vector projection (dot product).
    t = dot(AP, AB) / dot(AB, AB)
    F = A + t * AB
    P lies on AB iff 0 < t < 1 AND |PF| < tolerance

Author: Loc Vu Trung tong hop vi dam me cung ban!
"""


def point_on_segment(px, py, ax, ay, bx, by, tolerance):
    """Check if point P lies on segment AB within tolerance.

    Uses vector projection to find the closest point F on line AB,
    then checks distance PF < tolerance and 0 < t < 1.

    Args:
        px, py: Coordinates of point P.
        ax, ay: Coordinates of segment start A.
        bx, by: Coordinates of segment end B.
        tolerance: Maximum distance for P to be on AB.

    Returns:
        Tuple (bool, float): (is_on_segment, parameter_t).
        t=0.0 means A, t=1.0 means B, t=0.5 means midpoint.
    """
    dx = bx - ax
    dy = by - ay
    len_sq = dx * dx + dy * dy

    if len_sq == 0:  # A coincides with B
        dist = ((px - ax) ** 2 + (py - ay) ** 2) ** 0.5
        return (dist < tolerance, 0.0)

    # Projection parameter: t = dot(AP, AB) / dot(AB, AB)
    t = ((px - ax) * dx + (py - ay) * dy) / len_sq

    # P must be strictly BETWEEN A and B (not at endpoints)
    if t <= 0.0 or t >= 1.0:
        return (False, t)

    # Foot of perpendicular F = A + t * AB
    fx = ax + t * dx
    fy = ay + t * dy

    # Distance from P to F
    dist = ((px - fx) ** 2 + (py - fy) ** 2) ** 0.5

    return (dist < tolerance, t)
