using System;
using System.Runtime.InteropServices;

namespace XP.Hardware.Detector.Implementations
{
    /// <summary>
    /// XISL API 互操作层 | XISL API interop layer
    /// 封装 Varex 探测器的 xisl.dll 原厂 API
    /// </summary>
    public static class XISLApi
    {
        #region 枚举定义 | Enum Definitions

        /// <summary>
        /// XISL API 返回码 | XISL API return codes
        /// </summary>
        public enum HIS_RETURN
        {
            HIS_ALL_OK = 0,
            HIS_Init = -1,
            HIS_ERROR_MEMORY = 1,
            HIS_ERROR_BOARDINIT = 2,
            HIS_ERROR_NOBOARD = 3,
            HIS_ERROR_NOCAMERA = 4,
            HIS_ERROR_TIMEOUT = 5,
            HIS_ERROR_INVALIDPARAM = 6,
            HIS_ERROR_ABORT = 7
        }

        #endregion

        #region 常量定义 | Constant Definitions

        /// <summary>
        /// 连续采集模式 | Continuous acquisition mode
        /// </summary>
        public const int HIS_SEQ_CONTINUOUS = 0x100;

        /// <summary>
        /// 单帧采集模式（单缓冲区）| Single frame mode (one buffer)
        /// </summary>
        public const int HIS_SEQ_ONE_BUFFER = 0x2;

        /// <summary>
        /// 采集数据标志：连续采集 | Acquisition data flag: continuous
        /// </summary>
        public const uint ACQ_CONT = 1;

        /// <summary>
        /// 采集数据标志：暗场校正 | Acquisition data flag: offset correction
        /// </summary>
        public const uint ACQ_OFFSET = 2;

        /// <summary>
        /// 采集数据标志：增益校正 | Acquisition data flag: gain correction
        /// </summary>
        public const uint ACQ_GAIN = 4;

        /// <summary>
        /// 采集数据标志：单帧采集 | Acquisition data flag: snap (single frame)
        /// </summary>
        public const uint ACQ_SNAP = 8;

        /// <summary>
        /// 等待对象信号 | Wait object signaled
        /// </summary>
        public const uint WAIT_OBJECT_0 = 0x00000000;

        /// <summary>
        /// 无限等待 | Infinite wait
        /// </summary>
        public const uint INFINITE = 0xFFFFFFFF;

        /// <summary>
        /// 内部定时器同步模式 | Internal timer sync mode
        /// </summary>
        public const int HIS_SYNCMODE_INTERNAL_TIMER = 2;

        #endregion

        #region 回调函数委托 | Callback Delegates

        /// <summary>
        /// 帧结束回调函数委托 | End frame callback delegate
        /// </summary>
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void EndFrameCallback(IntPtr hAcqDesc);

        /// <summary>
        /// 采集结束回调函数委托 | End acquisition callback delegate
        /// </summary>
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void EndAcqCallback(IntPtr hAcqDesc);

        #endregion

        #region Win32 API | Win32 API

        /// <summary>
        /// 创建事件对象 | Create event object
        /// </summary>
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);

        /// <summary>
        /// 设置事件信号 | Set event signal
        /// </summary>
        [DllImport("kernel32.dll")]
        public static extern bool SetEvent(IntPtr hEvent);

        /// <summary>
        /// 等待单个对象 | Wait for single object
        /// </summary>
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

        /// <summary>
        /// 关闭句柄 | Close handle
        /// </summary>
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool CloseHandle(IntPtr hObject);

        #endregion

        #region XISL API - 基础函数 | XISL API - Basic Functions

        /// <summary>
        /// 获取下一个探测器传感器 | Get next sensor
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_GetNextSensor", CallingConvention = CallingConvention.StdCall)]
        public static extern HIS_RETURN Acquisition_GetNextSensor(ref IntPtr pAcqDesc, ref IntPtr hWnd);

        /// <summary>
        /// 获取探测器配置信息 | Get detector configuration
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_GetConfiguration", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_GetConfiguration(
            IntPtr hAcqDesc, out uint dwFrames, out uint dwRows, out uint dwColumns,
            out uint dwDataType, out uint dwSortFlags, out int iIRQFlags,
            out uint dwAcqType, out uint dwSystemID, out uint dwSyncMode, out uint dwHwAccess);

        /// <summary>
        /// 获取采集数据指针 | Get acquisition data pointer
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_GetAcqData", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_GetAcqData(IntPtr hAcqDesc, out IntPtr vpAcqData);

        /// <summary>
        /// 设置采集数据标志 | Set acquisition data flags
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_SetAcqData", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_SetAcqData(IntPtr hAcqDesc, ref uint dwAcqData);

        /// <summary>
        /// 定义目标缓冲区 | Define destination buffers
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_DefineDestBuffers", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_DefineDestBuffers(IntPtr hAcqDesc, IntPtr pBuffer, int iFrames, uint dwRows, uint dwColumns);

        /// <summary>
        /// 设置回调函数和消息 | Set callbacks and messages
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_SetCallbacksAndMessages", CallingConvention = CallingConvention.StdCall)]
        public static extern HIS_RETURN Acquisition_SetCallbacksAndMessages(
            IntPtr pAcqDesc,
            IntPtr hWnd,
            uint dwErrorMsg,
            uint dwLoosingFramesMsg,
            EndFrameCallback lpfnEndFrameCallback,
            EndAcqCallback lpfnEndAcqCallback);

        /// <summary>
        /// 关闭所有连接 | Close all connections
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_CloseAll", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_CloseAll();

        #endregion

        #region XISL API - 参数设置 | XISL API - Parameter Settings

        /// <summary>
        /// 设置 Binning 模式 | Set binning mode
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_SetCameraBinningMode", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_SetCameraBinningMode(IntPtr hAcqDesc, uint wMode);

        /// <summary>
        /// 设置增益模式 | Set gain mode
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_SetCameraGain", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_SetCameraGain(IntPtr hAcqDesc, uint wMode);

        /// <summary>
        /// 设置定时器同步（曝光时间）| Set timer sync (exposure time)
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_SetTimerSync", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_SetTimerSync(IntPtr hAcqDesc, ref uint wMode);

        /// <summary>
        /// 设置帧同步模式 | Set frame sync mode
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_SetFrameSyncMode", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_SetFrameSyncMode(IntPtr hAcqDesc, uint dwMode);

        /// <summary>
        /// 设置相机触发模式 | Set camera trigger mode
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_SetCameraTriggerMode", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_SetCameraTriggerMode(IntPtr hAcqDesc, uint dwMode);

        #endregion

        #region XISL API - 图像采集 | XISL API - Image Acquisition

        /// <summary>
        /// 采集图像 | Acquire image
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_Acquire_Image", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_Acquire_Image(
            IntPtr hAcqDesc,
            uint dwFrames,
            uint dwSkipFrms,
            uint dwOpt,
            IntPtr pwOffsetData,
            IntPtr pdwGainData,
            IntPtr pdwPxlCorrList);

        /// <summary>
        /// 停止采集 | Abort acquisition
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_Abort", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_Abort(IntPtr hAcqDesc);

        /// <summary>
        /// 获取当前帧号 | Get current frame number
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_GetActFrame", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_GetActFrame(IntPtr hAcqDesc, out uint dwActFrame, out uint dwSecFrame);

        #endregion

        #region XISL API - 校正功能 | XISL API - Correction Functions

        /// <summary>
        /// 采集暗场图像 | Acquire offset image
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_Acquire_OffsetImage", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_Acquire_OffsetImage(IntPtr hAcqDesc, IntPtr pOffsetData, uint nRows, uint nCols, uint nFrames);

        /// <summary>
        /// 采集增益图像 | Acquire gain image
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_Acquire_GainImage", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_Acquire_GainImage(IntPtr hAcqDesc, IntPtr pOffsetData, IntPtr pGainData, uint nRows, uint nCols, uint nFrames);

        /// <summary>
        /// 创建增益映射 | Create gain map
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_CreateGainMap", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_CreateGainMap(IntPtr pGainData, IntPtr pGainAVG, int nCount, int nFrame);

        /// <summary>
        /// 创建坏像素列表 | Create pixel map
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_CreatePixelMap", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_CreatePixelMap(IntPtr pData, int nDataRows, int nDataColumns, IntPtr pCorrList, ref int nCorrListSize);

        /// <summary>
        /// 重置板载选项 | Reset onboard options
        /// </summary>
        [DllImport("xisl.dll", EntryPoint = "Acquisition_Reset_OnboardOptions", CallingConvention = CallingConvention.Cdecl)]
        public static extern HIS_RETURN Acquisition_Reset_OnboardOptions(IntPtr hAcqDesc);

        #endregion

        #region VarexDetDll API - Varex 探测器初始化 | VarexDetDll API - Varex Detector Initialization

        /// <summary>
        /// 探测器底层初始化 | Detector low-level initialization
        /// 由 VarexDetDll.dll 提供，内部完成枚举、连接等底层操作
        /// 返回 0 表示成功 | Returns 0 on success
        /// </summary>
        [DllImport("VarexDetDll.dll", EntryPoint = "DoDetInit", CallingConvention = CallingConvention.StdCall)]
        public static extern int DoDetInit(ref IntPtr hAcqDesc);

        #endregion
    }
}
