# -*- coding: utf-8 -*-
"""
Bindings de bajo nivel para bassmix.dll.

Mezclador de canales con resampling, matrix mixing y splitting.
"""

import ctypes
from typing import Optional
from ..cargador import cargar_addon
from ..tipos import QWORD
from ..callbacks.bass import SYNCPROC
from ..estructuras.addons import BASS_MIXER_NODE

_dll: Optional[ctypes.WinDLL] = None

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

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

	d.BASS_Mixer_StreamCreate.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong]
	d.BASS_Mixer_StreamCreate.restype = ctypes.c_ulong

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

	d.BASS_Mixer_StreamAddChannelEx.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, QWORD, QWORD]
	d.BASS_Mixer_StreamAddChannelEx.restype = ctypes.c_int

	try:
		d.BASS_Mixer_StreamGetChannels.argtypes = [ctypes.c_ulong, ctypes.POINTER(ctypes.c_ulong), ctypes.c_ulong]
		d.BASS_Mixer_StreamGetChannels.restype = ctypes.c_ulong
	except AttributeError:
		pass

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

	d.BASS_Mixer_ChannelFlags.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong]
	d.BASS_Mixer_ChannelFlags.restype = ctypes.c_ulong

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

	d.BASS_Mixer_ChannelSetPosition.argtypes = [ctypes.c_ulong, QWORD, ctypes.c_ulong]
	d.BASS_Mixer_ChannelSetPosition.restype = ctypes.c_int

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

	try:
		d.BASS_Mixer_ChannelGetPositionEx.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong]
		d.BASS_Mixer_ChannelGetPositionEx.restype = QWORD
	except AttributeError:
		pass

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

	try:
		d.BASS_Mixer_ChannelGetLevelEx.argtypes = [ctypes.c_ulong, ctypes.POINTER(ctypes.c_float), ctypes.c_float, ctypes.c_ulong]
		d.BASS_Mixer_ChannelGetLevelEx.restype = ctypes.c_int
	except AttributeError:
		pass

	d.BASS_Mixer_ChannelGetData.argtypes = [ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong]
	d.BASS_Mixer_ChannelGetData.restype = ctypes.c_ulong

	d.BASS_Mixer_ChannelSetSync.argtypes = [ctypes.c_ulong, ctypes.c_ulong, QWORD, SYNCPROC, ctypes.c_void_p]
	d.BASS_Mixer_ChannelSetSync.restype = ctypes.c_ulong

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

	d.BASS_Mixer_ChannelSetMatrix.argtypes = [ctypes.c_ulong, ctypes.POINTER(ctypes.c_float)]
	d.BASS_Mixer_ChannelSetMatrix.restype = ctypes.c_int

	d.BASS_Mixer_ChannelGetMatrix.argtypes = [ctypes.c_ulong, ctypes.POINTER(ctypes.c_float)]
	d.BASS_Mixer_ChannelGetMatrix.restype = ctypes.c_int

	try:
		d.BASS_Mixer_ChannelSetMatrixEx.argtypes = [ctypes.c_ulong, ctypes.POINTER(ctypes.c_float), ctypes.c_float]
		d.BASS_Mixer_ChannelSetMatrixEx.restype = ctypes.c_int
	except AttributeError:
		pass

	d.BASS_Mixer_ChannelSetEnvelope.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(BASS_MIXER_NODE), ctypes.c_ulong]
	d.BASS_Mixer_ChannelSetEnvelope.restype = ctypes.c_int

	d.BASS_Mixer_ChannelSetEnvelopePos.argtypes = [ctypes.c_ulong, ctypes.c_ulong, QWORD]
	d.BASS_Mixer_ChannelSetEnvelopePos.restype = ctypes.c_int

	d.BASS_Mixer_ChannelGetEnvelopePos.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_float)]
	d.BASS_Mixer_ChannelGetEnvelopePos.restype = QWORD

	try:
		d.BASS_Mixer_ChannelIsActive.argtypes = [ctypes.c_ulong]
		d.BASS_Mixer_ChannelIsActive.restype = ctypes.c_ulong
	except AttributeError:
		pass

	d.BASS_Split_StreamCreate.argtypes = [ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(ctypes.c_int)]
	d.BASS_Split_StreamCreate.restype = ctypes.c_ulong

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

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

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

	try:
		d.BASS_Split_StreamGetAvailable.argtypes = [ctypes.c_ulong]
		d.BASS_Split_StreamGetAvailable.restype = ctypes.c_ulong
	except AttributeError:
		pass

	try:
		d.BASS_Split_StreamGetSplits.argtypes = [ctypes.c_ulong, ctypes.POINTER(ctypes.c_ulong), ctypes.c_ulong]
		d.BASS_Split_StreamGetSplits.restype = ctypes.c_ulong
	except AttributeError:
		pass

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

bassmix = BassMixAPI()
