# Author:  mozman
# Purpose: convex hull algorithm
# Created: 28.02.2010
# License: MIT License
from typing import TYPE_CHECKING, Iterable, List
from ezdxf.math.construct2d import left_of_line

if TYPE_CHECKING:
    from ezdxf.eztypes import Vertex


def convex_hull_2d(points: Iterable['Vertex'])->List['Vertex']:
    def _convexhull(hull):
        while len(hull) > 2:
            start_point, check_point, destination_point = hull[-3:]  # the last three points
            if not left_of_line(check_point, start_point, destination_point):  # curve not turns right
                del hull[-2]  # remove the penultimate point
            else:
                break
        return hull

    points = sorted(set(points))  # remove duplicate points

    if len(points) < 3:
        raise ValueError("ConvexHull(): Less than 3 unique points given!")

    upper_hull = points[:2]  # first two points
    for next_point in points[2:]:
        upper_hull.append(next_point)
        upper_hull = _convexhull(upper_hull)
    lower_hull = [points[-1], points[-2]]  # last two points

    for next_point in reversed(points[:-2]):
        lower_hull.append(next_point)
        lower_hull = _convexhull(lower_hull)
    upper_hull.extend(lower_hull[1:-1])
    return upper_hull
