using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace MeterVision.FreeAi
{
    public class FaImport
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct BeforeAI
        {
            //01 仪表类型
            public byte METER_TYPE;          // uint8_t 对应 byte
            //02 数字个数(黑色+红色)
            public byte NUM_NUMBERS;          // uint8_t 对应 byte
            //03 尾数单位的含义,最小单位1分升,1dL, 0.1L（万分之一立方)
            public uint UNIT_OF_THE_LAST_NUMBER; // uint32_t 对应 uint
            //04（配置信息）指针个数
            public byte NUM_INDICATORS;       // uint8_t 对应 byte
            //05 指针的尾数单位
            public uint UNIT_OF_THE_LAST_INDICATOR; // uint32_t 对应 uint
            
            public uint HOURS_FORM_LAST_1278; //当前时间 离上一次1278结果的 间隔小时数

            //06 当前时间距离上次准确识别时间内的最大流量,最小单位0.1L(1m³/10000), (万分之一立方)
            public ulong MAX_FLOW_THRESHOLD;  // uint64_t 对应 ulong           
          
            //07 8字节整数,表示识别结果，最小单位分升,即1dL=0.1L=1m³/10000),万分之一立方;
            public ulong AI_RESULT;           // uint64_t 对应 ulong

            //08 完整的结果
            public ulong AI_COMPLETE_RESULT;

            //09 数字区域的四个顶点坐标值(4组)
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public ushort[] CONFIG_NUM_REGION;       // uint16_t 对应 ushort, 8 个元素的数组
            //10 首位指针坐标值(2组)
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public ushort[] CONFIG_TWO_IND;       // uint16_t 对应 ushort, 4 个元素的数组
            //11 表盘坐标
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public ushort[] CONFIG_METER_REGION;       // uint16_t 对应 ushort, 4 个元素的数组

            //12 图片亮度
            public float BRIGHT_FACTOR;       // float 对应 float

            //13 大图JPG图像的最大字节数
            public ushort BIG_JPG_SIZE;   // uint16_t 对应 ushort

            //14 AI输出JPG图是,使用测试图标记,1:使用,0:不使用
            public byte USE_TEST_JPG_FLAG;    // uint8_t 对应 byte

            //15 压缩JPG的索引,来自after_struct,首次索引为0
            public byte COMPRESS_JPG_INDEX;   // uint8_t 对应 byte

            //16 是否上传红色指针部分的数据(0:不上传;1:上传;默认1)
            public byte IS_UPLOAD_RED_IND_PART;// uint8_t 对应 byte

            //16.1 add by lyj 20250321
            public byte IS_NUM_IN_UPPER;

            //17 上传日志的printf回调函数
            public IntPtr printfAiLog;        // 回调函数指针, 用 IntPtr 表示  
        }


            //After结构体
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct AfterAI
        {
            public byte METER_TYPE;             //仪表类型(0:不是水表图片,1:数字+指针,2:全指针 3:全数字)
            //add by lyj 20250321
            public byte RESULT_TYPE;            //

            public ulong AI_RESULT;             //识别最终结果，经过校正步骤后的最终结果，单位分升dL
            public ulong INIT_AI_RESULT;        //网络直接输出的、没有经过校正的最初识别结果，单位分升dL
            public ulong AI_COMPLETE_RESULT;    //最终的、完整的、经过校正步骤的结果，单位分升dL

            public byte IS_VALUE_CHANGED;       //与上一次比较，水表读数是否在变化？变化范围包括数字+指针部分，也就是比较上次和本次的 AI_COMPLETE_RESULT

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] // AI_result_array[2][12] 转成一维数组
            public byte[] AI_RESULT_ARRAY;    //03（本次结果）int数组的识别结果（2维数组，第一行元素为类别、第二行为识别概率）

            public byte COMPRESS_JPG_INDEX;    //上一次JPG的压缩索引

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] AI_VER;  //AI程序的数字版本号            
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct SmallImage
        {
            public ushort size_of_JPEG_data;  //01（本次结果）数字区域的JPG数据长度

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 841)]
            public byte[] JPEG_data;  //02（本次结果）数字区域的JPG数字部分

            public byte number_region_index_of_header; //03（本次结果）JPG压缩头编号 （如果此值0-9，说明是彩色图，JPG文件头589字节；10-19，说明是灰度图，JPG文件头514字节）

            public int image_height;  //04（本次结果）图像高度
            public int image_width;   //05（本次结果）图像宽度
        }


        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct BigImage
        {
            public ushort size_of_JPEG_data;  //01（本次结果）JPG格式的整张图片数据长度 （包括JPG数据， 包括文件头）

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50 * 1024)]
            public byte[] JPEG_data;  //02（本次结果）JPG格式的整张图片（包括JPG数据， 包括文件头）

            public byte whole_image_index_of_header;  //03（本次结果）JPG压缩头编号。（如果此值0-9，说明是彩色图，JPG文件头589字节；10-19，说明是灰度图，JPG文件头514字节）

            public ushort image_height;  //04（本次结果）图像高度

            public ushort image_width;   //05（本次结果）图像宽度
        }

        // 声明打印回调的委托
        public delegate void PrintfCallback(string message);

        //已改为使用动态加载方式，暂时把静态的注释掉
        // 引入 C 函数
        [DllImport("freeAI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        public static extern int recognition(
            [In] short[] rgb565,
            ref BeforeAI beforeAI,
            ref AfterAI afterAI,
            ref SmallImage smallJpg,
            ref BigImage bigJpg,
            [MarshalAs(UnmanagedType.LPWStr)] string modelPath,
            PrintfCallback callback
        );

    }
}
