# -*- coding: utf-8 -*-
"""
Tipos ctypes comunes para basskit.

Define aliases de tipos utilizados en toda la biblioteca para mantener
coherencia con los tipos nativos de BASS (C/C++).
"""

import ctypes
from ctypes import wintypes


# ─── Tipos enteros básicos ────────────────────────────────────────────
DWORD = ctypes.c_ulong
WORD = ctypes.c_ushort
BYTE = ctypes.c_ubyte
BOOL = ctypes.c_int
QWORD = ctypes.c_int64
FLOAT = ctypes.c_float
DOUBLE = ctypes.c_double
INT = ctypes.c_int

# ─── Tipos de handle ─────────────────────────────────────────────────
# En BASS 64-bit, los handles son DWORD (32 bits sin signo)
HMUSIC = ctypes.c_ulong		# Handle de música MOD
HSAMPLE = ctypes.c_ulong		# Handle de muestra
HCHANNEL = ctypes.c_ulong		# Handle de canal de reproducción
HSTREAM = ctypes.c_ulong		# Handle de stream
HRECORD = ctypes.c_ulong		# Handle de grabación
HSYNC = ctypes.c_ulong			# Handle de sincronizador
HDSP = ctypes.c_ulong			# Handle de DSP
HFX = ctypes.c_ulong			# Handle de efecto DX8
HPLUGIN = ctypes.c_ulong		# Handle de plugin
HENCODE = ctypes.c_ulong		# Handle de codificación (BASSenc)

# ─── Tipos de handle ASIO ────────────────────────────────────────────
# (Solo disponible si bassasio.dll está presente)

# ─── Tipos de puntero ────────────────────────────────────────────────
PVOID = ctypes.c_void_p
LPVOID = ctypes.c_void_p
HWND = ctypes.c_ulong			# Handle de ventana (en 64 bits sigue siendo c_ulong para BASS)

# ─── Tipos de string ─────────────────────────────────────────────────
LPCSTR = ctypes.c_char_p		# Puntero a string ANSI
LPWSTR = ctypes.c_wchar_p		# Puntero a string Unicode

# ─── Tipo función base ───────────────────────────────────────────────
# BASS usa convención __stdcall en Windows
WINFUNCTYPE = ctypes.WINFUNCTYPE


# ─── Funciones auxiliares de manipulación de bits ─────────────────────
def LOBYTE(valor: int) -> int:
	"""Obtiene el byte bajo de un valor."""
	return valor & 0xFF


def HIBYTE(valor: int) -> int:
	"""Obtiene el byte alto de un valor de 16 bits."""
	return (valor >> 8) & 0xFF


def LOWORD(valor: int) -> int:
	"""Obtiene la palabra baja (16 bits inferiores) de un valor."""
	return valor & 0xFFFF


def HIWORD(valor: int) -> int:
	"""Obtiene la palabra alta (16 bits superiores) de un valor."""
	return (valor >> 16) & 0xFFFF


def MAKEWORD(bajo: int, alto: int) -> int:
	"""Construye un WORD a partir de dos bytes."""
	return (bajo & 0xFF) | ((alto & 0xFF) << 8)


def MAKELONG(bajo: int, alto: int) -> int:
	"""Construye un DWORD a partir de dos WORDs."""
	return (bajo & 0xFFFF) | ((alto & 0xFFFF) << 16)


def version_a_texto(valor: int) -> str:
	"""
	Convierte un valor de versión BASS (DWORD) a texto legible.

	Por ejemplo, 0x02041203 se convierte en '2.4.18.3'.
	"""
	mayor = (valor >> 24) & 0xFF
	menor = (valor >> 16) & 0xFF
	revision = (valor >> 8) & 0xFF
	build = valor & 0xFF
	return f"{mayor}.{menor}.{revision}.{build}"
