from typing import Optional
from .Image import Image, Icon, DefaultIcon
from .Camera import Camera
from .Color import Color
from Mesh import Mesh2D
from .Constants import All, WindowFlag
from ._sdl.sdl2 import SDL_Surface, SDL_Texture, SDL_Window, SDL_Renderer, SDL_GLContext

__all__ = ["Window", "CreateGlWindow", "InternalWindow"]

class _drawnObjectsList:
    _drawnObjects: dict

    def __init__(self): ...

    def addObject(self, obj_id:any, metadata:any=None) -> bool: ...

    def hasObject(self, obj_id:any) -> bool: ...

    def getObject(self, obj_id:any) -> any: ...

    def getAllObjects(self) -> any: ...

    def getAll(self) -> dict: ...

    def count(self) -> int: ...

    def clear(self): ...

    def removeObject(self, obj_id:any) -> any: ...

class _Window:
    __WindowActive__: bool

    window: Optional[SDL_Window]
    context: Optional[SDL_GLContext]
    renderer: Optional[SDL_Renderer]
    __WindowId__: int

    _frameRateLimit:int
    _cache:dict
    frameRate:int

    drawnObjects: _drawnObjectsList

    def __init__(self): ...

    @property
    def flags(self) -> int: ...

    @property
    def isUsingOpenGLContext(self) -> bool: ...

    @property
    def frameRateLimit(self) -> int: ...

    @frameRateLimit.setter
    def frameRateLimit(self, value:int): ...

    def close(self): ...

    def clear(self, force:bool=False, color:list[int, int, int, int]|tuple[int, int, int, int]=(0, 0, 0, 255)): ...

    def getImage(self) -> Image: ...

    def blit(self, surface: Image | SDL_Surface | SDL_Texture, location=(0, 0), size=None, rotation: int = 0): ...

    def drawPixel(self, location, color:Color): ...

    def drawSquare(self, location, size, rotation, radius, color: Color): ...

    def drawEdgesSquare(self, location, size, rotation, line_size, radius, color: Color): ...

    def drawLine(self, start, end, size, color: Color): ...

    def drawSimpleLine(self, start, end, color: Color): ...

    def drawPolygon(self, location, scale, rotation: int, mesh: Mesh2D, color: Color): ...

    def drawEdgesPolygon(self, location, scale, rotation, mesh: Mesh2D, color: Color): ...

    @property
    def color(self) -> tuple[int, int, int, int]: ...

    @color.setter
    def color(self, color: Color | list[int, int, int, int]): ...

class Window(_Window):

    _title:str
    _location:tuple|list
    _resolution:tuple|list
    _logical_resolution:tuple|list

    camera:Camera

    _icon:Icon

    _shape: Optional[SDL_Surface]

    _hwnd:int

    variables:dict

    def __init__(self, title:str="MGE", icon:Icon=DefaultIcon, resolution:tuple[int, int]|list[int, int]=(1280, 720), location:tuple[int, int]|list[int, int]=(300, 300), logical_resolution:tuple[int, int]|list[int, int]=(0, 0), shape:Optional[SDL_Surface]=None, camera:Camera=Camera(), render_driver:int=All, flags=WindowFlag.Shown|WindowFlag.Resizable): ...

    @property
    def hwnd(self) -> int: ...

    def update(self, still_frame_optimization: bool = False) -> bool|None: ...

    def recreate(self, title:str="MGE", icon:Icon=DefaultIcon, resolution:tuple[int, int]|list[int, int]=(1280, 720), location:tuple[int, int]|list[int, int]=(300, 300), logical_resolution=(0, 0), shape=None, camera=Camera(), flags=WindowFlag.Shown | WindowFlag.Resizable): ...

    def restore(self): ...

    def show(self): ...

    def hide(self): ...

    def maximize(self): ...

    def minimize(self): ...

    @property
    def title(self) -> str: ...

    @title.setter
    def title(self, title: str): ...

    @property
    def icon(self) -> Icon: ...

    @icon.setter
    def icon(self, icon: Image | Icon): ...

    @property
    def shape(self) -> SDL_Surface: ...

    @shape.setter
    def shape(self, shape:SDL_Surface): ...

    @property
    def opacity(self) -> float: ...

    @opacity.setter
    def opacity(self, opacity:float): ...

    @property
    def location(self) -> tuple[int, int]: ...

    @location.setter
    def location(self, location:tuple[int, int]|list[int, int]): ...

    @property
    def resolution(self) -> tuple[int, int]: ...

    @resolution.setter
    def resolution(self, resolution:tuple[int, int]|list[int, int]): ...

    @property
    def minimumResolution(self) -> tuple[int, int]: ...

    @minimumResolution.setter
    def minimumResolution(self, resolution:tuple[int, int]|list[int, int]): ...

    @property
    def maximumResolution(self) -> tuple[int, int]: ...

    @maximumResolution.setter
    def maximumResolution(self, resolution:tuple[int, int]|list[int, int]): ...

    @property
    def logicalResolution(self) -> tuple[int, int]: ...

    @logicalResolution.setter
    def logicalResolution(self, resolution:tuple[int, int]|list[int, int]): ...

    @property
    def borderless(self) -> bool: ...

    @borderless.setter
    def borderless(self, v: bool): ...

    @property
    def resizable(self) -> bool: ...

    @resizable.setter
    def resizable(self, v: bool): ...

    @property
    def alwaysOnTop(self) -> bool: ...

    @alwaysOnTop.setter
    def alwaysOnTop(self, v: bool): ...

    def set_TitleBarColor(self, color: Color): ...

    def set_BorderColor(self, color: Color | None): ...

    def set_TitleColor(self, color: Color): ...

def CreateGlWindow(title="MGE", icon: Icon = DefaultIcon, resolution=(1280, 720), location=(300, 300), shape=None, msaa=0, flags=WindowFlag.Shown | WindowFlag.Resizable) -> Window: ...

class InternalWindow(_Window):
    _location: tuple|list
    _resolution: tuple|list
    _logical_resolution: tuple|list

    camera: Camera

    variables: dict

    def __init__(self, location=(0, 0), rotation: int = 0, size=(1280, 720), scale=(1, 1), resolution=(1280, 720), camera=Camera()): ...

    def render(self, window:Optional[Window]=None): ...

    def drawObject(self, window:Window, camera:Optional[Camera]=None, still_frame_optimization:bool=False): ...

    def hover(self, window, camera: Camera = None) -> bool: ...

    def recreate(self, location=(0, 0), rotation: int = 0, size=(1280, 720), scale=(1, 1), resolution=(1280, 720), camera=Camera()): ...

    @property
    def location(self) -> tuple: ...

    @location.setter
    def location(self, location): ...

    def getTrueLocation(self, window: Window, camera: Camera = None) -> tuple: ...

    @property
    def size(self) -> list[int, int]: ...

    @size.setter
    def size(self, size): ...

    def getTrueSize(self, window: Window, camera: Camera = None) -> tuple: ...

    @property
    def rotation(self) -> int: ...

    @rotation.setter
    def rotation(self, rotation: int | float): ...

    @property
    def scale(self) -> tuple: ...

    @scale.setter
    def scale(self, scale:tuple): ...

    @property
    def pivot(self) -> tuple: ...

    @pivot.setter
    def pivot(self, pivot): ...

    def getTrueRenderLocationSize(self, window: Window, camera: Camera = None): ...

    @property
    def resolution(self) -> tuple: ...

    @resolution.setter
    def resolution(self, resolution): ...

    @property
    def logicalResolution(self) -> tuple: ...

    @logicalResolution.setter
    def logicalResolution(self, resolution): ...
