from typing import ClassVar

import numpy as np
from numpy.typing import ArrayLike, NDArray

from ._util import arg_to_vec4
from .base_transform import BaseTransform

class NullTransform(BaseTransform):
    glsl_map: ClassVar[str]
    glsl_imap: ClassVar[str]

    Linear: bool = ...
    Orthogonal: bool = ...
    NonScaling: bool = ...
    Isometric: bool = ...

    @arg_to_vec4
    def map(self, coords: ArrayLike): ...
    def imap(self, coords: ArrayLike): ...
    def __mul__(self, tr): ...
    def __rmul__(self, tr): ...

class STTransform(BaseTransform):
    glsl_map: ClassVar[str]

    glsl_imap: ClassVar[str]

    Linear: bool = ...
    Orthogonal: bool = ...
    NonScaling: bool = ...
    Isometric: bool = ...

    def __init__(self, scale: ArrayLike | None = None, translate: ArrayLike | None = None): ...
    @arg_to_vec4
    def map(self, coords: ArrayLike) -> NDArray: ...
    @arg_to_vec4
    def imap(self, coords: ArrayLike) -> NDArray: ...
    def shader_map(self): ...
    def shader_imap(self): ...
    @property
    def scale(self): ...
    @scale.setter
    def scale(self, s): ...
    @property
    def translate(self): ...
    @translate.setter
    def translate(self, t): ...
    def _set_st(self, scale=None, translate=None, update=True): ...
    def _update_shaders(self): ...
    def move(self, move: ArrayLike): ...
    def zoom(self, zoom: ArrayLike, center: ArrayLike = ..., mapped: bool = True): ...
    def as_matrix(self): ...
    @classmethod
    def from_mapping(cls, x0: ArrayLike, x1: ArrayLike) -> STTransform: ...
    def set_mapping(self, x0: ArrayLike, x1: ArrayLike, update: bool = True): ...
    def __mul__(self, tr): ...
    def __rmul__(self, tr): ...
    def __repr__(self): ...

class MatrixTransform(BaseTransform):
    glsl_map: ClassVar[str]

    glsl_imap: ClassVar[str]

    Linear: bool = ...
    Orthogonal: bool = ...
    NonScaling: bool = ...
    Isometric: bool = ...

    def __init__(self, matrix: ArrayLike | None = None): ...
    @arg_to_vec4
    def map(self, coords: ArrayLike) -> NDArray: ...
    @arg_to_vec4
    def imap(self, coords: ArrayLike) -> NDArray: ...
    def shader_map(self): ...
    def shader_imap(self): ...
    @property
    def matrix(self): ...
    @matrix.setter
    def matrix(self, m): ...
    @property
    def inv_matrix(self): ...
    @arg_to_vec4
    def translate(self, pos: np.ndarray): ...
    def scale(self, scale: ArrayLike, center: ArrayLike | None = None): ...
    def rotate(self, angle: float, axis: ArrayLike): ...
    def set_mapping(self, points1: ArrayLike, points2: ArrayLike): ...
    def set_ortho(self, l: float, r: float, b: float, t: float, n: float, f: float): ...
    def reset(self): ...
    def __mul__(self, tr): ...
    def __repr__(self): ...
    def set_perspective(self, fov: float, aspect: float, near: float, far: float): ...
    def set_frustum(self, l: float, r: float, b: float, t: float, n: float, f: float): ...
