// 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 camera on the local endpoint.
	/// </summary>
	public class LocalCamera: IDisposable {
		private bool disposed = false; 
#if __IOS__
		const string importLib = "__Internal";
#else
		const string importLib = "libVidyoClient";
#endif
		private IntPtr objPtr; // opaque VidyoLocalCamera reference.
		private GCHandle objHandle; // weak VidyoLocalCamera reference.
		public IntPtr GetObjectPtr() {
			return objPtr;
		}
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern ulong VidyoLocalCameraAddToLocalRendererNative(IntPtr c, IntPtr localRenderer);

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

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

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraControlPTZNative(IntPtr c, int pan, int tilt, int zoom);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraControlPTZStartNative(IntPtr c, [MarshalAs(UnmanagedType.I4)]CameraControlCapabilities.CameraControlDirection cmd, ulong timeout);

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

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

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

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern LocalCameraTradeOffProfile VidyoLocalCameraGetFramerateTradeOffProfileNative(IntPtr c);

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

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern LocalCameraPosition VidyoLocalCameraGetPositionNative(IntPtr c);

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern LocalCameraTradeOffProfile VidyoLocalCameraGetResolutionTradeOffProfileNative(IntPtr c);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern LocalCameraTorchMode VidyoLocalCameraGetTorchModeNative(IntPtr c);

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoLocalCameraGetVideoCapabilitiesGetcapabilitiesArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoLocalCameraGetVideoCapabilitiesFreecapabilitiesArrayNative(IntPtr obj, int size);

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

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraGetVideoCapabilitiesAsyncNative(IntPtr c, OnGetVideoCapabilitiesComplete onComplete);

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

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

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

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraIsTorchModeSupportedNative(IntPtr c, [MarshalAs(UnmanagedType.I4)]LocalCameraTorchMode mode);

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

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

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetAspectRatioConstraintNative(IntPtr c, uint aspectRatioWidth, uint aspectRatioHeight);

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetBoundsConstraintNative(IntPtr c, uint minWidth, uint minHeight, uint maxWidth, uint maxHeight, ulong maxFrameInterval, ulong minFrameInterval, uint aspectRatioWidth, uint aspectRatioHeight, uint temporalSpatialTradeOff);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetCapabilitiesConstraintNative(IntPtr c, IntPtr capabilities, uint temporalSpatialTradeOff);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoLocalCameraSetCapabilitiesConstraintSetcapabilitiesArrayNative(IntPtr obj, IntPtr objArray, int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetConstraintsNative(IntPtr c, uint minWidth, uint minHeight, uint maxWidth, uint maxHeight, uint maxFrameInterval, uint minFrameInterval, uint aspectRatioWidth, uint aspectRatioHeight, uint temporalSpatialTradeOff, IntPtr capabilities);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoLocalCameraSetConstraintsSetcapabilitiesArrayNative(IntPtr obj, IntPtr objArray, int size);

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoLocalCameraSetControlDigitalNative(IntPtr c, Boolean digital);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetFramerateTradeOffProfileNative(IntPtr c, [MarshalAs(UnmanagedType.I4)]LocalCameraTradeOffProfile profile);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetMaxConstraintNative(IntPtr c, uint width, uint height, ulong frameInterval);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetNudgeTimesNative(IntPtr c, ulong panTime, ulong tiltTime, ulong zoomTime);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetOrientationNative(IntPtr c, [MarshalAs(UnmanagedType.I4)]Device.DeviceOrientation orientation, Boolean lockOrientation);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetPositionInLocalRendererNative(IntPtr c, IntPtr localRenderer, int x, int y, uint width, uint height, ulong frameInterval);

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

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

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetResolutionTradeOffProfileNative(IntPtr c, [MarshalAs(UnmanagedType.I4)]LocalCameraTradeOffProfile profile);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoLocalCameraSetTargetBitRateNative(IntPtr c, uint bitRate);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoLocalCameraSetTorchModeNative(IntPtr c, [MarshalAs(UnmanagedType.I4)]LocalCameraTorchMode mode);

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

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

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

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetVideoCapabilitiesComplete(IntPtr c, IntPtr capabilities);
		private OnGetVideoCapabilitiesComplete _mOnGetVideoCapabilitiesComplete = OnGetVideoCapabilitiesCompleteDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoLocalCameraOnGetVideoCapabilitiesCompleteGetcapabilitiesArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoLocalCameraOnGetVideoCapabilitiesCompleteFreecapabilitiesArrayNative(IntPtr obj, int size);

		/// <summary>
		/// Position of the camera.
		/// </summary>
		public enum LocalCameraPosition {
			/// <summary>Position is unknown.</summary>
			LocalcamerapositionUnknown,
			/// <summary>Facing towards the screen.</summary>
			LocalcamerapositionFront,
			/// <summary>Facing away from the screen.</summary>
			LocalcamerapositionBack
		}
		/// <summary>
		/// Represents torch modes for a mobile camera.
		/// </summary>
		public enum LocalCameraTorchMode {
			/// <summary>Torch is On.</summary>
			LocalcameraTORCHMODE_Off,
			/// <summary>Torch is Off.</summary>
			LocalcameraTORCHMODE_On,
			/// <summary>Error.</summary>
			LocalcameraTORCHMODE_None
		}
		/// <summary>
		/// Frame-rate and resolution tradeoff profile.
		/// </summary>
		public enum LocalCameraTradeOffProfile {
			/// <summary>High frame-rate, high resolution.</summary>
			LocalcameratradeoffprofileHigh,
			/// <summary>Balanced frame-rate and resolution.</summary>
			LocalcameratradeoffprofileMedium,
			/// <summary>Low frame-rate, low resolution.</summary>
			LocalcameratradeoffprofileLow,
			/// <summary>Try to guarantee max frame rate, max resolutioin.</summary>
			LocalcameratradeoffprofileMax
		}
		public interface IGetVideoCapabilitiesAsync{

			void OnGetVideoCapabilitiesComplete(List<VideoCapability> capabilities);
		}
		private IGetVideoCapabilitiesAsync _mIGetVideoCapabilitiesAsync;
		public LocalCamera(IntPtr other){
			objPtr = VidyoLocalCameraConstructCopyNative(other);
			if (objPtr != IntPtr.Zero) {
				objHandle = GCHandle.Alloc(this, GCHandleType.Weak);
				VidyoLocalCameraSetUserDataNative(objPtr, GCHandle.ToIntPtr(objHandle));
			}
		}
		~LocalCamera(){
			Dispose(false);
		}
		public void Dispose(){
			Dispose(true);
			GC.SuppressFinalize(this);
		}

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

			disposed = true;
			if(objPtr != IntPtr.Zero) {
				VidyoLocalCameraSetUserDataNative(objPtr, IntPtr.Zero);
				VidyoLocalCameraDestructNative(objPtr);
				objPtr = IntPtr.Zero;
			}

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

		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="localRenderer"></param>
		public ulong AddToLocalRenderer(LocalRenderer localRenderer) {
			if (objPtr == IntPtr.Zero) { return default; }

			ulong ret = VidyoLocalCameraAddToLocalRendererNative(objPtr, (localRenderer != null) ? localRenderer.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="remoteRenderer"></param>
		public Boolean AddToRemoteRenderer(RemoteRenderer remoteRenderer) {
			if (objPtr == IntPtr.Zero) { return default; }

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

			return ret;
		}
		/// <summary>
		/// Allows the PTZ conrol of the camera by remote participants.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="allow">Allow or prohibit camera control.</param>
		public Boolean AllowRemoteCameraControl(Boolean allow) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraAllowRemoteCameraControlNative(objPtr, allow);

			return ret;
		}
		/// <summary>
		/// Send the PTZ Nudge commands to the local camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="pan">Number of nudges to pan the camera.</param>
		/// <param name="tilt">Number of nudges to tilt the camera.</param>
		/// <param name="zoom">Number of nudges to zoom the camera.</param>
		public Boolean ControlPTZ(int pan, int tilt, int zoom) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraControlPTZNative(objPtr, pan, tilt, zoom);

			return ret;
		}
		/// <summary>
		/// Send PTZ Start command to the local camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="cmd">PTZ command.</param>
		/// <param name="timeout">Amount of time in nanoseconds at which camera will be moving in the specified direction.</param>
		public Boolean ControlPTZStart(CameraControlCapabilities.CameraControlDirection cmd, ulong timeout) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraControlPTZStartNative(objPtr, cmd, timeout);

			return ret;
		}
		/// <summary>
		/// Send PTZ Stop command to the local camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public Boolean ControlPTZStop() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraControlPTZStopNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets the backlight compensation state.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public Boolean GetBacklightCompensation() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraGetBacklightCompensationNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets camera control capabilities.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public CameraControlCapabilities GetControlCapabilities() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoLocalCameraGetControlCapabilitiesNative(objPtr);
			CameraControlCapabilities csRet = new CameraControlCapabilities(ret);

			return csRet;
		}
		/// <summary>
		/// Gets the frame rate v.s. video quality tradeoff profile.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public LocalCameraTradeOffProfile GetFramerateTradeOffProfile() {
			if (objPtr == IntPtr.Zero) { return default; }

			LocalCameraTradeOffProfile ret = VidyoLocalCameraGetFramerateTradeOffProfileNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets the unique ID of the camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public String GetId() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoLocalCameraGetIdNative(objPtr);

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

			IntPtr ret = VidyoLocalCameraGetNameNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets the position of the camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public LocalCameraPosition GetPosition() {
			if (objPtr == IntPtr.Zero) { return default; }

			LocalCameraPosition ret = VidyoLocalCameraGetPositionNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets the preview label of the camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public String GetPreviewLabel() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoLocalCameraGetPreviewLabelNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets the resolution v.s. video quality tradeoff profile.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public LocalCameraTradeOffProfile GetResolutionTradeOffProfile() {
			if (objPtr == IntPtr.Zero) { return default; }

			LocalCameraTradeOffProfile ret = VidyoLocalCameraGetResolutionTradeOffProfileNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Returns the current torch mode of camera. This function is only available if VidyoLocalCameraHasTorch returns true.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public LocalCameraTorchMode GetTorchMode() {
			if (objPtr == IntPtr.Zero) { return default; }

			LocalCameraTorchMode ret = VidyoLocalCameraGetTorchModeNative(objPtr);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="capabilities"></param>
		public Boolean GetVideoCapabilities(ref List<VideoCapability> capabilities) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nListCapabilities = VidyoLocalCameraVectorVidyoVideoCapabilityAllocateNative();

			Boolean ret = VidyoLocalCameraGetVideoCapabilitiesNative(objPtr, nListCapabilities);

			List<VideoCapability> csCapabilities = new List<VideoCapability>();
			var nCapabilitiesSize = 0;
			var nCapabilities = VidyoLocalCameraGetVideoCapabilitiesGetcapabilitiesArrayNative(nListCapabilities, ref nCapabilitiesSize);
			var nCapabilitiesIndex = 0;
			while (nCapabilitiesIndex < nCapabilitiesSize) {
				VideoCapability csTcapabilities = new VideoCapability(Marshal.ReadIntPtr(nCapabilities + (nCapabilitiesIndex * Marshal.SizeOf(nCapabilities))));
				csCapabilities.Add(csTcapabilities);
				nCapabilitiesIndex++;
			}

			capabilities = csCapabilities;
			VidyoLocalCameraGetVideoCapabilitiesFreecapabilitiesArrayNative(nCapabilities, nCapabilitiesSize);
			VidyoLocalCameraVectorVidyoVideoCapabilityDeallocateNative(nListCapabilities);

			return ret;
		}
		/// <summary>
		/// Gets supported video capabilities.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="onComplete">The callback that is triggered when getting video capabilities completes.</param>
		public Boolean GetVideoCapabilitiesAsync(IGetVideoCapabilitiesAsync _iIGetVideoCapabilitiesAsync) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetVideoCapabilitiesAsync = _iIGetVideoCapabilitiesAsync;

			Boolean ret = VidyoLocalCameraGetVideoCapabilitiesAsyncNative(objPtr, _mOnGetVideoCapabilitiesComplete);

			return ret;
		}
		/// <summary>
		/// Determines whether the camera has a torch.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public Boolean HasTorch() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraHasTorchNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Checks if the camera control to digital only.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public Boolean IsControlDigital() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraIsControlDigitalNative(objPtr);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public Boolean IsPaused() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraIsPausedNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Checks if the camera is suspended.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public Boolean IsSuspended() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraIsSuspendedNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Determines whether camera supports a particular torch mode. This function is only available if VidyoLocalCameraHasTorch returns true.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="mode">Torch mode.</param>
		public Boolean IsTorchModeSupported(LocalCameraTorchMode mode) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraIsTorchModeSupportedNative(objPtr, mode);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="localRenderer"></param>
		public Boolean RemoveFromLocalRenderer(LocalRenderer localRenderer) {
			if (objPtr == IntPtr.Zero) { return default; }

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

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="remoteRenderer"></param>
		public Boolean RemoveFromRemoteRenderer(RemoteRenderer remoteRenderer) {
			if (objPtr == IntPtr.Zero) { return default; }

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

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		public void Resume() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoLocalCameraResumeNative(objPtr);
		}
		/// <summary>
		/// Sets the aspect ratio constraint on the camera which will adjust local camera frames to match.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="aspectRatioWidth">Width of the aspect ratio.</param>
		/// <param name="aspectRatioHeight">Height of the aspect ration.</param>
		public Boolean SetAspectRatioConstraint(uint aspectRatioWidth, uint aspectRatioHeight) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetAspectRatioConstraintNative(objPtr, aspectRatioWidth, aspectRatioHeight);

			return ret;
		}
		/// <summary>
		/// Set the backlight compensation which improves the dynamic range of the image when the subject is dark but the background is bright.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="backlightCompensation">Compensate for the bright backlighting.</param>
		public Boolean SetBacklightCompensation(Boolean backlightCompensation) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetBacklightCompensationNative(objPtr, backlightCompensation);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="minWidth"></param>
		/// <param name="minHeight"></param>
		/// <param name="maxWidth"></param>
		/// <param name="maxHeight"></param>
		/// <param name="maxFrameInterval">Maximum time between frames in ns. This is a hint to the resource manager for how it decides to allocate internal resources (cpu,mem,etc)</param>
		/// <param name="minFrameInterval">Minimum time between frames in ns. This is a hint to the resource manager for how it decides to allocate internal resources (cpu,mem,etc)</param>
		/// <param name="aspectRatioWidth"></param>
		/// <param name="aspectRatioHeight"></param>
		/// <param name="temporalSpatialTradeOff"></param>
		public Boolean SetBoundsConstraint(uint minWidth, uint minHeight, uint maxWidth, uint maxHeight, ulong maxFrameInterval, ulong minFrameInterval, uint aspectRatioWidth, uint aspectRatioHeight, uint temporalSpatialTradeOff) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetBoundsConstraintNative(objPtr, minWidth, minHeight, maxWidth, maxHeight, maxFrameInterval, minFrameInterval, aspectRatioWidth, aspectRatioHeight, temporalSpatialTradeOff);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="capabilities"></param>
		/// <param name="temporalSpatialTradeOff"></param>
		public Boolean SetCapabilitiesConstraint(List<VideoCapability> capabilities, uint temporalSpatialTradeOff) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nListCapabilities = VidyoLocalCameraVectorVidyoVideoCapabilityAllocateNative();

			IntPtr nCapabilities = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * capabilities.Count);
			int nCapabilitiesSize = 0;
			foreach (VideoCapability iter in capabilities) {
				Marshal.WriteIntPtr(nCapabilities + (nCapabilitiesSize * Marshal.SizeOf<IntPtr>()), iter.GetObjectPtr());
				nCapabilitiesSize++;
			}
			VidyoLocalCameraSetCapabilitiesConstraintSetcapabilitiesArrayNative(nListCapabilities, nCapabilities, nCapabilitiesSize);
			Marshal.FreeHGlobal(nCapabilities);
			Boolean ret = VidyoLocalCameraSetCapabilitiesConstraintNative(objPtr, nListCapabilities, temporalSpatialTradeOff);
			VidyoLocalCameraVectorVidyoVideoCapabilityDeallocateNative(nListCapabilities);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="minWidth"></param>
		/// <param name="minHeight"></param>
		/// <param name="maxWidth"></param>
		/// <param name="maxHeight"></param>
		/// <param name="maxFrameInterval">Maximum time between frames in ns. This is a hint to the resource manager for how it decides to allocate internal resources (cpu,mem,etc)</param>
		/// <param name="minFrameInterval">Minimum time between frames in ns. This is a hint to the resource manager for how it decides to allocate internal resources (cpu,mem,etc)</param>
		/// <param name="aspectRatioWidth"></param>
		/// <param name="aspectRatioHeight"></param>
		/// <param name="temporalSpatialTradeOff"></param>
		/// <param name="capabilities"></param>
		public Boolean SetConstraints(uint minWidth, uint minHeight, uint maxWidth, uint maxHeight, uint maxFrameInterval, uint minFrameInterval, uint aspectRatioWidth, uint aspectRatioHeight, uint temporalSpatialTradeOff, List<VideoCapability> capabilities) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nListCapabilities = VidyoLocalCameraVectorVidyoVideoCapabilityAllocateNative();

			IntPtr nCapabilities = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * capabilities.Count);
			int nCapabilitiesSize = 0;
			foreach (VideoCapability iter in capabilities) {
				Marshal.WriteIntPtr(nCapabilities + (nCapabilitiesSize * Marshal.SizeOf<IntPtr>()), iter.GetObjectPtr());
				nCapabilitiesSize++;
			}
			VidyoLocalCameraSetConstraintsSetcapabilitiesArrayNative(nListCapabilities, nCapabilities, nCapabilitiesSize);
			Marshal.FreeHGlobal(nCapabilities);
			Boolean ret = VidyoLocalCameraSetConstraintsNative(objPtr, minWidth, minHeight, maxWidth, maxHeight, maxFrameInterval, minFrameInterval, aspectRatioWidth, aspectRatioHeight, temporalSpatialTradeOff, nListCapabilities);
			VidyoLocalCameraVectorVidyoVideoCapabilityDeallocateNative(nListCapabilities);

			return ret;
		}
		/// <summary>
		/// Sets camera control capabilities.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="caps">The VidyoCameraControlCapabilities object.</param>
		public Boolean SetControlCapabilities(CameraControlCapabilities caps) {
			if (objPtr == IntPtr.Zero) { return default; }

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

			return ret;
		}
		/// <summary>
		/// Sets the camera control to digital only.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="digital">Forces digital control.</param>
		public void SetControlDigital(Boolean digital) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoLocalCameraSetControlDigitalNative(objPtr, digital);
		}
		/// <summary>
		/// Sets the frame rate v.s. video quality tradeoff profile.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="profile">Frame-rate tradeoff profile.</param>
		public Boolean SetFramerateTradeOffProfile(LocalCameraTradeOffProfile profile) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetFramerateTradeOffProfileNative(objPtr, profile);

			return ret;
		}
		/// <summary>
		/// Sets the maximum resolution and framerate constraint on the local camera. This overrides the defaults which are based on the CPU profile of the endpoint. The maximum if not an exact match for the camera resolution will be chosen by the aproximate closest resolution based on calculations that include the width, height and frameInterval.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="width">Maximum width.</param>
		/// <param name="height">Maximum height.</param>
		/// <param name="frameInterval">Maximum frame interval. Setting to 0 selects the fastest frame rate.</param>
		public Boolean SetMaxConstraint(uint width, uint height, ulong frameInterval) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetMaxConstraintNative(objPtr, width, height, frameInterval);

			return ret;
		}
		/// <summary>
		/// Set the time delta that the camera moves left/right (pan), up/down (tilt), and/or in/out (zoom) for each nudge if the camera supports only start/stop (relative) behavior.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="panTime">The time delta to pan the camera per nudge.</param>
		/// <param name="tiltTime">The time delta to tilt the camera per nudge.</param>
		/// <param name="zoomTime">The time delta to zoom the camera per nudge.</param>
		public Boolean SetNudgeTimes(ulong panTime, ulong tiltTime, ulong zoomTime) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetNudgeTimesNative(objPtr, panTime, tiltTime, zoomTime);

			return ret;
		}
		/// <summary>
		/// Sets relative orientation of a local camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="orientation">Orientation of the camera.</param>
		/// <param name="lockOrientation">Lock the camera in the specified orientation.</param>
		public Boolean SetOrientation(Device.DeviceOrientation orientation, Boolean lockOrientation) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetOrientationNative(objPtr, orientation, lockOrientation);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="localRenderer"></param>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <param name="width"></param>
		/// <param name="height"></param>
		/// <param name="frameInterval"></param>
		public Boolean SetPositionInLocalRenderer(LocalRenderer localRenderer, int x, int y, uint width, uint height, ulong frameInterval) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetPositionInLocalRendererNative(objPtr, (localRenderer != null) ? localRenderer.GetObjectPtr():IntPtr.Zero, x, y, width, height, frameInterval);

			return ret;
		}
		/// <summary>
		/// Set the preview label of the camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="previewLabel">Display name to set on the camera.</param>
		public Boolean SetPreviewLabel(String previewLabel) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nPreviewLabel = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(previewLabel ?? string.Empty);
			Boolean ret = VidyoLocalCameraSetPreviewLabelNative(objPtr, nPreviewLabel);
			Marshal.FreeHGlobal(nPreviewLabel);

			return ret;
		}
		/// <summary>
		/// Set the preview label of the camera stream.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="previewLabel">Display name to set on the camera stream. Camera and Content labels are stored separately.</param>
		public Boolean SetPreviewStreamLabel(String previewLabel) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nPreviewLabel = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(previewLabel ?? string.Empty);
			Boolean ret = VidyoLocalCameraSetPreviewStreamLabelNative(objPtr, nPreviewLabel);
			Marshal.FreeHGlobal(nPreviewLabel);

			return ret;
		}
		/// <summary>
		/// Sets the resolution v.s. video quality trade off profile.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="profile">Resolution tradeoff profile.</param>
		public Boolean SetResolutionTradeOffProfile(LocalCameraTradeOffProfile profile) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetResolutionTradeOffProfileNative(objPtr, profile);

			return ret;
		}
		/// <summary>
		/// Sets the target send bit rate for a local camera.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="bitRate">The target send bit rate in bits per second.</param>
		public void SetTargetBitRate(uint bitRate) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoLocalCameraSetTargetBitRateNative(objPtr, bitRate);
		}
		/// <summary>
		/// Set the torch mode for camera. This function is only available if VidyoLocalCameraHasTorch returns true and VidyoLocalCameraGetTorchMode called with the torch mode returns true.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="mode">Torch mode.</param>
		public Boolean SetTorchMode(LocalCameraTorchMode mode) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraSetTorchModeNative(objPtr, mode);

			return ret;
		}
		/// <summary>
		/// Shows camera control when rendering preview.
		/// </summary>
		/// <param name="c">The VidyoLocalCamera object.</param>
		/// <param name="show">Show or hide camera controls.</param>
		public Boolean ShowCameraControl(Boolean show) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoLocalCameraShowCameraControlNative(objPtr, show);

			return ret;
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetVideoCapabilitiesComplete))]
#endif
		private static void OnGetVideoCapabilitiesCompleteDelegate(IntPtr c, IntPtr capabilities){
			var csCPtr = c != IntPtr.Zero ? VidyoLocalCameraGetUserDataNative(c) : IntPtr.Zero;
			if(csCPtr == IntPtr.Zero) return;
			var csC = (LocalCamera)GCHandle.FromIntPtr(csCPtr).Target;

			List<VideoCapability> csCapabilities = new List<VideoCapability>();
			var nCapabilitiesSize = 0;
			var nCapabilities = VidyoLocalCameraOnGetVideoCapabilitiesCompleteGetcapabilitiesArrayNative(capabilities, ref nCapabilitiesSize);
			var nCapabilitiesIndex = 0;
			while (nCapabilitiesIndex < nCapabilitiesSize) {
				VideoCapability csTcapabilities = new VideoCapability(Marshal.ReadIntPtr(nCapabilities + (nCapabilitiesIndex * Marshal.SizeOf(nCapabilities))));
				csCapabilities.Add(csTcapabilities);
				nCapabilitiesIndex++;
			}

			csC?._mIGetVideoCapabilitiesAsync?.OnGetVideoCapabilitiesComplete(csCapabilities);
			VidyoLocalCameraOnGetVideoCapabilitiesCompleteFreecapabilitiesArrayNative(nCapabilities, nCapabilitiesSize);
		}
	};
}
