using System;
using System.IO;
using System.Runtime.InteropServices;
using BioAPI.include.bioapi_type;
using BioAPI.include.bioapi_schema;
using System.Runtime.Serialization.Formatters.Binary;

namespace BioAPI.framework.h_layer
{
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	public struct BioAPI_BSP_SCHEMA_MARSHAL 
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)]
		public byte[] ModuleId;
		public uint DeviceId;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string BSPName;
		public BioAPI_VERSION SpecVersion;
		public BioAPI_VERSION ProductVersion;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string Vendor;
		[MarshalAs(UnmanagedType.ByValArray, SizeConst= (int) Consts.MDSU_MAX_VALUE_COUNT * 2)]
		public ushort [] BspSupportedFormats;
		public uint NumSupportedFormats;
		public uint FactorsMask;
		public uint Operations;
		public uint Options;
		public uint PayloadPolicy;
		public uint MaxPayloadSize;
		public int DefaultVerifyTimeout;
		public int DefaultIdentifyTimeout;
		public int DefaultCaptureTimeout;
		public int DefaultEnrollTimeout;
		public uint MaxBspDbSize;
		public uint MaxIdentify;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string Description;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=(int) Consts.MAX_PATH )]
		public string Path;
		public void Unmarshal(BioAPI_BSP_SCHEMA to)
		{
			to.ModuleId.Assign(ModuleId);
			to.DeviceId = DeviceId;
			to.BSPName = BSPName;
			to.SpecVersion = SpecVersion;
			to.ProductVersion = ProductVersion;
			to.Vendor = Vendor;
			for (int i = 0; i < (int) Consts.MDSU_MAX_VALUE_COUNT; i++)
			{
				to.BspSupportedFormats[i].Assign(BspSupportedFormats[2*i], BspSupportedFormats[2*i+1]);
			}
			to.NumSupportedFormats = NumSupportedFormats;
			to.FactorsMask = FactorsMask;
			to.Operations = Operations;
			to.Options = Options;
			to.PayloadPolicy = PayloadPolicy;
			to.MaxPayloadSize = MaxPayloadSize;
			to.DefaultVerifyTimeout = DefaultVerifyTimeout;
			to.DefaultIdentifyTimeout = DefaultIdentifyTimeout;
			to.DefaultCaptureTimeout = DefaultCaptureTimeout;
			to.DefaultEnrollTimeout = DefaultEnrollTimeout;
			to.MaxBspDbSize = MaxBspDbSize;
			to.MaxIdentify = Operations;
			to.Description = Description;
			to.Path = Path;
		}
	}    

	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	public struct BioAPI_DEVICE_SCHEMA_MARSHAL 
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)]
		public byte[] ModuleId;
		public uint DeviceId;
		[MarshalAs(UnmanagedType.ByValArray, SizeConst= (int) Consts.MDSU_MAX_VALUE_COUNT * 2)]
		public ushort [] DeviceSupportedFormats;
		public uint NumSupportedFormats;
		public uint SupportedEvents;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string DeviceVendor;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string DeviceDescription;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string DeviceSerialNumber;
		public BioAPI_VERSION DeviceHardwareVersion;
		public BioAPI_VERSION DeviceFirmwareVersion;
		public uint AuthenticatedDevice;

		//public void DoUnmarshal(BioAPI_BSP_SCHEMA to)
		public void Unmarshal(BioAPI_DEVICE_SCHEMA to)
		{
			to.ModuleId.Assign(ModuleId);
			to.DeviceId = (BioAPI_DEVICE_ID) DeviceId;
			for (int i = 0; i < (int) Consts.MDSU_MAX_VALUE_COUNT; i++)
			{
				to.DeviceSupportedFormats[i].Assign(DeviceSupportedFormats[2*i], DeviceSupportedFormats[2*i+1]);
			}
			to.NumSupportedFormats = NumSupportedFormats;
			to.SupportedEvents = SupportedEvents;
			to.DeviceVendor = DeviceVendor;
			to.DeviceDescription = DeviceDescription;
			to.DeviceSerialNumber = DeviceSerialNumber;
			to.DeviceHardwareVersion = DeviceHardwareVersion;
			to.DeviceFirmwareVersion = DeviceFirmwareVersion;
			to.AuthenticatedDevice = (BioAPI_BOOL) AuthenticatedDevice;
		}
	}    

	//	typedef struct _bioapi_h_level_framework_schema
	//			{
	//				BioAPI_UUID ModuleId;
	//				CSSM_STRING ModuleName;
	//				BioAPI_VERSION SpecVersion;
	//				BioAPI_VERSION ProdVersion;
	//				CSSM_STRING Vendor;
	//				CSSM_STRING Description;
	//			} BioAPI_H_LEVEL_FRAMEWORK_SCHEMA;
	//	
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
	public struct BioAPI_H_LEVEL_FRAMEWORK_SCHEMA_MARSHAL 
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)]
		public byte[] ModuleId;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string ModuleName;
		public BioAPI_VERSION SpecVersion;
		public BioAPI_VERSION ProdVersion;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string Vendor;
		[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=68 )]
		public string Description;

		public void Unmarshal(BioAPI_H_LEVEL_FRAMEWORK_SCHEMA to)
		{
			to.ModuleId.Assign(ModuleId);
			to.ModuleName = ModuleName;
			to.SpecVersion = SpecVersion;
			to.ProdVersion = ProdVersion;
			to.Vendor = Vendor;
			to.Description = Description;
		}
	}    

	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_INPUT_BIR_Marshal 
	{
		public BioAPI_INPUT_BIR_FORM Form;
		public IntPtr ptrInputBIR;

		public BioAPI_INPUT_BIR_Marshal(BioAPI_INPUT_BIR source)
		{
			IntPtr ptr = IntPtr.Zero;
			int len = 0;
			this.Form = source.Form;

			switch (Form)
			{
				case BioAPI_INPUT_BIR_FORM.BioAPI_DATABASE_ID_INPUT:
					ptr = source.InputBIR.BIRinDb.DoMarshal(ref len);
					break;
				case BioAPI_INPUT_BIR_FORM.BioAPI_BIR_HANDLE_INPUT:
					ptr = Marshal.AllocCoTaskMem( Marshal.SizeOf(Type.GetType("System.Int32")));
					Marshal.WriteInt32(ptr, 0, (int) source.InputBIR.BIRinBSP);
					break;
				case BioAPI_INPUT_BIR_FORM.BioAPI_FULLBIR_INPUT:
					ptr = source.InputBIR.BIR.DoMarshal(ref len);
					break;
			}
			ptrInputBIR = ptr;
		}

		public void Unmarshal(BioAPI_INPUT_BIR dest, bool fDeleteOld)
		{
			int len  = 0;
			IntPtr ptr = ptrInputBIR;
			dest.Form = Form;

			if (ptr == IntPtr.Zero) return;

			switch (Form)
			{
				case BioAPI_INPUT_BIR_FORM.BioAPI_DATABASE_ID_INPUT:
					dest.InputBIR.BIRinDb.DoUnmarshal(ptr, ref len, false);
					break;
				case BioAPI_INPUT_BIR_FORM.BioAPI_BIR_HANDLE_INPUT:
					dest.InputBIR.BIRinBSP = (BioAPI_BIR_HANDLE) Marshal.ReadInt32(ptr, 0);
					break;
				case BioAPI_INPUT_BIR_FORM.BioAPI_FULLBIR_INPUT:
					dest.InputBIR.BIR.DoUnmarshal(ptr, ref len, false);
					break;
			}
			if (fDeleteOld)  { Marshal.FreeCoTaskMem( ptr ); }
		}

		public void Dispose()
		{ if (ptrInputBIR != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrInputBIR ); }

	}

	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_CANDIDATE_Marshal 
	{
		public BioAPI_IDENTIFY_POPULATION_TYPE Type;
		public IntPtr ptrBIR;
		public BioAPI_FAR FARAchieved; 
		public BioAPI_FRR FRRAchieved; 

		public BioAPI_CANDIDATE_Marshal(BioAPI_CANDIDATE source)
		{
			IntPtr ptr = IntPtr.Zero;
			int len = 0;
			Type = source.Type;
			FARAchieved = source.FARAchieved;
			FRRAchieved = source.FRRAchieved;

			switch (Type)
			{
				case BioAPI_IDENTIFY_POPULATION_TYPE.BioAPI_DB_TYPE:
					ptr = source.BIR.BIRInDataBase.DoMarshal(ref len);
					break;
				case BioAPI_IDENTIFY_POPULATION_TYPE.BioAPI_ARRAY_TYPE:
					ptr = Marshal.AllocCoTaskMem( Marshal.SizeOf(System.Type.GetType("System.Int32")));
					Marshal.WriteInt32(ptr, 0, (int) source.BIR.BIRInArray);
					break;
			}
			ptrBIR = ptr;
		}

		public void Unmarshal(BioAPI_CANDIDATE dest, bool fDeleteOld)
		{
			int len  = 0;
			IntPtr ptr = ptrBIR;

			dest.Type = Type;
			dest.FARAchieved = FARAchieved;
			dest.FRRAchieved = FRRAchieved;

			if (ptr == IntPtr.Zero) return;

			switch (Type)
			{
				case BioAPI_IDENTIFY_POPULATION_TYPE.BioAPI_DB_TYPE:
					dest.BIR.BIRInDataBase.DoUnmarshal(ptr, ref len, false);
					break;
				case BioAPI_IDENTIFY_POPULATION_TYPE.BioAPI_ARRAY_TYPE:
					dest.BIR.BIRInArray = (uint) Marshal.ReadInt32(ptr, 0);
					break;
			}
			if (fDeleteOld)  { Marshal.FreeCoTaskMem( ptr ); }
		}

		public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
		{
			int ofs = 0;
			size = Marshal.SizeOf(System.Type.GetType("System.Byte")) + 
					Marshal.SizeOf(System.Type.GetType("System.IntPtr")) +
					2 * Marshal.SizeOf(System.Type.GetType("System.Int32"));

			Type =  (BioAPI_IDENTIFY_POPULATION_TYPE) Marshal.ReadByte( ptr, ofs );
			ofs += Marshal.SizeOf(System.Type.GetType("System.Byte"));

			ptrBIR = Marshal.ReadIntPtr(ptr, ofs);
			ofs += Marshal.SizeOf(System.Type.GetType("System.IntPtr"));

			FARAchieved = (BioAPI_FAR) Marshal.ReadInt32(ptr, ofs);
			ofs += Marshal.SizeOf(System.Type.GetType("System.IntPtr"));
			FRRAchieved = (BioAPI_FRR) Marshal.ReadInt32(ptr, ofs);
			ofs += Marshal.SizeOf(System.Type.GetType("System.IntPtr"));

			if (fDeleteOld)  { if (ptrBIR != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrBIR ); }
			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}


		public void Dispose()
		{ if (ptrBIR != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrBIR ); }
	}

	[StructLayout(LayoutKind.Sequential)]
	public class BioAPI_IDENTIFY_POPULATION_Marshal 
	{
		public BioAPI_IDENTIFY_POPULATION_TYPE Type;
		public IntPtr ptrBIRs;

		public BioAPI_IDENTIFY_POPULATION_Marshal(BioAPI_IDENTIFY_POPULATION source)
		{
			IntPtr ptr = IntPtr.Zero;
			int len = 0;
			Type = source.Type;

			switch (Type)
			{
				case BioAPI_IDENTIFY_POPULATION_TYPE.BioAPI_DB_TYPE:
					ptr = Marshal.AllocCoTaskMem( Marshal.SizeOf(System.Type.GetType("System.Int32")));
					Marshal.WriteInt32(ptr, 0, (int) source.BIRs.BIRDataBase);
					break;
				case BioAPI_IDENTIFY_POPULATION_TYPE.BioAPI_ARRAY_TYPE:
					ptr = source.BIRs.BIRArray.DoMarshal(ref len);
					break;
			}
			ptrBIRs = ptr;
		}

		public void Unmarshal(BioAPI_IDENTIFY_POPULATION dest, bool fDeleteOld)
		{
			int len  = 0;
			IntPtr ptr = ptrBIRs;
			dest.Type = Type;

			if (ptr == IntPtr.Zero) return;

			switch (Type)
			{
				case BioAPI_IDENTIFY_POPULATION_TYPE.BioAPI_DB_TYPE:
					dest.BIRs.BIRDataBase = (BioAPI_DB_HANDLE) Marshal.ReadInt32(ptr, 0);
					break;
				case BioAPI_IDENTIFY_POPULATION_TYPE.BioAPI_ARRAY_TYPE:
					dest.BIRs.BIRArray.DoUnmarshal(ptr, ref len, fDeleteOld);
					break;
			}
			if (fDeleteOld)  { Marshal.FreeCoTaskMem( ptr ); }
		}

		public void Dispose()
		{ if (ptrBIRs != IntPtr.Zero) Marshal.FreeCoTaskMem( ptrBIRs ); }
	}


	public class BioAPIWin32 
	{
//		BioAPI_RETURN BioAPI BioAPI_Init(
//								 const BioAPI_VERSION *Version,
//								 uint32 Reserved1,
//								 const void *Reserved2,
//								 uint32 Reserved3,
//								 const void *Reserved4 );
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_Init
			(BioAPI_VERSION Version,		// [in]
			 int Reserved1,					// [in]
			 IntPtr Reserved2,				// [in]
			 int Reserved3,					// [in]
			 IntPtr Reserved4);				// [in]

//		BioAPI_RETURN BioAPI BioAPI_Terminate (void);
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_Terminate ();

//		BioAPI_RETURN BioAPI BioAPI_EnumModules(
//								 BioAPI_BSP_SCHEMA * BspSchemaArray,
//								 uint32 ArraySize,
//								 uint32 * ElementsNeeded,
//								 uint32 * NumElementsReturned);
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_EnumModules(
			[In, Out] BioAPI_BSP_SCHEMA_MARSHAL [] BspSchemaArray,	// [in, out]
			uint ArraySize,											// [in]
			[In, Out] ref uint ElementsNeeded,						// [out]
			[In, Out] ref uint NumElementsReturned);				// [out]

//		BioAPI_RETURN BioAPI BioAPI_ModuleLoad(
//								  const BioAPI_UUID *ModuleUuid,
//								  uint32 Reserved,
//								  BioAPI_ModuleEventHandler AppNotifyCallback,
//								  void *AppNotifyCallbackCtx);
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_ModuleLoad(
			IntPtr ModuleUuid,								// [in]
			uint Reserved,									// [in]		
			BioAPI_ModuleEventHandler AppNotifyCallback,	// [in/optional]
			IntPtr AppNotifyCallbackCtx);					// [in/optional]

//		BioAPI_RETURN BioAPI BioAPI_ModuleUnload(
//			const BioAPI_UUID *ModuleUuid,					
//			BioAPI_ModuleEventHandler AppNotifyCallback,	
//			void* AppNotifyCallbackCtx)						
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_ModuleUnload(
			IntPtr ModuleUuid,								// [in]
			BioAPI_ModuleEventHandler AppNotifyCallback,	// [in/optional]
			IntPtr AppNotifyCallbackCtx);					// [in/optional]

//		BioAPI_RETURN BioAPI BioAPI_ModuleAttach(
//			const BioAPI_UUID *ModuleUuid,
//			const BioAPI_VERSION *Version,
//			const BioAPI_MEMORY_FUNCS *MemoryFuncs,
//			uint32 DeviceID,
//			uint32 Reserved1,
//			uint32 Reserved2,
//			uint32 Reserved3,
//			BioAPI_FUNC_NAME_ADDR *FunctionTable,
//			uint32 NumFunctionTable,
//			const void *Reserved4,
//			BioAPI_HANDLE_PTR NewModuleHandle);
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_ModuleAttach(
			IntPtr ModuleUuid,									// [in]
			BioAPI_VERSION Version,								// [in]
			BioAPI_MEMORY_FUNCS MemoryFuncs,					// [in]
			uint DeviceID,										// [in]
			uint Reserved1,										// [in]
			uint Reserved2,										// [in]
			uint Reserved3,										// [in]
			[In, Out] BioAPI_FUNC_NAME_ADDR [] FunctionTable,	// [in/out/optional]
			uint NumFunctionTable,								// [in]
			IntPtr Reserved4,									// [in]
			[In, Out] ref BioAPI_HANDLE NewModuleHandle);		// [out]

// 		BioAPI_RETURN BioAPI BioAPI_ModuleDetach(BioAPI_HANDLE ModuleHandle)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_ModuleDetach(	
			uint ModuleHandle );								// [in]


//		BioAPI_RETURN BioAPI BioAPI_Enroll(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_BIR_PURPOSE Purpose,
//			const BioAPI_INPUT_BIR *StoredTemplate,
//			BioAPI_BIR_HANDLE_PTR NewTemplate,
//			const BioAPI_DATA *Payload,
//			sint32 Timeout,
//			BioAPI_BIR_HANDLE_PTR AuditData)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_Enroll(
			BioAPI_HANDLE ModuleHandle,						// [in]
			BioAPI_BIR_PURPOSE Purpose,						// [in]
			BioAPI_INPUT_BIR_Marshal StoredTemplate,		// [in/optional]
			[In, Out] ref BioAPI_BIR_HANDLE NewTemplate,	// [out]
			IntPtr Payload,									// [in/optional]
			int Timeout,									// [in]
			[In, Out] IntPtr ptrAuditData);					// [out/optional]

//		BioAPI_RETURN BioAPI BioAPI_Capture(
//				BioAPI_HANDLE ModuleHandle,
//				BioAPI_BIR_PURPOSE Purpose,
//				BioAPI_BIR_HANDLE_PTR CapturedBIR,
//				sint32 Timeout,
//				BioAPI_BIR_HANDLE_PTR AuditData)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_Capture(
			BioAPI_HANDLE ModuleHandle,						// [in]
			BioAPI_BIR_PURPOSE Purpose,						// [in]
			[In, Out] ref BioAPI_BIR_HANDLE CapturedBIR,	// [out]
			int Timeout,									// [in]
			[In, Out] IntPtr ptrAuditData);					// [out/optional]

//		BioAPI_RETURN BioAPI BioAPI_Process(
//			BioAPI_HANDLE ModuleHandle,
//			const BioAPI_INPUT_BIR *CapturedBIR,
//			BioAPI_BIR_HANDLE_PTR ProcessedBIR)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_Process(
			BioAPI_HANDLE ModuleHandle,						//[in]
			BioAPI_INPUT_BIR_Marshal CapturedBIR,		//[in]
			[In, Out] ref BioAPI_BIR_HANDLE ProcessedBIR);	//[out]

//		BioAPI_RETURN BioAPI BioAPI_VerifyMatch(
//			BioAPI_HANDLE ModuleHandle,				
//			const BioAPI_FAR *MaxFARRequested,		
//			const BioAPI_FRR *MaxFRRRequested,		
//			const BioAPI_BOOL *FARPrecedence,		
//			const BioAPI_INPUT_BIR *ProcessedBIR,	
//			const BioAPI_INPUT_BIR *StoredTemplate,	
//			BioAPI_BIR_HANDLE *AdaptedBIR,			
//			BioAPI_BOOL *Result,					
//			BioAPI_FAR_PTR FARAchieved,				
//			BioAPI_FRR_PTR FRRAchieved,				
//			BioAPI_DATA_PTR *Payload)				
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_VerifyMatch(
			BioAPI_HANDLE ModuleHandle,				//	[in]
			ref BioAPI_FAR MaxFARRequested,			//	[in]
			IntPtr ptrMaxFRRRequested,				//	[in/optional]
			ref BioAPI_BOOL FARPrecedence,			//	[in]
			BioAPI_INPUT_BIR_Marshal ProcessedBIR,	//	[in]
			BioAPI_INPUT_BIR_Marshal StoredTemplate,//	[in]
			[In, Out] IntPtr ptrAdaptedBIR,			//	[out/optional]
			[In, Out] ref BioAPI_BOOL Result,		//	[out]
			[In, Out] ref BioAPI_FAR FARAchieved,	//	[out]
			[In, Out] IntPtr ptrFRRAchieved,		//	[out/optional]
			[In, Out] BioAPI_DATA ptrPayload);		//	[out/optional]


//		BioAPI_RETURN BioAPI BioAPI_Verify(
//			BioAPI_HANDLE ModuleHandle,
//			const BioAPI_FAR *MaxFARRequested,
//			const BioAPI_FRR *MaxFRRRequested,
//			const BioAPI_BOOL *FARPrecedence,
//			const BioAPI_INPUT_BIR *StoredTemplate,
//			BioAPI_BIR_HANDLE_PTR AdaptedBIR,
//			BioAPI_BOOL *Result,
//			BioAPI_FAR_PTR FARAchieved,
//			BioAPI_FRR_PTR FRRAchieved,
//			BioAPI_DATA_PTR *Payload,
//			sint32 Timeout,
//			BioAPI_BIR_HANDLE_PTR AuditData)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_Verify(
			BioAPI_HANDLE ModuleHandle,				//	[in]
			ref BioAPI_FAR MaxFARRequested,			//	[in]
			IntPtr ptrMaxFRRRequested,				//	[in/optional]
			ref BioAPI_BOOL FARPrecedence,			//	[in]
			BioAPI_INPUT_BIR_Marshal StoredTemplate,	//	[in]
			[In, Out] IntPtr ptrAdaptedBIR,			//	[out/optional]
			[In, Out] ref BioAPI_BOOL Result,		//	[out]
			[In, Out] ref BioAPI_FAR FARAchieved,	//	[out]
			[In, Out] IntPtr ptrFRRAchieved,		//	[out/optional]
			[In, Out] BioAPI_DATA ptrPayload,		//	[out/optional]
			int Timeout,							//	[in]
			[In, Out] IntPtr ptrAuditData);			// [out/optional]

//		BioAPI_RETURN BioAPI BioAPI_IdentifyMatch(
//			BioAPI_HANDLE ModuleHandle,
//			const BioAPI_FAR *MaxFARRequested,
//			const BioAPI_FRR *MaxFRRRequested,
//			const BioAPI_BOOL *FARPrecedence,
//			const BioAPI_INPUT_BIR *ProcessedBIR,
//			const BioAPI_IDENTIFY_POPULATION *Population,
//			BioAPI_BOOL Binning,
//			uint32 MaxNumberOfResults,
//			uint32 *NumberOfResults,
//			BioAPI_CANDIDATE_ARRAY_PTR *Candidates,
//			sint32 Timeout)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_IdentifyMatch(
			BioAPI_HANDLE ModuleHandle,				//	[in]
			ref BioAPI_FAR MaxFARRequested,			//	[in]
			IntPtr ptrMaxFRRRequested,				//	[in/optional]
			ref BioAPI_BOOL FARPrecedence,			//	[in]
			BioAPI_INPUT_BIR_Marshal ProcessedBIR,	//	[in]
			ref BioAPI_IDENTIFY_POPULATION Population,	//	[in]
			BioAPI_BOOL Binning,					//	[in]
			uint MaxNumberOfResults,				//	[in]
			[In, Out]ref uint NumberOfResults,		//	[out]
			[In, Out] IntPtr ptrCandidates,			//	[out]
			int Timeout);							//	[in]

//		BioAPI_RETURN BioAPI BioAPI_Identify(
//			BioAPI_HANDLE ModuleHandle,
//			const BioAPI_FAR *MaxFARRequested,
//			const BioAPI_FRR *MaxFRRRequested,
//			const BioAPI_BOOL *FARPrecedence,
//			const BioAPI_IDENTIFY_POPULATION *Population,
//			BioAPI_BOOL Binning,
//			uint32 MaxNumberOfResults,
//			uint32 *NumberOfResults,
//			BioAPI_CANDIDATE_ARRAY_PTR *Candidates,
//			sint32 Timeout,
//			BioAPI_BIR_HANDLE_PTR AuditData)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_Identify(
			BioAPI_HANDLE ModuleHandle,				//	[in]
			ref BioAPI_FAR MaxFARRequested,			//	[in]
			IntPtr ptrMaxFRRRequested,				//	[in/optional]
			ref BioAPI_BOOL FARPrecedence,			//	[in]
			ref BioAPI_IDENTIFY_POPULATION Population,	//	[in]
			BioAPI_BOOL Binning,					//	[in]
			uint MaxNumberOfResults,				//	[in]
			[In, Out]ref uint NumberOfResults,		//	[out]
			[In, Out] IntPtr ptrCandidates,			//	[out]
			int Timeout,							//	[in]
			[In, Out]IntPtr AuditData);				//	[out/optional]


//		BioAPI_RETURN BioAPI BioAPI_GetHeaderFromHandle
//			   (BioAPI_HANDLE ModuleHandle,
//				BioAPI_BIR_HANDLE BIRHandle,
//				BioAPI_BIR_HEADER_PTR Header)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_GetHeaderFromHandle(
			BioAPI_HANDLE ModuleHandle,				// [in]
			BioAPI_BIR_HANDLE BIRHandle,			// [in]
			[In, Out] BioAPI_BIR_HEADER Header);	// [in]
			//[In, Out] IntPtr ptrHeader);


//		BioAPI_RETURN BioAPI BioAPI_GetBIRFromHandle(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_BIR_HANDLE BIRHandle,
//			BioAPI_BIR_PTR *BIR)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_GetBIRFromHandle(
			BioAPI_HANDLE ModuleHandle,			// [in]
			BioAPI_BIR_HANDLE BIRHandle,		// [in]
			[In, Out] IntPtr ptrBIR);			// [out]

//		BioAPI_RETURN BioAPI BioAPI_FreeBIRHandle(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_BIR_HANDLE BIRHandle)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_FreeBIRHandle(
			BioAPI_HANDLE ModuleHandle,			// [in]
			BioAPI_BIR_HANDLE BIRHandle);		// [in]

//		BioAPI_RETURN BioAPI BioAPI_QueryDevice(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_SERVICE_UID_PTR DeviceUID)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_QueryDevice(
			BioAPI_HANDLE ModuleHandle,					// [in]
			[In, Out] BioAPI_SERVICE_UID DeviceUID);	// [out]

//		BioAPI_RETURN BioAPI BioAPI_EnableEvents(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_MODULE_EVENT_MASK *Events)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_EnableEvents(
			BioAPI_HANDLE ModuleHandle,				// [in]
			ref BioAPI_MODULE_EVENT_MASK Events);	// [in]

//		BioAPI_RETURN BioAPI BioAPI_SetGUICallbacks(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_GUI_STREAMING_CALLBACK GuiStreamingCallback,
//			void *GuiStreamingCallbackCtx,
//			BioAPI_GUI_STATE_CALLBACK GuiStateCallback,
//			void *GuiStateCallbackCtx )
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_SetGUICallbacks(
			BioAPI_HANDLE ModuleHandle,								// [in]
			BioAPI_GUI_STREAMING_CALLBACK GuiStreamingCallback,		// [in]
			IntPtr GuiStreamingCallbackCtx,							// [in]
			BioAPI_GUI_STATE_CALLBACK GuiStateCallback,				// [in]
			IntPtr GuiStateCallbackCtx);							// [in]

//		BioAPI_RETURN BioAPI BioAPI_SetStreamCallback(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_STREAM_CALLBACK StreamCallback,
//			void *StreamCallbackCtx)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_SetStreamCallback(
			BioAPI_HANDLE ModuleHandle,								// [in]
			BioAPI_GUI_STREAMING_CALLBACK GuiStreamingCallback,		// [in]
			IntPtr GuiStreamingCallbackCtx);						// [in]

//		BioAPI_RETURN BioAPI BioAPI_StreamInputOutput(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_DATA_PTR InMessage,
//			BioAPI_DATA_PTR OutMessage)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_StreamInputOutput(
			BioAPI_HANDLE ModuleHandle,			// [in]
			BioAPI_DATA InMessage,				// [in]
			[In, Out]  BioAPI_DATA OutMessage);	// [out]


//		BioAPI_RETURN BioAPI BioAPI_CreateTemplate(
//			BioAPI_HANDLE ModuleHandle,
//			const BioAPI_INPUT_BIR *CapturedBIR,
//			const BioAPI_INPUT_BIR *StoredTemplate,
//			BioAPI_BIR_HANDLE_PTR NewTemplate,
//			const BioAPI_DATA *Payload)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_CreateTemplate(
			BioAPI_HANDLE ModuleHandle,				// [in]
			BioAPI_INPUT_BIR_Marshal CapturedBIR,	//	[in]
			BioAPI_INPUT_BIR_Marshal StoredTemplate,//	[in/optional]
			[In, Out] ref BioAPI_BIR_HANDLE NewTemplate,// [out]
			BioAPI_DATA Payload);					// [in/optional]

//		BioAPI_RETURN BioAPI BioAPI_Import(
//			  BioAPI_HANDLE ModuleHandle,
//			  const BioAPI_DATA *InputData,
//			  BioAPI_BIR_BIOMETRIC_DATA_FORMAT InputFormat,
//			  BioAPI_BIR_PURPOSE Purpose,
//			  BioAPI_BIR_HANDLE_PTR ConstructedBIR)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_Import(
			BioAPI_HANDLE ModuleHandle,						// [in]
			BioAPI_DATA InputData,							// [in]
			BioAPI_BIR_BIOMETRIC_DATA_FORMAT InputFormat,	//	[in]
			BioAPI_BIR_PURPOSE Purpose,						// [in]
			[In, Out] ref BioAPI_BIR_HANDLE ConstructedBIR);// [out]

//		BioAPI_RETURN BioAPI BioAPI_SetPowerMode(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_POWER_MODE PowerMode)
		[DllImport("bioapi100.dll")]
		public static extern BioAPI_RETURN BioAPI_SetPowerMode(
			BioAPI_HANDLE ModuleHandle,						// [in]
			BioAPI_POWER_MODE PowerMode);					// [in]

//		BioAPI_RETURN BioAPI BioAPI_DbOpen(
//			BioAPI_HANDLE ModuleHandle,
//			const uint8 *DbName,
//			BioAPI_DB_ACCESS_TYPE AccessRequest,
//			BioAPI_DB_HANDLE_PTR DbHandle,
//			BioAPI_DB_CURSOR_PTR Cursor)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbOpen(
			BioAPI_HANDLE ModuleHandle,						// [in]
			string DbName,									// [in]
			BioAPI_DB_ACCESS_TYPE AccessRequest,			// [in]
			[In, Out] ref BioAPI_DB_HANDLE DbHandle,		// [out]
			[In, Out] ref BioAPI_DB_CURSOR Cursor);			// [out]		


//		BioAPI_RETURN BioAPI BioAPI_DbClose(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_DB_HANDLE DbHandle);
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbClose(
			BioAPI_HANDLE ModuleHandle,					// [in]
			BioAPI_DB_HANDLE DbHandle);					// [in]


//		BioAPI_RETURN BioAPI BioAPI_DbCreate(
//			BioAPI_HANDLE ModuleHandle,
//			const uint8 *DbName,
//			BioAPI_DB_ACCESS_TYPE AccessRequest,
//			BioAPI_DB_HANDLE_PTR DbHandle)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbCreate(
			BioAPI_HANDLE ModuleHandle,						// [in]
			string DbName,									// [in]
			BioAPI_DB_ACCESS_TYPE AccessRequest,			// [in]
			[In, Out] ref BioAPI_DB_HANDLE DbHandle);		// [out]

//		BioAPI_RETURN BioAPI BioAPI_DbDelete(
//			BioAPI_HANDLE ModuleHandle,
//			const uint8 *DbName)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbDelete(
			BioAPI_HANDLE ModuleHandle,				// [in]
			string DbName);							// [in]

//		BioAPI_RETURN BioAPI BioAPI_DbSetCursor(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_DB_HANDLE DbHandle,
//			const BioAPI_UUID *KeyValue,
//			BioAPI_DB_CURSOR_PTR Cursor)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbSetCursor(
			BioAPI_HANDLE ModuleHandle,				// [in]
			BioAPI_DB_HANDLE DbHandle,				// [in]
			IntPtr KeyValue,						// [in]
			[In, Out] ref BioAPI_DB_CURSOR Cursor);	// [out]

//		BioAPI_RETURN BioAPI BioAPI_DbFreeCursor(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_DB_CURSOR_PTR Cursor)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbFreeCursor(
			BioAPI_HANDLE ModuleHandle,				// [in]
			ref BioAPI_DB_CURSOR Cursor);			// [in]

//		BioAPI_RETURN BioAPI BioAPI_DbStoreBIR(
//			BioAPI_HANDLE ModuleHandle,
//			const BioAPI_INPUT_BIR *BIRToStore,
//			BioAPI_DB_HANDLE DbHandle,
//			BioAPI_UUID_PTR Uuid)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbStoreBIR(
			BioAPI_HANDLE ModuleHandle,				// [in]
			BioAPI_INPUT_BIR_Marshal BIRToStore,	// [in]
			BioAPI_DB_HANDLE DbHandle,				// [in]
			[In, Out] IntPtr Uuid);					// [out]


//		BioAPI_RETURN BioAPI BioAPI_DbGetBIR(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_DB_HANDLE DbHandle,
//			const BioAPI_UUID *KeyValue,
//			BioAPI_BIR_HANDLE_PTR RetrievedBIR,
//			BioAPI_DB_CURSOR_PTR Cursor)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbGetBIR(
			BioAPI_HANDLE ModuleHandle,						// [in]
			BioAPI_DB_HANDLE DbHandle,						// [in]
			IntPtr KeyValue,								// [in]
			[In, Out] ref BioAPI_BIR_HANDLE RetrievedBIR,	// [out]
			[In, Out] ref BioAPI_DB_CURSOR Cursor);			// [out]


//		BioAPI_RETURN BioAPI BioAPI_DbGetNextBIR(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_DB_CURSOR_PTR Cursor,
//			BioAPI_BIR_HANDLE_PTR RetievedBIR,
//			BioAPI_UUID_PTR Uuid)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbGetNextBIR(
			BioAPI_HANDLE ModuleHandle,						// [in]
			[In, Out] ref BioAPI_DB_CURSOR Cursor,			// [in/out]
			[In, Out] ref BioAPI_BIR_HANDLE RetrievedBIR,	// [out]
			[In, Out] IntPtr KeyValue);						// [out]

//		BioAPI_RETURN BioAPI BioAPI_DbQueryBIR(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_DB_HANDLE DbHandle,
//			const BioAPI_INPUT_BIR *BIRToQuery,
//			BioAPI_UUID_PTR Uuid)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbQueryBIR(
			BioAPI_HANDLE ModuleHandle,				// [in]
			BioAPI_DB_HANDLE DbHandle,				// [in]
			BioAPI_INPUT_BIR_Marshal BIRToQuery,	// [in]
			[In, Out] IntPtr Uuid);					// [out]

//		BioAPI_RETURN BioAPI BioAPI_DbDeleteBIR(
//			BioAPI_HANDLE ModuleHandle,
//			BioAPI_DB_HANDLE DbHandle,
//			const BioAPI_UUID *KeyValue)
		[DllImport("bioapi100.dll", CharSet=CharSet.Ansi)]
		public static extern BioAPI_RETURN BioAPI_DbDeleteBIR(
			BioAPI_HANDLE ModuleHandle,				// [in]
			BioAPI_DB_HANDLE DbHandle,				// [in]
			IntPtr KeyValue);						// [in]


		public static IntPtr MarshalByte(byte val)
		{
			IntPtr ptr = Marshal.AllocCoTaskMem( 1 );
			Marshal.WriteByte(ptr, val);
			return ptr;
		}
		public static byte UnmarshalByte(IntPtr ptr, bool fDeleteOld )
		{
			byte val = 0;
			if (ptr != IntPtr.Zero) 
			{
				val = Marshal.ReadByte( ptr );;
				if (fDeleteOld)  { Marshal.FreeCoTaskMem( ptr ); }
			}
			return val;
		}		

		public static IntPtr MarshalInt16(short val)
		{
			IntPtr ptr = Marshal.AllocCoTaskMem( 2 );
			Marshal.WriteInt16(ptr, val);
			return ptr;
		}
		public static short UnmarshalInt16(IntPtr ptr, bool fDeleteOld )
		{
			short val = 0;
			if (ptr != IntPtr.Zero) 
			{
				val = Marshal.ReadInt16( ptr );;
				if (fDeleteOld)  { Marshal.FreeCoTaskMem( ptr ); }
			}
			return val;
		}		

		public static IntPtr MarshalInt32(int val)
		{
			IntPtr ptr = Marshal.AllocCoTaskMem( 4 );
			Marshal.WriteInt32(ptr, val);
			return ptr;
		}
		public static int UnmarshalInt32(IntPtr ptr, bool fDeleteOld )
		{
			int val = 0;
			if (ptr != IntPtr.Zero) 
			{
				val = Marshal.ReadInt32( ptr );;
				if (fDeleteOld)  { Marshal.FreeCoTaskMem( ptr ); }
			}
			return val;
		}	

		public static IntPtr MarshalByteArray(byte[] val)
		{
			IntPtr ptr = IntPtr.Zero;
			if (val == null) return ptr;
			ptr = Marshal.AllocCoTaskMem( val.Length );
			Marshal.Copy(val, 0, ptr, val.Length);
			return ptr;
		}
		public static void UnmarshalByteArray(IntPtr ptr, byte[] val, bool fDeleteOld )
		{
			if (ptr == IntPtr.Zero) return;
			Marshal.Copy(ptr, val, 0, val.Length);
			if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
		}	
	}
}