// DO NOT EDIT! This is an autogenerated file. All changes will be
// overwritten!

//	Copyright (c) 2023 Vidyo, Inc. All rights reserved.


using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace VidyoClient
{
	/// <summary>
	/// This object represents a virtual audio source on the local endpoint.
	/// </summary>
	public class VirtualAudioSource: IDisposable {
		private bool disposed = false; 
#if __IOS__
		const string importLib = "__Internal";
#else
		const string importLib = "libVidyoClient";
#endif
		private IntPtr objPtr; // opaque VidyoVirtualAudioSource reference.
		private GCHandle objHandle; // weak VidyoVirtualAudioSource reference.
		public IntPtr GetObjectPtr() {
			return objPtr;
		}
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceAddToLocalSpeakerNative(IntPtr virtualAudioSource, IntPtr localSpeaker);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceAddToRemoteSpeakerNative(IntPtr virtualAudioSource, IntPtr remoteSpeaker);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoVirtualAudioSourceConstructNative(IntPtr endpoint, IntPtr name, IntPtr id, IntPtr configuration);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoVirtualAudioSourceConstructCopyNative(IntPtr virtualAudioSourceSrc);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoVirtualAudioSourceDestructNative(IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoVirtualAudioSourceGetConfigurationNative(IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoVirtualAudioSourceGetIdNative(IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoVirtualAudioSourceGetNameNative(IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceIsSelectedNative(IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceRegisterEventListenerNative(IntPtr virtualAudioSource, StartCallback onStart, StopCallback onStop, ReconfigureCallback onReconfigure, ExternalMediaBufferReleaseCallback onBufferRelease);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceRemoveFromLocalSpeakerNative(IntPtr virtualAudioSource, IntPtr localSpeaker);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceRemoveFromRemoteSpeakerNative(IntPtr virtualAudioSource, IntPtr remoteSpeaker);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceSendFrameNative(IntPtr virtualAudioSource, IntPtr audioFrame);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceSendFrameWithExternalDataNative(IntPtr virtualAudioSource, IntPtr buffer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT nbSamples, ulong elapsedTime);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceSetAudioContentShareNative(IntPtr virtualAudioSource, Boolean enable);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceSetConfigurationNative(IntPtr virtualAudioSource, IntPtr configuration);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoVirtualAudioSourceUnregisterEventListenerNative(IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr VidyoVirtualAudioSourceGetUserDataNative(IntPtr obj);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		public static extern void VidyoVirtualAudioSourceSetUserDataNative(IntPtr obj, IntPtr userData);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void ExternalMediaBufferReleaseCallback(IntPtr virtualAudioSource, IntPtr buffer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT size);
		private ExternalMediaBufferReleaseCallback _mExternalMediaBufferReleaseCallback = ExternalMediaBufferReleaseCallbackDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void ReconfigureCallback(IntPtr virtualAudioSource, Device.DeviceState state);
		private ReconfigureCallback _mReconfigureCallback = ReconfigureCallbackDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void StartCallback(IntPtr virtualAudioSource);
		private StartCallback _mStartCallback = StartCallbackDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void StopCallback(IntPtr virtualAudioSource);
		private StopCallback _mStopCallback = StopCallbackDelegate;
		public interface IRegisterEventListener{

			void StartCallback();
			void StopCallback();
			void ReconfigureCallback(Device.DeviceState state);
			void ExternalMediaBufferReleaseCallback(byte[] buffer, SizeT size);
		}
		private IRegisterEventListener _mIRegisterEventListener;
		/// <summary>
		/// Constructs a virtual audio source. The VidyoVirtualAudioSourceStartCallback will trigger.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="endpoint">The VidyoEndpoint object.</param>
		/// <param name="name">The name for the virtual audio source.</param>
		/// <param name="id">The id for the virtual audio source.</param>
		/// <param name="configuration">The string in JSON format with virtual audio source configuration. <p>format - Specifies the media format. Possible values are: fl32 or in16. The default is fl32.</p> <p>Example: {'format' : 'in16'}.</p> <p>sampleRate - Specifies the audio sample rate. Possible values are: 48000, 32000 and 16000. The default is 32000.</p> <p>Example: {'sampleRate' : 48000}.</p> <p>numberOfChannels - Specifies the number of channels. Possible values are: 1 or 2. The default is 1.</p> <p>Example: {'numberOfChannels' : 2}.</p> <p>frameInterval - Specifies the frame interval in ms. Possible values are: 20 or 40. The default is 20.</p> <p>Example: {'frameInterval' : 40}.</p></param>
		/// <param name="allocator">The allocator object.</param>
		public VirtualAudioSource(Endpoint endpoint, String name, String id, String configuration) {

			IntPtr nName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(name ?? string.Empty);
			IntPtr nId = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(id ?? string.Empty);
			IntPtr nConfiguration = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(configuration ?? string.Empty);
			objPtr = VidyoVirtualAudioSourceConstructNative((endpoint != null) ? endpoint.GetObjectPtr():IntPtr.Zero, nName, nId, nConfiguration);
			objHandle = GCHandle.Alloc(this, GCHandleType.Weak);
			Marshal.FreeHGlobal(nConfiguration);
			Marshal.FreeHGlobal(nId);
			Marshal.FreeHGlobal(nName);
			VidyoVirtualAudioSourceSetUserDataNative(objPtr, GCHandle.ToIntPtr(objHandle));
		}
		public VirtualAudioSource(IntPtr virtualAudioSourceSrc){
			objPtr = VidyoVirtualAudioSourceConstructCopyNative(virtualAudioSourceSrc);
			objHandle = GCHandle.Alloc(this, GCHandleType.Weak);
			VidyoVirtualAudioSourceSetUserDataNative(objPtr, GCHandle.ToIntPtr(objHandle));
		}
		~VirtualAudioSource(){
			Dispose(false);
		}
		public void Dispose(){
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		public void Dispose(bool disposing){
			if(disposed) return;

			disposed = true;
			if(objPtr != IntPtr.Zero) {
				VidyoVirtualAudioSourceSetUserDataNative(objPtr, IntPtr.Zero);
				VidyoVirtualAudioSourceDestructNative(objPtr);
				objPtr = IntPtr.Zero;
			}

			if(objHandle.IsAllocated) objHandle.Free();
		}

		/// <summary>
		/// Add the virtual audio source to the local speaker stream. The VidyoVirtualAudioSourceStartCallback will trigger if needed.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="localSpeaker">The VidyoLocalSpeaker object.</param>
		public Boolean AddToLocalSpeaker(LocalSpeaker localSpeaker) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoVirtualAudioSourceAddToLocalSpeakerNative(objPtr, (localSpeaker != null) ? localSpeaker.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Add the virtual audio source to the remote speaker stream. The VidyoVirtualAudioSourceStartCallback will trigger if needed.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="remoteSpeaker">The VidyoLocalSpeaker object.</param>
		public Boolean AddToRemoteSpeaker(RemoteSpeaker remoteSpeaker) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoVirtualAudioSourceAddToRemoteSpeakerNative(objPtr, (remoteSpeaker != null) ? remoteSpeaker.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Gets the audio configs for the virtual audio source.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualVideoSource object.</param>
		public String GetConfiguration() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoVirtualAudioSourceGetConfigurationNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets the virtual audio source id.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualVideoSource object.</param>
		public String GetId() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoVirtualAudioSourceGetIdNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets the virtual audio source name.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualVideoSource object.</param>
		public String GetName() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoVirtualAudioSourceGetNameNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Check if source is selected.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		public Boolean IsSelected() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoVirtualAudioSourceIsSelectedNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about virtual audio source events.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="onStart">The callback invoked to notify that virtual audio source started.</param>
		/// <param name="onStop">The callback invoked to notify that virtual audio source stoped.</param>
		/// <param name="onReconfigure">The callback invoked if the virtual audio source configuration changed.</param>
		/// <param name="onBufferRelease">The callback invoked each time when VidyoClient is done with an application allocated buffer that holds raw audio frame.</param>
		public Boolean RegisterEventListener(IRegisterEventListener _iIRegisterEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterEventListener = _iIRegisterEventListener;

			Boolean ret = VidyoVirtualAudioSourceRegisterEventListenerNative(objPtr, _mStartCallback, _mStopCallback, _mReconfigureCallback, _mExternalMediaBufferReleaseCallback);

			return ret;
		}
		/// <summary>
		/// Remove the virtual audio source from the local speaker stream. The VidyoVirtualAudioSourceStopCallback will trigger if needed.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="localSpeaker">The VidyoLocalSpeaker object.</param>
		public Boolean RemoveFromLocalSpeaker(LocalSpeaker localSpeaker) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoVirtualAudioSourceRemoveFromLocalSpeakerNative(objPtr, (localSpeaker != null) ? localSpeaker.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Remove the virtual audio source from the remote speaker stream. The VidyoVirtualAudioSourceStopCallback will trigger if needed.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="remoteSpeaker">The VidyoRemoteSpeaker object.</param>
		public Boolean RemoveFromRemoteSpeaker(RemoteSpeaker remoteSpeaker) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoVirtualAudioSourceRemoveFromRemoteSpeakerNative(objPtr, (remoteSpeaker != null) ? remoteSpeaker.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Sends already constructed audio frame to selected virtual audio source and then send it to local and/or remote streams.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="audioFrame">The audio frame.</param>
		public Boolean SendFrame(AudioFrame audioFrame) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoVirtualAudioSourceSendFrameNative(objPtr, (audioFrame != null) ? audioFrame.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Pass raw buffer to selected virtual audio source, based on which the audio frame will be constructed and then send it to local and/or remote streams. The VidyoVirtualAudioSourceExternalMediaBufferReleaseCallback will trigger. This is an asynchronous interface.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="buffer">The audio frame.</param>
		/// <param name="nbSamples">The number of samples.</param>
		/// <param name="elapsedTime">The elapsed time.</param>
		public Boolean SendFrameWithExternalData(byte[] buffer, SizeT nbSamples, ulong elapsedTime) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr pointer = ByteArrayHelperSingleton.ByteArrayToRawPointer(buffer);
			Boolean ret = VidyoVirtualAudioSourceSendFrameWithExternalDataNative(objPtr, pointer, nbSamples, elapsedTime);

			return ret;
		}
		/// <summary>
		/// Enable or disable the content share.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="enable">The audio content share status.</param>
		public Boolean SetAudioContentShare(Boolean enable) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoVirtualAudioSourceSetAudioContentShareNative(objPtr, enable);

			return ret;
		}
		/// <summary>
		/// Sets the audio configs for the virtual audio source. The VidyoVirtualAudioSourceReconfigureCallback will trigger.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		/// <param name="configuration">The string in JSON format with virtual audio source configuration. <p>format - Specifies the media format. Possible values are: fl32 or in16. The default is fl32.</p> <p>Example: {'format' : 'in16'}.</p> <p>sampleRate - Specifies the audio sample rate. Possible values are: 48000, 32000 and 16000. The default is 32000.</p> <p>Example: {'sampleRate' : 48000}.</p> <p>numberOfChannels - Specifies the number of channels. Possible values are: 1 or 2. The default is 1.</p> <p>Example: {'numberOfChannels' : 2}.</p> <p>frameInterval - Specifies the frame interval in ms. Possible values are: 20 or 40. The default is 20.</p> <p>Example: {'frameInterval' : 40}.</p></param>
		public Boolean SetConfiguration(String configuration) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nConfiguration = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(configuration ?? string.Empty);
			Boolean ret = VidyoVirtualAudioSourceSetConfigurationNative(objPtr, nConfiguration);
			Marshal.FreeHGlobal(nConfiguration);

			return ret;
		}
		/// <summary>
		/// Unregisters virtual audio source event notifications.
		/// </summary>
		/// <param name="virtualAudioSource">The VidyoVirtualAudioSource object.</param>
		public Boolean UnregisterEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoVirtualAudioSourceUnregisterEventListenerNative(objPtr);

			return ret;
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(ExternalMediaBufferReleaseCallback))]
#endif
		private static void ExternalMediaBufferReleaseCallbackDelegate(IntPtr virtualAudioSource, IntPtr buffer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT size){
			var csVirtualAudioSourcePtr = virtualAudioSource != IntPtr.Zero ? VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource) : IntPtr.Zero;
			if(csVirtualAudioSourcePtr == IntPtr.Zero) return;
			var csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;

			var pointer = ByteArrayHelperSingleton.RawPointerToByteArray(buffer);
			csVirtualAudioSource?._mIRegisterEventListener?.ExternalMediaBufferReleaseCallback(pointer, size);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(ReconfigureCallback))]
#endif
		private static void ReconfigureCallbackDelegate(IntPtr virtualAudioSource, Device.DeviceState state){
			var csVirtualAudioSourcePtr = virtualAudioSource != IntPtr.Zero ? VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource) : IntPtr.Zero;
			if(csVirtualAudioSourcePtr == IntPtr.Zero) return;
			var csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;

			csVirtualAudioSource?._mIRegisterEventListener?.ReconfigureCallback(state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(StartCallback))]
#endif
		private static void StartCallbackDelegate(IntPtr virtualAudioSource){
			var csVirtualAudioSourcePtr = virtualAudioSource != IntPtr.Zero ? VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource) : IntPtr.Zero;
			if(csVirtualAudioSourcePtr == IntPtr.Zero) return;
			var csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;

			csVirtualAudioSource?._mIRegisterEventListener?.StartCallback();
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(StopCallback))]
#endif
		private static void StopCallbackDelegate(IntPtr virtualAudioSource){
			var csVirtualAudioSourcePtr = virtualAudioSource != IntPtr.Zero ? VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource) : IntPtr.Zero;
			if(csVirtualAudioSourcePtr == IntPtr.Zero) return;
			var csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;

			csVirtualAudioSource?._mIRegisterEventListener?.StopCallback();
		}
	};
}
