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

namespace YoseenPTZ.SDKDef
{
    [Flags]
    public enum StrechControlFlags : int
    {
        SCF_StrechType = 0x0001,

        //SCF_Contrast = 0x0002,
        //SCF_Brightness = 0x0004,

        SCF_Gain = 0x0008,
        //SCF_Linear = 0x0010,

        SCF_PHEStream = 0x0020,

        SCF_DDELevel = 0x0040,
        SCF_ColorTemp = 0x0080,

        SCF_ManEnable = 0x0100,
        SCF_ManTemp0 = 0x0200,
        SCF_ManTemp1 = 0x0400,

        //20211113
        SCF_CK = 0x00010000,

        //20211216
        SCF_HW = 0x00020000,

        //
        SCF_Frame = SCF_StrechType | SCF_Gain
            | SCF_ManEnable | SCF_ManTemp0 | SCF_ManTemp1
            | SCF_DDELevel
            | SCF_ColorTemp
            | SCF_CK
            | SCF_HW,

        SCF_All = 0x00ffffff,
    }

    public enum strech_type : byte
    {
        STRECH_TYPE_PHE = 1,
        STRECH_TYPE_LINEAR,
        STRECH_TYPE_CK,
        STRECH_TYPE_HW,
    }

    public enum ColorTempType : byte
    {
        None,
        High,
        Low,
        Mid,
        ExMid,
    }

    [StructLayout(LayoutKind.Sequential, Size = 64)]
    public struct strech_control
    {
        public StrechControlFlags flags;

        public strech_type strech_type;
        public byte contrast;
        public byte brightness;
        public byte phe_stream;

        public float gain;

        public short man_temp0;
        public short man_temp1;
        public byte man_enable;
        byte pad;

        public byte dde_level;

        public ColorTempType ct_type;
        public short ct_temp0;
        public short ct_temp1;
        public int ct_color0;
        public int ct_color1;

        //ck20211113
        public short ck_lowDelta;//0.1C
        public byte ck_lowPercent;//%1
        byte pad2_1;
        int pad2_4;

        //hw20211216
        public short hw_lowDelta;//
        public byte hw_lowPercent;//%1

        public void Reset()
        {
            flags = StrechControlFlags.SCF_All;
            strech_type = strech_type.STRECH_TYPE_PHE;
            brightness = 50;
            contrast = 50;

            gain = 2.0f;
            dde_level = 0;

            //
            man_temp0 = 200; man_temp1 = 400;
            man_enable = 0;

            //
            phe_stream = 0;

            //
            ct_type = ColorTempType.None;
            ct_temp0 = 200; ct_color0 = 0x000000;
            ct_temp1 = 400; ct_color1 = 0x000000;

            //
            ck_lowDelta = 150;
            ck_lowPercent = 2;

            //
            hw_lowDelta = 150;
            hw_lowPercent = 2;
        }
    }

    [StructLayout(LayoutKind.Sequential, Size = 1024)]
    public struct H264FrameHeaderV2
    {
        public int Size;

        public ushort Width;
        public ushort Height;

        public int ShellTemp;
        public int LocalResultFlags;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
        public xxxresult[] ResultArray;

        public static H264FrameHeaderV2 Create()
        {
            H264FrameHeaderV2 x = new H264FrameHeaderV2();
            x.ResultArray = new xxxresult[17];
            return x;
        }
    }

    [StructLayout(LayoutKind.Sequential, Size = 20)]
    public struct xxxshield
    {
        public byte id;

        byte pad1;
        byte pad2;
        byte pad3;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public ushort[] xydata;

        public static xxxshield Create()
        {
            xxxshield x = new xxxshield();
            x.xydata = new ushort[8];
            return x;
        }

        public static xxxshield Create(ref xxxshield a)
        {
            xxxshield x = new xxxshield();
            x.xydata = new ushort[8];
            x.Copy(ref a);
            return x;
        }

        public static xxxshield[] CreateArray(int count)
        {
            xxxshield[] a = new xxxshield[count];
            int i = 0;
            for (; i < count; i++)
            {
                a[i].xydata = new ushort[8];
            }
            return a;
        }

        public void Copy(ref xxxshield x)
        {
            id = x.id;

            ushort[] xydata2 = x.xydata;
            int i = 0;
            for (; i < 8; i++)
            {
                xydata[i] = xydata2[i];
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, Size = 152)]
    public struct xxxmeasure
    {
        public byte id;
        public xxxmeasuretype measuretype;

        public byte points;
        public byte emmi;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public ushort[] xydata;


        public xxxalarmtype alarmtype;
        public xxxmeasureflags measureflags;

        public xxxtextpos textpos;
        byte pad;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public float[] alarmdata;		//t0,t1,t2

        public static xxxmeasure Create()
        {
            xxxmeasure n = new xxxmeasure();
            n.id = 0;
            n.measuretype = xxxmeasuretype.point;
            n.points = 0;
            n.emmi = 97;
            n.xydata = new ushort[64];

            n.alarmtype = xxxalarmtype.none;
            n.measureflags = xxxmeasureflags.plot_max;
            n.textpos = xxxtextpos.RightBottom;
            n.alarmdata = new float[4];
            return n;
        }

        public static xxxmeasure Create(ref xxxmeasure x)
        {
            xxxmeasure n = new xxxmeasure();
            n.id = x.id;
            n.measuretype = x.measuretype;
            n.points = x.points;
            n.emmi = x.emmi;
            n.xydata = new ushort[64];

            n.alarmtype = x.alarmtype;
            n.measureflags = x.measureflags;
            n.textpos = xxxtextpos.RightBottom;
            n.alarmdata = new float[4];

            //
            int i = 0;
            for (; i < 64; i++)
            {
                n.xydata[i] = x.xydata[i];
            }
            for (i = 0; i < 4; i++)
            {
                n.alarmdata[i] = x.alarmdata[i];
            }

            return n;
        }

        public static xxxmeasure[] CreateArray(int count)
        {
            xxxmeasure[] a = new xxxmeasure[count];
            int i = 0;
            for (; i < count; i++)
            {
                a[i].xydata = new ushort[64];
                a[i].alarmdata = new float[4];
            }
            return a;
        }

        public void Copy(ref xxxmeasure x)
        {
            id = x.id;
            measuretype = x.measuretype;
            points = x.points;
            emmi = x.emmi;

            int i = 0;
            for (; i < 64; i++)
            {
                xydata[i] = x.xydata[i];
            }

            alarmtype = x.alarmtype;
            measureflags = x.measureflags;
            textpos = x.textpos;
            for (i = 0; i < 4; i++)
            {
                alarmdata[i] = x.alarmdata[i];
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, Size = 24)]
    public struct xxxresult
    {
        public int alarmLevel;

        public ushort maxX;
        public ushort maxY;
        public ushort minX;
        public ushort minY;

        public float max;
        public float min;
        public float avg;
    }

    [StructLayout(LayoutKind.Sequential, Size = 128)]
    public struct MeasureTemplateHead
    {
        public int Version;

        public ushort Width;
        public ushort Height;

        public int ShieldFlags;
        public int LMOFlags;
    }

    [StructLayout(LayoutKind.Sequential, Size = ConstSize)]
    public struct MeasureTemplate
    {
        public const int ConstSize = 2872;

        public MeasureTemplateHead Head;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public xxxshield[] ShieldArray;

        public xxxmeasure GMO;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public xxxmeasure[] LMOArray;

        public static MeasureTemplate Create()
        {
            MeasureTemplate x = new MeasureTemplate();
            x.GMO = xxxmeasure.Create();
            x.ShieldArray = xxxshield.CreateArray(8);
            x.LMOArray = xxxmeasure.CreateArray(16);
            return x;
        }

        public void Copy(ref MeasureTemplate x)
        {
            Head = x.Head;

            //gmo+lmos
            GMO.Copy(ref x.GMO);
            int i = 0;
            for (; i < 16; i++)
            {
                LMOArray[i].Copy(ref x.LMOArray[i]);
            }

            //shields
            for (i = 0; i < 8; i++)
            {
                ShieldArray[i].Copy(ref x.ShieldArray[i]);
            }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MeasureTemplateResult
    {
        public xxxresult GMR;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public xxxresult[] LMRArray;

        public static MeasureTemplateResult Create()
        {
            MeasureTemplateResult x = new MeasureTemplateResult();
            x.LMRArray = new xxxresult[16];
            return x;
        }
    }
}
