// 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>
	/// A wrapper class for Local and Remote devices.
	/// </summary>
	public class Device: IDisposable {
		private bool disposed = false; 
#if __IOS__
		const string importLib = "__Internal";
#else
		const string importLib = "libVidyoClient";
#endif
		private IntPtr objPtr; // opaque VidyoDevice reference.
		private GCHandle objHandle; // weak VidyoDevice reference.
		public IntPtr GetObjectPtr() {
			return objPtr;
		}
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoDeviceConstructCopyNative(IntPtr other);

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

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

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

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern DeviceType VidyoDeviceGetTypeNative(IntPtr d);

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

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

		/// <summary>
		/// Sets the type of the auido signal which determines how it is processed such as noise suppression, echo cancellation etc.
		/// </summary>
		public enum DeviceAudioSignalType {
			/// <summary>Default type which will do echo cancellation, noise suppresstion etc.</summary>
			DeviceaudiosignaltypeVoice,
			/// <summary>Does not alter audio singal by having all the audio processing disabled.</summary>
			DeviceaudiosignaltypeUnprocessed
		}
		/// <summary>
		/// Orientations of the device.
		/// </summary>
		public enum DeviceOrientation {
			/// <summary>Up</summary>
			DeviceorientationUP,
			/// <summary>Down</summary>
			DeviceorientationDOWN,
			/// <summary>Left</summary>
			DeviceorientationLEFT,
			/// <summary>Right</summary>
			DeviceorientationRIGHT
		}
		/// <summary>
		/// Operational state of a device.
		/// </summary>
		public enum DeviceState {
			/// <summary>The device was added to the system.</summary>
			DevicestateAdded,
			/// <summary>The device was removed from the system.</summary>
			DevicestateRemoved,
			/// <summary>The device started successfully.</summary>
			DevicestateStarted,
			/// <summary>The device stopped.</summary>
			DevicestateStopped,
			/// <summary>The device was suspended and the frames can no longer be captured.</summary>
			DevicestateSuspended,
			/// <summary>The device was unsuspended.</summary>
			DevicestateUnsuspended,
			/// <summary>The device is in use by another application.</summary>
			DevicestateInUse,
			/// <summary>The device that was previousely in use is now available.</summary>
			DevicestateAvailable,
			/// <summary>The device was paused (muted) and no media will be sent.</summary>
			DevicestatePaused,
			/// <summary>The device was resumed (unmuted) and media will be sent.</summary>
			DevicestateResumed,
			/// <summary>The device is under Remote control (i.e if paused, can only be resumed by remote controller.</summary>
			DevicestateControlledByRemoteEntity,
			/// <summary>The device is not under Remote control anymore.</summary>
			DevicestateNotControlledByRemoteEntity,
			/// <summary>The device PTZ is controllable.</summary>
			DevicestateControllable,
			/// <summary>The device PTZ is not controllable.</summary>
			DevicestateNotControllable,
			/// <summary>The device default device has changed.</summary>
			DevicestateDefaultChanged,
			/// <summary>The device configured successfully.</summary>
			DevicestateConfigureSuccess,
			/// <summary>The device configuring failed.</summary>
			DevicestateConfigureError,
			/// <summary>The device configuring changed.</summary>
			DevicestateConfigurationChanged,
			/// <summary>The device failed.</summary>
			DevicestateError,
			/// <summary>The device started successfully but cannot produce the data.</summary>
			DevicestateUnableGetDeviceData,
			/// <summary>The device started successfully but sends unexpected events.</summary>
			DevicestateUnexpectedEvent
		}
		/// <summary>
		/// Device type.
		/// </summary>
		public enum DeviceType {
			/// <summary>local camera device.</summary>
			DevicetypeLocalCamera,
			/// <summary>local microphone device.</summary>
			DevicetypeLocalMicrophone,
			/// <summary>local screen device.</summary>
			DevicetypeLocalMonitor,
			/// <summary>local application window device.</summary>
			DevicetypeLocalWindowShare,
			/// <summary>local speaker device.</summary>
			DevicetypeLocalSpeaker,
			/// <summary>local renderer device.</summary>
			DevicetypeLocalRenderer,
			/// <summary>remote camera device.</summary>
			DevicetypeRemoteCamera,
			/// <summary>remote microphone device.</summary>
			DevicetypeRemoteMicrophone,
			/// <summary>remote application window device.</summary>
			DevicetypeRemoteWindowShare,
			/// <summary>remote speaker device.</summary>
			DevicetypeRemoteSpeaker,
			/// <summary>remote renderer device.</summary>
			DevicetypeRemoteRenderer,
			/// <summary>virtual video source.</summary>
			DevicetypeVirtualVideoSource,
			/// <summary>virtual audio source.</summary>
			DevicetypeVirtualAudioSource
		}
		public Device(IntPtr other){
			objPtr = VidyoDeviceConstructCopyNative(other);
			if (objPtr != IntPtr.Zero) {
				objHandle = GCHandle.Alloc(this, GCHandleType.Weak);
				VidyoDeviceSetUserDataNative(objPtr, GCHandle.ToIntPtr(objHandle));
			}
		}
		~Device(){
			Dispose(false);
		}
		public void Dispose(){
			Dispose(true);
			GC.SuppressFinalize(this);
		}

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

			disposed = true;
			if(objPtr != IntPtr.Zero) {
				VidyoDeviceSetUserDataNative(objPtr, IntPtr.Zero);
				VidyoDeviceDestructNative(objPtr);
				objPtr = IntPtr.Zero;
			}

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

		/// <summary>
		/// Compare the values of two derived devices for equality.
		/// </summary>
		/// <param name="obj">The VidyoDevice object comparing against.</param>
		/// <param name="other">The VidyoDevice object comparing.</param>
		public Boolean DerivedEqual() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoDeviceDerivedEqualNative(objPtr, objPtr);

			return ret;
		}
		/// <summary>
		/// Gets the device id.
		/// </summary>
		/// <param name="d">The VidyoDevice object.</param>
		public String GetId() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoDeviceGetIdNative(objPtr);

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

			IntPtr ret = VidyoDeviceGetNameNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets the device type.
		/// </summary>
		/// <param name="d">The VidyoDevice object.</param>
		public DeviceType GetType() {
			if (objPtr == IntPtr.Zero) { return default; }

			DeviceType ret = VidyoDeviceGetTypeNative(objPtr);

			return ret;
		}
	};
}
