# -*- coding: utf-8 -*-
"""Bindings de bajo nivel para basscd, bassloud, bassdsd, basshls, tags y sub-encoders."""

import ctypes
from typing import Optional
from ..cargador import cargar_addon
from ..tipos import QWORD

# ─── Patron comun de proxy ──────────────────────────────────────────
def _crear_proxy(nombre_dll: str, configurador=None):
	"""Crea un proxy lazy-loading para un add-on."""
	class _Proxy:
		_dll = None
		def __getattr__(self, nombre: str):
			if _Proxy._dll is None:
				_Proxy._dll = cargar_addon(nombre_dll)
				if _Proxy._dll is None:
					raise OSError(f"{nombre_dll}.dll no disponible")
				if configurador:
					configurador(_Proxy._dll)
			return getattr(_Proxy._dll, nombre)
	return _Proxy()

# ─── BASSCD ──────────────────────────────────────────────────────────
def _cfg_cd(d):
	try:
		d.BASS_CD_SetInterface.argtypes = [ctypes.c_ulong]
		d.BASS_CD_SetInterface.restype = ctypes.c_ulong
	except AttributeError:
		pass
	try:
		d.BASS_CD_GetInfo.argtypes = [ctypes.c_ulong, ctypes.c_void_p]
		d.BASS_CD_GetInfo.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_CD_Door.argtypes = [ctypes.c_ulong, ctypes.c_int]
		d.BASS_CD_Door.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_CD_DoorIsOpen.argtypes = [ctypes.c_ulong]
		d.BASS_CD_DoorIsOpen.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_CD_DoorIsLocked.argtypes = [ctypes.c_ulong]
		d.BASS_CD_DoorIsLocked.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_CD_DoorLock.argtypes = [ctypes.c_ulong, ctypes.c_int]
		d.BASS_CD_DoorLock.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_CD_IsReady.argtypes = [ctypes.c_ulong]
		d.BASS_CD_IsReady.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_CD_GetTracks.argtypes = [ctypes.c_ulong]
		d.BASS_CD_GetTracks.restype = ctypes.c_ulong
	except AttributeError:
		pass
	try:
		d.BASS_CD_GetTrackLength.argtypes = [ctypes.c_ulong, ctypes.c_ulong]
		d.BASS_CD_GetTrackLength.restype = ctypes.c_ulong
	except AttributeError:
		pass
	try:
		d.BASS_CD_StreamCreate.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong]
		d.BASS_CD_StreamCreate.restype = ctypes.c_ulong
	except AttributeError:
		pass
	try:
		d.BASS_CD_StreamCreateFile.argtypes = [ctypes.c_char_p, ctypes.c_ulong]
		d.BASS_CD_StreamCreateFile.restype = ctypes.c_ulong
	except AttributeError:
		pass
	try:
		d.BASS_CD_StreamSetTrack.argtypes = [ctypes.c_ulong, ctypes.c_ulong]
		d.BASS_CD_StreamSetTrack.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_CD_GetID.argtypes = [ctypes.c_ulong, ctypes.c_ulong]
		d.BASS_CD_GetID.restype = ctypes.c_char_p
	except AttributeError:
		pass
	try:
		d.BASS_CD_GetSpeed.argtypes = [ctypes.c_ulong]
		d.BASS_CD_GetSpeed.restype = ctypes.c_ulong
	except AttributeError:
		pass
	try:
		d.BASS_CD_SetSpeed.argtypes = [ctypes.c_ulong, ctypes.c_ulong]
		d.BASS_CD_SetSpeed.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_CD_Release.argtypes = [ctypes.c_ulong]
		d.BASS_CD_Release.restype = ctypes.c_int
	except AttributeError:
		pass

basscd = _crear_proxy("basscd", _cfg_cd)

# ─── BASSloud ────────────────────────────────────────────────────────
def _cfg_loud(d):
	d.BASS_Loudness_GetVersion.argtypes = []
	d.BASS_Loudness_GetVersion.restype = ctypes.c_ulong
	d.BASS_Loudness_Start.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.c_int]
	d.BASS_Loudness_Start.restype = ctypes.c_ulong
	d.BASS_Loudness_Stop.argtypes = [ctypes.c_ulong]
	d.BASS_Loudness_Stop.restype = ctypes.c_int
	d.BASS_Loudness_GetLevel.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_float)]
	d.BASS_Loudness_GetLevel.restype = ctypes.c_int
	try:
		d.BASS_Loudness_GetLevelMulti.argtypes = [ctypes.POINTER(ctypes.c_ulong), ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_float)]
		d.BASS_Loudness_GetLevelMulti.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_Loudness_SetChannel.argtypes = [ctypes.c_ulong, ctypes.c_ulong]
		d.BASS_Loudness_SetChannel.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.BASS_Loudness_GetChannel.argtypes = [ctypes.c_ulong]
		d.BASS_Loudness_GetChannel.restype = ctypes.c_ulong
	except AttributeError:
		pass

bassloud = _crear_proxy("bassloud", _cfg_loud)

# ─── Tags ────────────────────────────────────────────────────────────
def _cfg_tags(d):
	try:
		d.TAGS_GetVersion.argtypes = []
		d.TAGS_GetVersion.restype = ctypes.c_ulong
	except AttributeError:
		pass
	try:
		d.TAGS_Read.argtypes = [ctypes.c_ulong, ctypes.c_char_p]
		d.TAGS_Read.restype = ctypes.c_char_p
	except AttributeError:
		pass
	try:
		d.TAGS_ReadEx.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_int]
		d.TAGS_ReadEx.restype = ctypes.c_char_p
	except AttributeError:
		pass
	try:
		d.TAGS_SetUTF8.argtypes = [ctypes.c_int]
		d.TAGS_SetUTF8.restype = ctypes.c_int
	except AttributeError:
		pass
	try:
		d.TAGS_GetLastErrorDesc.argtypes = []
		d.TAGS_GetLastErrorDesc.restype = ctypes.c_char_p
	except AttributeError:
		pass

tags = _crear_proxy("tags", _cfg_tags)

# ─── Sub-encoders (completos v0.3.0) ─────────────────────────────────
HENCODE = ctypes.c_ulong

def _cfg_enc_flac(d):
	try:
		d.BASS_Encode_FLAC_GetVersion.argtypes = []
		d.BASS_Encode_FLAC_GetVersion.restype = ctypes.c_ulong
	except AttributeError: pass
	try:
		d.BASS_Encode_FLAC_Start.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
		d.BASS_Encode_FLAC_Start.restype = HENCODE
	except AttributeError: pass
	try:
		d.BASS_Encode_FLAC_StartFile.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_char_p]
		d.BASS_Encode_FLAC_StartFile.restype = HENCODE
	except AttributeError: pass
	try:
		d.BASS_Encode_FLAC_NewStream.argtypes = [HENCODE]
		d.BASS_Encode_FLAC_NewStream.restype = ctypes.c_int
	except AttributeError: pass

def _cfg_enc_mp3(d):
	try:
		d.BASS_Encode_MP3_GetVersion.argtypes = []
		d.BASS_Encode_MP3_GetVersion.restype = ctypes.c_ulong
	except AttributeError: pass
	try:
		d.BASS_Encode_MP3_Start.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
		d.BASS_Encode_MP3_Start.restype = HENCODE
	except AttributeError: pass
	try:
		d.BASS_Encode_MP3_StartFile.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_char_p]
		d.BASS_Encode_MP3_StartFile.restype = HENCODE
	except AttributeError: pass

def _cfg_enc_ogg(d):
	try:
		d.BASS_Encode_OGG_GetVersion.argtypes = []
		d.BASS_Encode_OGG_GetVersion.restype = ctypes.c_ulong
	except AttributeError: pass
	try:
		d.BASS_Encode_OGG_Start.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
		d.BASS_Encode_OGG_Start.restype = HENCODE
	except AttributeError: pass
	try:
		d.BASS_Encode_OGG_StartFile.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_char_p]
		d.BASS_Encode_OGG_StartFile.restype = HENCODE
	except AttributeError: pass
	try:
		d.BASS_Encode_OGG_NewStream.argtypes = [HENCODE]
		d.BASS_Encode_OGG_NewStream.restype = ctypes.c_int
	except AttributeError: pass

def _cfg_enc_opus(d):
	try:
		d.BASS_Encode_OPUS_GetVersion.argtypes = []
		d.BASS_Encode_OPUS_GetVersion.restype = ctypes.c_ulong
	except AttributeError: pass
	try:
		d.BASS_Encode_OPUS_Start.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
		d.BASS_Encode_OPUS_Start.restype = HENCODE
	except AttributeError: pass
	try:
		d.BASS_Encode_OPUS_StartFile.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_char_p]
		d.BASS_Encode_OPUS_StartFile.restype = HENCODE
	except AttributeError: pass
	try:
		d.BASS_Encode_OPUS_NewStream.argtypes = [HENCODE]
		d.BASS_Encode_OPUS_NewStream.restype = ctypes.c_int
	except AttributeError: pass

bassenc_flac = _crear_proxy("bassenc_flac", _cfg_enc_flac)
bassenc_mp3 = _crear_proxy("bassenc_mp3", _cfg_enc_mp3)
bassenc_ogg = _crear_proxy("bassenc_ogg", _cfg_enc_ogg)
bassenc_opus = _crear_proxy("bassenc_opus", _cfg_enc_opus)

# ─── Plugins de formato (no necesitan config especial) ───────────────
bassdsd = _crear_proxy("bassdsd")
basshls = _crear_proxy("basshls")
bassflac = _crear_proxy("bassflac")
bassopus = _crear_proxy("bassopus")
basswebm = _crear_proxy("basswebm")
basswv = _crear_proxy("basswv")
bassalac = _crear_proxy("bassalac")
bassape = _crear_proxy("bassape")
bass_aac = _crear_proxy("bass_aac")
bass_ac3 = _crear_proxy("bass_ac3")
bass_mpc = _crear_proxy("bass_mpc")
bass_spx = _crear_proxy("bass_spx")
bass_tta = _crear_proxy("bass_tta")
bass_ofr = _crear_proxy("bass_ofr")
bass_vst = _crear_proxy("bass_vst")
bass_ssl = _crear_proxy("bass_ssl")
