import ctypes
import sys
from types import SimpleNamespace

import platform
from pathlib import Path

_here = Path(__file__).resolve().parent

if sys.platform.startswith("win"):
    lib_path = _here / "lib" / "Uniuge.dll"
elif sys.platform == "darwin":
    lib_path = _here / "lib" / "Uniuge.dylib"
else:
    raise RuntimeError("Unsupported platform")

lib = ctypes.CDLL(str(lib_path))

c_int = ctypes.c_int
c_float = ctypes.c_float
c_char = ctypes.c_char_p
c_bool = ctypes.c_bool

# Get time since program start
lib.get_time.restype = c_float
lib.get_time.argtypes = None

# Initialize
lib.initialization.argtypes = None
lib.initialization.restype = None

# Create window
lib.create_window.argtypes = [c_int, c_int, c_char, c_bool]
lib.create_window.restype = c_int

# Call every frame
lib.start_frame.argtypes = None
lib.start_frame.restype = None

# Check if window was closed
lib.window_closed.argtypes = [c_int]
lib.window_closed.restype = c_bool

# Swap window
lib.swap_win.argtypes = [c_int]
lib.swap_win.restype = None

lib.clear_win.argtypes = [c_int, c_float, c_float, c_float, c_float]
lib.clear_win.restype = None

lib.clear_tex.argtypes = [c_int, c_float, c_float, c_float, c_float]
lib.clear_tex.restype = None

lib.draw_rect_win.argtypes = [c_int, c_float, c_float, c_float, c_float, c_float, c_float, c_float, c_float]
lib.draw_rect_win.restype = None

lib.create_texture.argtypes = [c_int, c_int]
lib.create_texture.restype = c_int

lib.load_texture.argtypes = [c_int, c_char, c_bool]
lib.load_texture.restype = None

lib.draw_texture_win.argtypes = [c_int, c_int, c_float, c_float, c_float, c_float, c_float, c_float, c_float, c_float, c_bool, c_bool]
lib.draw_texture_win.restype = None

lib.draw_texture_tex.argtypes = [c_int, c_int, c_float, c_float, c_float, c_float, c_float, c_float, c_float, c_float, c_bool, c_bool]
lib.draw_texture_tex.restype = None

# Event
lib.get_event.argtypes = [c_int]
lib.get_event.restype = c_int

lib.event_pressed.argtypes = [c_int, c_int]
lib.event_pressed.restype = c_bool

lib.event_released.argtypes = [c_int, c_int]
lib.event_released.restype = c_bool

lib.event_down.argtypes = [c_int, c_int]
lib.event_down.restype = c_bool

lib.event_up.argtypes = [c_int, c_int]
lib.event_up.restype = c_bool

lib.get_time.argtypes = None
lib.get_time.restype = ctypes.c_double

lib.get_time.argtypes = None
lib.get_time.restype = ctypes.c_double

lib.load_font.argtypes = [c_char, c_float]
lib.load_font.restype = c_int

lib.draw_text_win.argtypes = [c_int, c_int, c_char, c_float, c_float, c_float, c_float, c_float, c_float, c_float]
lib.draw_text_win.restype = None

lib.draw_text_tex.argtypes = [c_int, c_int, c_char, c_float, c_float, c_float, c_float, c_float, c_float, c_float]
lib.draw_text_tex.restype = None


# -- 3D --
lib.create_space3d.argtypes = None
lib.create_space3d.restype = c_int

lib.draw_camera_3d_win.argtypes = [c_int, c_int, c_float, c_float, c_float, c_float, c_float, c_float, c_int, c_int, c_float, c_float]
lib.draw_camera_3d_win.restype = None

lib.draw_camera_3d_tex.argtypes = [c_int, c_int, c_float, c_float, c_float, c_float, c_float, c_float, c_int, c_int, c_float, c_float]
lib.draw_camera_3d_tex.restype = None

lib.clear_space3d.argtypes = [c_int]
lib.clear_space3d.restype = None

# adding a 3D cube to the 3D space
lib.draw_cube_3d.argtypes = [c_int,
                 c_float,c_float,c_float, # position(x,y,z)
                 c_float,c_float,c_float, # rotation(x,y,z)
                 c_float,c_float,c_float, # size(x,y,z)
                 c_float,c_float,c_float,c_float]
lib.draw_cube_3d.restype = None

lib.draw_ambient_light_3d.argtypes = [c_int, c_float, c_float, c_float, c_float, c_float]
lib.draw_ambient_light_3d.restype = None

lib.draw_point_light_3d.argtypes = [c_int, c_float, c_float, c_float, c_float, c_float, c_float, c_float, c_float]
lib.draw_point_light_3d.restype = None

lib.draw_rect_tex.argtypes = [c_int, c_float, c_float, c_float, c_float, c_float, c_float, c_float, c_float]
lib.draw_rect_tex.restype = None


# -- Image --

# Create image
lib.create_image.argtypes = [c_int, c_int]
lib.create_image.restype = c_int

# Load image
lib.load_image.argtypes = [c_int, c_char]
lib.load_image.restype = None

# 
lib.crop_image_to_texture.argtypes = [c_int, c_int, c_int, c_int, c_int, c_int, c_bool]
lib.crop_image_to_texture.restype = None