# -*- coding: utf-8 -*-
"""
Bindings de bajo nivel para bassenc.dll y sub-encoders.

Codificacion de audio, casting, servidor local.
"""

import ctypes
from typing import Optional
from ..cargador import cargar_addon
from ..tipos import QWORD
from ..callbacks.addons import ENCODEPROC, ENCODEPROCEX, ENCODECLIENTPROC, ENCODENOTIFYPROC

HENCODE = ctypes.c_ulong
_dll: Optional[ctypes.WinDLL] = None

def _obtener() -> ctypes.WinDLL:
	global _dll
	if _dll is None:
		_dll = cargar_addon("bassenc")
		if _dll is None:
			raise OSError("bassenc.dll no disponible")
		_configurar(_dll)
	return _dll

def _configurar(d: ctypes.WinDLL) -> None:
	d.BASS_Encode_GetVersion.argtypes = []
	d.BASS_Encode_GetVersion.restype = ctypes.c_ulong

	d.BASS_Encode_Start.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
	d.BASS_Encode_Start.restype = HENCODE

	try:
		d.BASS_Encode_StartLimit.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ENCODEPROC, ctypes.c_void_p, ctypes.c_ulong]
		d.BASS_Encode_StartLimit.restype = HENCODE
	except AttributeError:
		pass

	try:
		d.BASS_Encode_StartUser.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong, ENCODEPROCEX, ctypes.c_void_p]
		d.BASS_Encode_StartUser.restype = HENCODE
	except AttributeError:
		pass

	try:
		d.BASS_Encode_StartPCM.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
		d.BASS_Encode_StartPCM.restype = HENCODE
	except AttributeError:
		pass

	try:
		d.BASS_Encode_StartPCMFile.argtypes = [ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong]
		d.BASS_Encode_StartPCMFile.restype = HENCODE
	except AttributeError:
		pass

	try:
		d.BASS_Encode_StartDummy.argtypes = [ctypes.c_ulong, ctypes.c_ulong]
		d.BASS_Encode_StartDummy.restype = HENCODE
	except AttributeError:
		pass

	d.BASS_Encode_AddChunk.argtypes = [HENCODE, ctypes.c_char_p, ctypes.c_void_p, ctypes.c_ulong]
	d.BASS_Encode_AddChunk.restype = ctypes.c_int

	d.BASS_Encode_IsActive.argtypes = [ctypes.c_ulong]
	d.BASS_Encode_IsActive.restype = ctypes.c_ulong

	d.BASS_Encode_Stop.argtypes = [ctypes.c_ulong]
	d.BASS_Encode_Stop.restype = ctypes.c_int

	try:
		d.BASS_Encode_StopEx.argtypes = [ctypes.c_ulong, ctypes.c_int]
		d.BASS_Encode_StopEx.restype = ctypes.c_int
	except AttributeError:
		pass

	d.BASS_Encode_SetPaused.argtypes = [ctypes.c_ulong, ctypes.c_int]
	d.BASS_Encode_SetPaused.restype = ctypes.c_int

	d.BASS_Encode_Write.argtypes = [ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong]
	d.BASS_Encode_Write.restype = ctypes.c_int

	d.BASS_Encode_SetNotify.argtypes = [ctypes.c_ulong, ENCODENOTIFYPROC, ctypes.c_void_p]
	d.BASS_Encode_SetNotify.restype = ctypes.c_int

	d.BASS_Encode_GetCount.argtypes = [ctypes.c_ulong, ctypes.c_ulong]
	d.BASS_Encode_GetCount.restype = QWORD

	d.BASS_Encode_GetChannel.argtypes = [HENCODE]
	d.BASS_Encode_GetChannel.restype = ctypes.c_ulong

	try:
		d.BASS_Encode_SetChannel.argtypes = [HENCODE, ctypes.c_ulong]
		d.BASS_Encode_SetChannel.restype = ctypes.c_int
	except AttributeError:
		pass

	try:
		d.BASS_Encode_SetPriority.argtypes = [HENCODE, ctypes.c_int]
		d.BASS_Encode_SetPriority.restype = ctypes.c_int
	except AttributeError:
		pass

	# ACM (Windows only)
	try:
		d.BASS_Encode_GetACMFormat.argtypes = [ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_char_p, ctypes.c_ulong]
		d.BASS_Encode_GetACMFormat.restype = ctypes.c_ulong
	except AttributeError:
		pass

	try:
		d.BASS_Encode_StartACM.argtypes = [ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ENCODEPROC, ctypes.c_void_p]
		d.BASS_Encode_StartACM.restype = HENCODE
	except AttributeError:
		pass

	try:
		d.BASS_Encode_StartACMFile.argtypes = [ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_char_p]
		d.BASS_Encode_StartACMFile.restype = HENCODE
	except AttributeError:
		pass

	# Casting
	d.BASS_Encode_CastInit.argtypes = [HENCODE, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_int]
	d.BASS_Encode_CastInit.restype = ctypes.c_int

	d.BASS_Encode_CastSetTitle.argtypes = [HENCODE, ctypes.c_char_p, ctypes.c_char_p]
	d.BASS_Encode_CastSetTitle.restype = ctypes.c_int

	d.BASS_Encode_CastGetStats.argtypes = [HENCODE, ctypes.c_ulong, ctypes.c_char_p]
	d.BASS_Encode_CastGetStats.restype = ctypes.c_char_p

	try:
		d.BASS_Encode_CastSendMeta.argtypes = [HENCODE, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong]
		d.BASS_Encode_CastSendMeta.restype = ctypes.c_int
	except AttributeError:
		pass

	# Server
	d.BASS_Encode_ServerInit.argtypes = [HENCODE, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
	d.BASS_Encode_ServerInit.restype = ctypes.c_ulong

	d.BASS_Encode_ServerKick.argtypes = [HENCODE, ctypes.c_char_p]
	d.BASS_Encode_ServerKick.restype = ctypes.c_int

	try:
		d.BASS_Encode_ServerGetClients.argtypes = [HENCODE]
		d.BASS_Encode_ServerGetClients.restype = ctypes.c_char_p
	except AttributeError:
		pass

	try:
		d.BASS_Encode_UserOutput.argtypes = [HENCODE, ctypes.c_int64, ctypes.c_void_p, ctypes.c_ulong]
		d.BASS_Encode_UserOutput.restype = ctypes.c_int
	except AttributeError:
		pass

	try:
		d.BASS_Encode_GetCARef.argtypes = [HENCODE]
		d.BASS_Encode_GetCARef.restype = ctypes.c_void_p
	except AttributeError:
		pass

class BassEncAPI:
	"""Proxy de acceso a bassenc.dll."""
	def __getattr__(self, nombre: str):
		return getattr(_obtener(), nombre)

bassenc = BassEncAPI()
