from __future__ import annotations

from typing import Any, Tuple

from scitbx.array_family import flex

from .dxtbx_model_ext import BeamBase, Detector, MultiAxisGoniometer, Panel

def is_inside_polygon(polygon: flex.vec2_double, x: float, y: float) -> bool: ...
def mask_untrusted_rectangle(
    mask: flex.bool, x0: int, x1: int, y0: int, y1: int
) -> None: ...
def mask_untrusted_circle(
    mask: flex.bool, xc: float, yc: float, radius: float
) -> None: ...
def mask_untrusted_polygon(mask: flex.bool, polygon: flex.vec2_double) -> None: ...
def mask_untrusted_resolution_range(
    mask: flex.bool, beam: BeamBase, panel: Panel, d_min: float, d_max: float
) -> None: ...

class GoniometerShadowMasker:
    def __init__(
        self,
        goniometer: MultiAxisGoniometer,
        extrama_at_datum: flex.vec3_double,
        axis: flex.size_t,
        invert_mask: bool = False,
    ) -> None: ...
    def extrema_at_scan_angle(self, scan_angle: float) -> flex.vec3_double: ...
    def set_goniometer_angles(dxtbx, scitbx) -> Any: ...
    def project_extrema(
        self, detector: Detector, scan_angle: float
    ) -> flex.vec2_double: ...
    def get_mask(self, detector: Detector, scan_angle: float) -> Tuple[flex.bool]: ...

class SmarGonShadowMasker(GoniometerShadowMasker):
    def __init__(self, goniometer: MultiAxisGoniometer) -> None: ...
    def extrema_at_scan_angle(self, scan_angle: float) -> flex.vec3_double: ...
