using System;
using BioAPI.include.bioapi_type;
using System.Runtime.InteropServices;

namespace BioAPI.framework.h_layer
{
	public class manage_interface
	{
		public static BioAPI_RETURN BioAPI_Init(
			BioAPI_VERSION Version,		// [in]
			int Reserved1,				// [in]
			object Reserved2,			// [in]
			int Reserved3,				// [in]
			object Reserved4)			// [in]
		{
			return BioAPIWin32.BioAPI_Init(Version, 0, new IntPtr(0),
				0, new IntPtr(0));
		}

		public static BioAPI_RETURN BioAPI_Terminate()
		{
			return BioAPIWin32.BioAPI_Terminate();
		}

		public static BioAPI_RETURN BioAPI_ModuleLoad(
			BioAPI_UUID ModuleUuid,							// [in]
			uint Reserved,									// [in]
			BioAPI_ModuleEventHandler AppNotifyCallback,	// [in/optional]
			byte[] AppNotifyCallbackCtx)					// [in/optional]
		{
			int len = 0;
			IntPtr ptrModuleUuid = IntPtr.Zero;
			IntPtr ptrAppNotifyCallbackCtx = IntPtr.Zero;

			if (ModuleUuid != null) ptrModuleUuid =	ModuleUuid.DoMarshal(ref len);
			if (AppNotifyCallbackCtx != null) ptrAppNotifyCallbackCtx = BioAPIWin32.MarshalByteArray(AppNotifyCallbackCtx);;		
			
			BioAPI_RETURN bioReturn = BioAPIWin32.BioAPI_ModuleLoad(
				ptrModuleUuid, 
				0, 
				AppNotifyCallback, 
				ptrAppNotifyCallbackCtx);

			if (ptrModuleUuid != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrModuleUuid );
			if (ptrAppNotifyCallbackCtx != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrAppNotifyCallbackCtx );
			return bioReturn;
		}

		//		BioAPI_RETURN BioAPI BioAPI_ModuleUnload(
		//			const BioAPI_UUID *ModuleUuid,
		//			BioAPI_ModuleEventHandler AppNotifyCallback,
		//			void* AppNotifyCallbackCtx)
		public static BioAPI_RETURN BioAPI_ModuleUnload(
			BioAPI_UUID ModuleUuid,							// [in]
			BioAPI_ModuleEventHandler AppNotifyCallback,	// [in/optional]
			byte[] AppNotifyCallbackCtx)					// [in/optional]
		{
			int len = 0;
			IntPtr ptrModuleUuid = IntPtr.Zero;
			IntPtr ptrAppNotifyCallbackCtx = IntPtr.Zero;

			if (ModuleUuid != null) ptrModuleUuid =	ModuleUuid.DoMarshal(ref len);
			if (AppNotifyCallbackCtx != null) ptrAppNotifyCallbackCtx = BioAPIWin32.MarshalByteArray(AppNotifyCallbackCtx);;		

			BioAPI_RETURN bioReturn = BioAPIWin32.BioAPI_ModuleUnload(
				ptrModuleUuid, 
				AppNotifyCallback, 
				ptrAppNotifyCallbackCtx);

			if (ptrModuleUuid != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrModuleUuid );
			if (ptrAppNotifyCallbackCtx != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrAppNotifyCallbackCtx );

			return bioReturn;
		}

		public static BioAPI_RETURN BioAPI_ModuleAttach(
			BioAPI_UUID ModuleUuid,						// [in]
			BioAPI_VERSION Version,						// [in]
			BioAPI_MEMORY_FUNCS MemoryFuncs,			// [in]
			uint DeviceID,								// [in]
			uint Reserved1,								// [in]
			uint Reserved2,								// [in]
			uint Reserved3,								// [in]
			BioAPI_FUNC_NAME_ADDR [] FunctionTable,		// [in/out/optional]
			uint NumFunctionTable,						// [in]
			object Reserved4,							// [in]
			ref BioAPI_HANDLE NewModuleHandle)			// [out]
		{
			int len = 0;
			IntPtr ptrModuleUuid = IntPtr.Zero;

			if (ModuleUuid != null) ptrModuleUuid =	ModuleUuid.DoMarshal(ref len);

			BioAPI_RETURN bioReturn = BioAPIWin32.BioAPI_ModuleAttach(
				ptrModuleUuid, Version, MemoryFuncs, DeviceID,
				0, 0, 0,
				FunctionTable, NumFunctionTable, 
				IntPtr.Zero,  
				ref NewModuleHandle);

			if (ptrModuleUuid != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrModuleUuid );
			return bioReturn;
		}

		public static BioAPI_RETURN BioAPI_ModuleDetach( BioAPI_HANDLE ModuleHandle )
		{ return BioAPIWin32.BioAPI_ModuleDetach((uint) ModuleHandle); }

		public static BioAPI_RETURN BioAPI_QueryDevice(
			BioAPI_HANDLE ModuleHandle,					// [in]
			BioAPI_SERVICE_UID DeviceUID)				// [out]
		{
			return BioAPIWin32.BioAPI_QueryDevice(ModuleHandle, DeviceUID);
		}
	}
}