using System;
namespace IvfTl.Hardware
{
///
/// 单台相机(MVC2000)的唯一持有者。封装 MVCAPI P/Invoke。
/// 蓝本:autofocustool Camera(含 _pDest 空保护 + 锁内释放)。
/// ⚠ 所有原生调用必须走【全进程统一相机锁】(ICameraGate),替代现状三套各自的 static locker。
/// ⚠ 所有进 native 的实现方法必须加 [HandleProcessCorruptedStateExceptions][SecurityCritical] 防 native 崩溃拖垮进程。
/// 接口签名权威:13 文档 §3.3。
///
public interface ICamera : IDisposable
{
int Index { get; }
int Width { get; }
int Height { get; }
int Exposure { get; } // 单位 100us
string SerialNumber { get; }
bool IsInit { get; }
bool IsStart { get; }
// ── 生命周期 ──
/// 初始化(MV_Usb2Init MVC2000)。返回 0 成功。需立即 SetOpMode 才能抓图。
int Init(byte redGain = 25, byte greenGain = 14, byte blueGain = 25);
/// 采集模式:0=单帧拍照(对焦/调试抓图用),1=实时预览。返回 0 成功。
int SetOpMode(byte mode = 0, bool strobe = false);
/// 读相机序列号到 SerialNumber。返回 0 成功。
int ReadSerial();
/// 卸载相机(MV_Usb2Uninit)。返回 0 成功。
int UnInit();
// ── 参数 ──
/// 设曝光(单位 100us)。返回 0 成功。
int SetExposure(int exposure100us);
/// 设 RGB 三通道增益(0-255)。返回 0 成功。
int SetGain(byte red, byte green, byte blue);
// ── 抓帧(单帧)──
/// 抓一帧 RGB 到内部缓冲。返回 0 成功;之后用 GetFrameBuffer 取像素。
int GrabRgb();
/// 取当前帧像素(24bpp BGR, W*H*3)。_pDest 已释放返回 null(调用方按抓帧失败重试)。
byte[] GetFrameBuffer();
/// 抓一帧并返回像素的便捷重载,内置"丢残留帧 + 到位延时 + 重试"语义(13 §3.5)。
/// discardStale=true 时先 GrabRgb 丢弃一帧再抓有效帧(运动后旧帧滞留修复,对应 af 双 Grab)。
/// preDelayMs:抓前等待(电机到位稳定),retry:抓帧失败重试次数。失败返回 null。
byte[] GrabStable(int preDelayMs = 0, bool discardStale = true, int retry = 2);
// ── 实时预览(贴 WPF 窗口,operate 调试/control 预览用;af 不需要)──
/// 把实时画面贴到宿主控件句柄。对应 control/operate Usb2Start。返回 0 成功。
int StartPreview(IntPtr hostControl, int left, int top, int width, int height);
int StopPreview();
// ── operate 调试页"无图模式"两步抓帧 + 存图(M1-B2:调试页接入 lease.Camera 后转发到底层 Camera)──
/// 抓取一帧 RAW 到内部缓冲(对应底层 Camera.GetRawData)。返回 0 成功;之后配 RawToRgb 转 RGB。
int GrabRaw();
/// 把内部 RAW 缓冲转 RGB(对应底层 Camera.RawToRgb)。返回 0 成功。
int RawToRgb();
/// 把当前帧像素保存为图片文件(对应 operate 调试页 Camera.SavePic)。成功返回 true。
bool SavePic(string fullName, int width, int height);
/// 桥接对象:返回内部包装的具体 Camera(迁移期过渡,新代码只用本接口方法)。
object RawCamera { get; }
}
}