using System;
using System.Runtime.InteropServices;

namespace SDL2
{
	public static class SDL_mixer
	{
		public static void SDL_MIXER_VERSION(out SDL.SDL_version X)
		{
			X.major = 2;
			X.minor = 0;
			X.patch = 2;
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl, EntryPoint = "MIX_Linked_Version")]
		private static extern IntPtr INTERNAL_MIX_Linked_Version();

		public static SDL.SDL_version MIX_Linked_Version()
		{
			return (SDL.SDL_version)Marshal.PtrToStructure(SDL_mixer.INTERNAL_MIX_Linked_Version(), typeof(SDL.SDL_version));
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_Init(SDL_mixer.MIX_InitFlags flags);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_Quit();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_OpenAudio(int frequency, ushort format, int channels, int chunksize);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_AllocateChannels(int numchans);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_QuerySpec(out int frequency, out ushort format, out int channels);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr Mix_LoadWAV_RW(IntPtr src, int freesrc);

		public static IntPtr Mix_LoadWAV(string file)
		{
			return SDL_mixer.Mix_LoadWAV_RW(SDL.INTERNAL_SDL_RWFromFile(file, "rb"), 1);
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Mix_LoadMUS")]
		private static extern IntPtr INTERNAL_Mix_LoadMUS(byte[] file);

		public static IntPtr Mix_LoadMUS(string file)
		{
			return SDL_mixer.INTERNAL_Mix_LoadMUS(SDL.UTF8_ToNative(file));
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr Mix_QuickLoad_WAV([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1)] [In] byte[] mem);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr Mix_QuickLoad_RAW([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 1)] [In] byte[] mem, uint len);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_FreeChunk(IntPtr chunk);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_FreeMusic(IntPtr music);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GetNumChunkDecoders();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Mix_GetChunkDecoder")]
		private static extern IntPtr INTERNAL_Mix_GetChunkDecoder(int index);

		public static string Mix_GetChunkDecoder(int index)
		{
			return SDL.UTF8_ToManaged(SDL_mixer.INTERNAL_Mix_GetChunkDecoder(index), false);
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GetNumMusicDecoders();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Mix_GetMusicDecoder")]
		private static extern IntPtr INTERNAL_Mix_GetMusicDecoder(int index);

		public static string Mix_GetMusicDecoder(int index)
		{
			return SDL.UTF8_ToManaged(SDL_mixer.INTERNAL_Mix_GetMusicDecoder(index), false);
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern SDL_mixer.Mix_MusicType Mix_GetMusicType(IntPtr music);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_SetPostMix(SDL_mixer.MixFuncDelegate mix_func, IntPtr arg);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_HookMusic(SDL_mixer.MixFuncDelegate mix_func, IntPtr arg);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_HookMusicFinished(SDL_mixer.MusicFinishedDelegate music_finished);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr Mix_GetMusicHookData();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_ChannelFinished(SDL_mixer.ChannelFinishedDelegate channel_finished);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_RegisterEffect(int chan, SDL_mixer.Mix_EffectFunc_t f, SDL_mixer.Mix_EffectDone_t d, IntPtr arg);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_UnregisterEffect(int channel, SDL_mixer.Mix_EffectFunc_t f);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_UnregisterAllEffects(int channel);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_SetPanning(int channel, byte left, byte right);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_SetPosition(int channel, short angle, byte distance);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_SetDistance(int channel, byte distance);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_SetReverseStereo(int channel, int flip);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_ReserveChannels(int num);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GroupChannel(int which, int tag);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GroupChannels(int from, int to, int tag);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GroupAvailable(int tag);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GroupCount(int tag);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GroupOldest(int tag);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GroupNewer(int tag);

		public static int Mix_PlayChannel(int channel, IntPtr chunk, int loops)
		{
			return SDL_mixer.Mix_PlayChannelTimed(channel, chunk, loops, -1);
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_PlayChannelTimed(int channel, IntPtr chunk, int loops, int ticks);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_PlayMusic(IntPtr music, int loops);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_FadeInMusic(IntPtr music, int loops, int ms);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_FadeInMusicPos(IntPtr music, int loops, int ms, double position);

		public static int Mix_FadeInChannel(int channel, IntPtr chunk, int loops, int ms)
		{
			return SDL_mixer.Mix_FadeInChannelTimed(channel, chunk, loops, ms, -1);
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_FadeInChannelTimed(int channel, IntPtr chunk, int loops, int ms, int ticks);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_Volume(int channel, int volume);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_VolumeChunk(IntPtr chunk, int volume);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_VolumeMusic(int volume);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_HaltChannel(int channel);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_HaltGroup(int tag);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_HaltMusic();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_ExpireChannel(int channel, int ticks);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_FadeOutChannel(int which, int ms);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_FadeOutGroup(int tag, int ms);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_FadeOutMusic(int ms);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern SDL_mixer.Mix_Fading Mix_FadingMusic();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern SDL_mixer.Mix_Fading Mix_FadingChannel(int which);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_Pause(int channel);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_Resume(int channel);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_Paused(int channel);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_PauseMusic();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_ResumeMusic();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_RewindMusic();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_PausedMusic();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_SetMusicPosition(double position);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_Playing(int channel);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_PlayingMusic();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Mix_SetMusicCMD")]
		private static extern int INTERNAL_Mix_SetMusicCMD(byte[] command);

		public static int Mix_SetMusicCMD(string command)
		{
			return SDL_mixer.INTERNAL_Mix_SetMusicCMD(SDL.UTF8_ToNative(command));
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_SetSynchroValue(int value);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_GetSynchroValue();

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Mix_SetSoundFonts")]
		private static extern int INTERNAL_Mix_SetSoundFonts(byte[] paths);

		public static int Mix_SetSoundFonts(string paths)
		{
			return SDL_mixer.INTERNAL_Mix_SetSoundFonts(SDL.UTF8_ToNative(paths));
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Mix_GetSoundFonts")]
		private static extern IntPtr INTERNAL_Mix_GetSoundFonts();

		public static string Mix_GetSoundFonts()
		{
			return SDL.UTF8_ToManaged(SDL_mixer.INTERNAL_Mix_GetSoundFonts(), false);
		}

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern int Mix_EachSoundFont(SDL_mixer.SoundFontDelegate function, IntPtr data);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr Mix_GetChunk(int channel);

		[DllImport("SDL2_mixer", CallingConvention = CallingConvention.Cdecl)]
		public static extern void Mix_CloseAudio();

		private const string nativeLibName = "SDL2_mixer";

		public const int SDL_MIXER_MAJOR_VERSION = 2;

		public const int SDL_MIXER_MINOR_VERSION = 0;

		public const int SDL_MIXER_PATCHLEVEL = 2;

		public const int MIX_CHANNELS = 8;

		public static readonly int MIX_DEFAULT_FREQUENCY = 22050;

		public static readonly ushort MIX_DEFAULT_FORMAT = BitConverter.IsLittleEndian ? 32784 : 36880;

		public static readonly int MIX_DEFAULT_CHANNELS = 2;

		public static readonly byte MIX_MAX_VOLUME = 128;

		[Flags]
		public enum MIX_InitFlags
		{
			MIX_INIT_FLAC = 1,
			MIX_INIT_MOD = 2,
			MIX_INIT_MP3 = 8,
			MIX_INIT_OGG = 16,
			MIX_INIT_MID = 32
		}

		public enum Mix_Fading
		{
			MIX_NO_FADING,
			MIX_FADING_OUT,
			MIX_FADING_IN
		}

		public enum Mix_MusicType
		{
			MUS_NONE,
			MUS_CMD,
			MUS_WAV,
			MUS_MOD,
			MUS_MID,
			MUS_OGG,
			MUS_MP3,
			MUS_MP3_MAD,
			MUS_FLAC,
			MUS_MODPLUG
		}

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate void MixFuncDelegate(IntPtr udata, IntPtr stream, int len);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate void Mix_EffectFunc_t(int chan, IntPtr stream, int len, IntPtr udata);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate void Mix_EffectDone_t(int chan, IntPtr udata);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate void MusicFinishedDelegate();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate void ChannelFinishedDelegate(int channel);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate int SoundFontDelegate(IntPtr a, IntPtr b);
	}
}
