# -*- coding: utf-8 -*-
"""
Estructuras ctypes principales de BASS (bass.dll).

Define todas las estructuras C utilizadas por las funciones
de bass.dll, con docstrings en español.
"""

import ctypes
from ..tipos import DWORD, QWORD, HPLUGIN, HSAMPLE


class BASS_DEVICEINFO(ctypes.Structure):
	"""Información de un dispositivo de salida o grabación."""
	_fields_ = [
		("name", ctypes.c_char_p),			# Nombre del dispositivo
		("driver", ctypes.c_char_p),		# Identificador del controlador
		("flags", ctypes.c_ulong),			# Flags del dispositivo (BASS_DEVICE_xxx)
	]

	def __repr__(self) -> str:
		nombre = self.name.decode("utf-8", errors="replace") if self.name else "(sin nombre)"
		return f"<BASS_DEVICEINFO: {nombre} flags=0x{self.flags:08X}>"


class BASS_INFO(ctypes.Structure):
	"""Información del dispositivo de salida inicializado."""
	_fields_ = [
		("flags", ctypes.c_ulong),			# Capacidades del dispositivo
		("hwsize", ctypes.c_ulong),			# Tamaño total de memoria de hardware
		("hwfree", ctypes.c_ulong),			# Memoria de hardware libre
		("freesam", ctypes.c_ulong),		# Slots de muestra libres
		("free3d", ctypes.c_ulong),			# Slots de muestra 3D libres
		("minrate", ctypes.c_ulong),		# Frecuencia mínima soportada
		("maxrate", ctypes.c_ulong),		# Frecuencia máxima soportada
		("eax", ctypes.c_int),				# ¿Soporta EAX?
		("minbuf", ctypes.c_ulong),			# Buffer mínimo recomendado (ms)
		("dsver", ctypes.c_ulong),			# Versión de DirectSound
		("latency", ctypes.c_ulong),		# Latencia (ms)
		("initflags", ctypes.c_ulong),		# Flags usados en BASS_Init
		("speakers", ctypes.c_ulong),		# Número de altavoces
		("freq", ctypes.c_ulong),			# Frecuencia de salida actual
	]


class BASS_RECORDINFO(ctypes.Structure):
	"""Información del dispositivo de grabación."""
	_fields_ = [
		("flags", ctypes.c_ulong),			# Capacidades
		("formats", ctypes.c_ulong),		# Formatos soportados
		("inputs", ctypes.c_ulong),			# Número de entradas
		("singlein", ctypes.c_int),			# ¿Solo una entrada a la vez?
		("freq", ctypes.c_ulong),			# Frecuencia actual
	]


class BASS_SAMPLE(ctypes.Structure):
	"""Información de una muestra."""
	_fields_ = [
		("freq", ctypes.c_ulong),			# Frecuencia de reproducción
		("volume", ctypes.c_float),			# Volumen (0-1)
		("pan", ctypes.c_float),			# Pan (-1=izq, 0=centro, 1=der)
		("flags", ctypes.c_ulong),			# Flags
		("length", ctypes.c_ulong),			# Longitud en bytes
		("max", ctypes.c_ulong),			# Máximo de reproducciones simultáneas
		("origres", ctypes.c_ulong),		# Resolución original en bits
		("chans", ctypes.c_ulong),			# Número de canales
		("mingap", ctypes.c_ulong),			# Separación mínima entre canales (ms)
		("mode3d", ctypes.c_ulong),			# Modo 3D
		("mindist", ctypes.c_float),		# Distancia mínima 3D
		("maxdist", ctypes.c_float),		# Distancia máxima 3D
		("iangle", ctypes.c_ulong),			# Ángulo interior del cono
		("oangle", ctypes.c_ulong),			# Ángulo exterior del cono
		("outvol", ctypes.c_float),			# Volumen fuera del cono
		("vam", ctypes.c_ulong),			# Flags VAM
		("priority", ctypes.c_ulong),		# Prioridad
	]


class BASS_CHANNELINFO(ctypes.Structure):
	"""Información de un canal (stream, muestra, música)."""
	_fields_ = [
		("freq", ctypes.c_ulong),			# Frecuencia de reproducción
		("chans", ctypes.c_ulong),			# Número de canales
		("flags", ctypes.c_ulong),			# Flags
		("ctype", ctypes.c_ulong),			# Tipo de canal
		("origres", ctypes.c_ulong),		# Resolución original
		("plugin", ctypes.c_ulong),			# Plugin que maneja el formato
		("sample", ctypes.c_ulong),			# Handle de muestra asociada
		("filename", ctypes.c_char_p),		# Nombre de archivo
	]


class BASS_3DVECTOR(ctypes.Structure):
	"""Vector 3D para posiciones, velocidades y orientaciones."""
	_fields_ = [
		("x", ctypes.c_float),				# +=derecha, -=izquierda
		("y", ctypes.c_float),				# +=arriba, -=abajo
		("z", ctypes.c_float),				# +=adelante, -=atrás
	]

	def __repr__(self) -> str:
		return f"<BASS_3DVECTOR x={self.x:.2f} y={self.y:.2f} z={self.z:.2f}>"


class BASS_PLUGINFORM(ctypes.Structure):
	"""Descripción de formato soportado por un plugin."""
	_fields_ = [
		("ctype", ctypes.c_ulong),			# Tipo de canal
		("name", ctypes.c_char_p),			# Descripción del formato
		("exts", ctypes.c_char_p),			# Filtro de extensiones
	]


class BASS_PLUGININFO(ctypes.Structure):
	"""Información de un plugin cargado."""
	_fields_ = [
		("version", ctypes.c_ulong),		# Versión del plugin
		("formatc", ctypes.c_ulong),		# Número de formatos
		("formats", ctypes.POINTER(BASS_PLUGINFORM)),	# Array de formatos
	]


# ─── Estructuras de efectos DX8 ──────────────────────────────────────

class BASS_DX8_CHORUS(ctypes.Structure):
	"""Parámetros del efecto chorus DX8."""
	_fields_ = [
		("fWetDryMix", ctypes.c_float),
		("fDepth", ctypes.c_float),
		("fFeedback", ctypes.c_float),
		("fFrequency", ctypes.c_float),
		("lWaveform", ctypes.c_ulong),		# 0=triángulo, 1=seno
		("fDelay", ctypes.c_float),
		("lPhase", ctypes.c_ulong),			# BASS_DX8_PHASE_xxx
	]


class BASS_DX8_COMPRESSOR(ctypes.Structure):
	"""Parámetros del efecto compresor DX8."""
	_fields_ = [
		("fGain", ctypes.c_float),
		("fAttack", ctypes.c_float),
		("fRelease", ctypes.c_float),
		("fThreshold", ctypes.c_float),
		("fRatio", ctypes.c_float),
		("fPredelay", ctypes.c_float),
	]


class BASS_DX8_DISTORTION(ctypes.Structure):
	"""Parámetros del efecto distorsión DX8."""
	_fields_ = [
		("fGain", ctypes.c_float),
		("fEdge", ctypes.c_float),
		("fPostEQCenterFrequency", ctypes.c_float),
		("fPostEQBandwidth", ctypes.c_float),
		("fPreLowpassCutoff", ctypes.c_float),
	]


class BASS_DX8_ECHO(ctypes.Structure):
	"""Parámetros del efecto eco DX8."""
	_fields_ = [
		("fWetDryMix", ctypes.c_float),
		("fFeedback", ctypes.c_float),
		("fLeftDelay", ctypes.c_float),
		("fRightDelay", ctypes.c_float),
		("lPanDelay", ctypes.c_int),
	]


class BASS_DX8_FLANGER(ctypes.Structure):
	"""Parámetros del efecto flanger DX8."""
	_fields_ = [
		("fWetDryMix", ctypes.c_float),
		("fDepth", ctypes.c_float),
		("fFeedback", ctypes.c_float),
		("fFrequency", ctypes.c_float),
		("lWaveform", ctypes.c_ulong),
		("fDelay", ctypes.c_float),
		("lPhase", ctypes.c_ulong),
	]


class BASS_DX8_GARGLE(ctypes.Structure):
	"""Parámetros del efecto gargle DX8."""
	_fields_ = [
		("dwRateHz", ctypes.c_ulong),
		("dwWaveShape", ctypes.c_ulong),	# 0=triángulo, 1=cuadrado
	]


class BASS_DX8_I3DL2REVERB(ctypes.Structure):
	"""Parámetros del efecto reverberación I3DL2."""
	_fields_ = [
		("lRoom", ctypes.c_int),
		("lRoomHF", ctypes.c_int),
		("flRoomRolloffFactor", ctypes.c_float),
		("flDecayTime", ctypes.c_float),
		("flDecayHFRatio", ctypes.c_float),
		("lReflections", ctypes.c_int),
		("flReflectionsDelay", ctypes.c_float),
		("lReverb", ctypes.c_int),
		("flReverbDelay", ctypes.c_float),
		("flDiffusion", ctypes.c_float),
		("flDensity", ctypes.c_float),
		("flHFReference", ctypes.c_float),
	]


class BASS_DX8_PARAMEQ(ctypes.Structure):
	"""Parámetros del ecualizador paramétrico DX8."""
	_fields_ = [
		("fCenter", ctypes.c_float),
		("fBandwidth", ctypes.c_float),
		("fGain", ctypes.c_float),
	]


class BASS_DX8_REVERB(ctypes.Structure):
	"""Parámetros del efecto reverberación DX8."""
	_fields_ = [
		("fInGain", ctypes.c_float),
		("fReverbMix", ctypes.c_float),
		("fReverbTime", ctypes.c_float),
		("fHighFreqRTRatio", ctypes.c_float),
	]


class BASS_FX_VOLUME_PARAM(ctypes.Structure):
	"""Parámetros del efecto de volumen DSP."""
	_fields_ = [
		("fTarget", ctypes.c_float),		# Volumen objetivo
		("fCurrent", ctypes.c_float),		# Volumen actual (solo lectura)
		("fTime", ctypes.c_float),			# Tiempo de transición
		("lCurve", ctypes.c_ulong),			# Tipo de curva
	]


# ─── Estructuras de tags ─────────────────────────────────────────────

class TAG_ID3(ctypes.Structure):
	"""Estructura de tags ID3v1."""
	_fields_ = [
		("id", ctypes.c_char * 3),
		("title", ctypes.c_char * 30),
		("artist", ctypes.c_char * 30),
		("album", ctypes.c_char * 30),
		("year", ctypes.c_char * 4),
		("comment", ctypes.c_char * 30),
		("genre", ctypes.c_ubyte),
	]


class TAG_BEXT(ctypes.Structure):
	"""Estructura de tags BWF (Broadcast Wave Format)."""
	_fields_ = [
		("Description", ctypes.c_char * 256),
		("Originator", ctypes.c_char * 32),
		("OriginatorReference", ctypes.c_char * 32),
		("OriginationDate", ctypes.c_char * 10),
		("OriginationTime", ctypes.c_char * 8),
		("TimeReference", ctypes.c_int64),
		("Version", ctypes.c_ushort),
		("UMID", ctypes.c_ubyte * 64),
		("Reserved", ctypes.c_ubyte * 190),
		("CodingHistory", ctypes.c_char_p),
	]


class TAG_CART_TIMER(ctypes.Structure):
	"""Timer de etiqueta CART."""
	_fields_ = [
		("dwUsage", ctypes.c_ulong),
		("dwValue", ctypes.c_ulong),
	]


class TAG_CART(ctypes.Structure):
	"""Estructura de tags CART (AES46-2002)."""
	_fields_ = [
		("Version", ctypes.c_char * 4),
		("Title", ctypes.c_char * 64),
		("Artist", ctypes.c_char * 64),
		("CutID", ctypes.c_char * 64),
		("ClientID", ctypes.c_char * 64),
		("Category", ctypes.c_char * 64),
		("Classification", ctypes.c_char * 64),
		("OutCue", ctypes.c_char * 64),
		("StartDate", ctypes.c_char * 10),
		("StartTime", ctypes.c_char * 8),
		("EndDate", ctypes.c_char * 10),
		("EndTime", ctypes.c_char * 8),
		("ProducerAppID", ctypes.c_char * 64),
		("ProducerAppVersion", ctypes.c_char * 64),
		("UserDef", ctypes.c_char * 64),
		("dwLevelReference", ctypes.c_ulong),
		("PostTimer", TAG_CART_TIMER * 8),
		("Reserved", ctypes.c_char * 276),
		("URL", ctypes.c_char * 1024),
		("TagText", ctypes.c_char_p),
	]


class TAG_CA_CODEC(ctypes.Structure):
	"""Información del códec CoreAudio."""
	_fields_ = [
		("ftype", ctypes.c_ulong),
		("atype", ctypes.c_ulong),
		("name", ctypes.c_char_p),
	]


class TAG_APE_BINARY(ctypes.Structure):
	"""Tag binario APE."""
	_fields_ = [
		("key", ctypes.c_char_p),
		("data", ctypes.c_void_p),
		("length", ctypes.c_ulong),
	]


class TAG_BINARY(ctypes.Structure):
	"""Bloque de datos binario (ej. ID3v2)."""
	_fields_ = [
		("data", ctypes.c_void_p),
		("length", ctypes.c_ulong),
	]


# ─── Estructuras de file procs ───────────────────────────────────────
# (Las FILEPROCS se definen en callbacks)
