using System;
using System.Runtime.InteropServices;

namespace NZSDK_CSharpSample
{
    public partial class NZSDK
    {
        #region Constraints

        public enum Models : int
        {
            Unknown = 0,
            Rhino,
            Leopard
        }

        public enum SessionTypes : int
        {
            Live = 0,
            Playback
        }

        public enum StreamTypes : int
        {
            Video = 0,
            Audio,
            Event,
            CameraDisconnected,
            ServerDisconnected
        }

        public enum CodecKinds : int
        {
            H264 = 0,
            MPEG4,
            JPEG,
            YUV420P,
            PCM,
            G711A,
            G711U,
            G726
        }

        public enum EventTypes : int
        {
            Record = 0,
            Alarm,
            Motion,
            LossVideoHighStream,
            LossVideoLowStream,
            TextIn,
            DiskTemperature,
            DiskSMART,
            DiskBad
        }

        public enum StatusTypes : int
        {
            CameraConnected = 0,
            CameraVideoLoss,
            ServerConnected,
            ServerVideoLoss
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct StreamVideo
        {
            public CodecKinds Codec;
            public UInt64 Stream;
            public int StreamLength;
            [MarshalAs(UnmanagedType.Bool)]
            public bool KeyFrame;
            public UInt32 Width;
            public UInt32 Height;
            [MarshalAs(UnmanagedType.Bool)]
            public bool RecordingStatus;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct StreamAudio
        {
            public CodecKinds Codec;
            public UInt64 Stream;
            public int StreamLength;
            public int BitRate;
            public int SampleRate;
            public int Channels;
            public int BitPerSample;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct StreamEvent
        {
            public EventTypes Event;
            [MarshalAs(UnmanagedType.Bool)]
            public bool Triggered;
            public int DataSize;
            public UInt64 ExtraData;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct StreamStatus
        {
            public StatusTypes Status;
            [MarshalAs(UnmanagedType.Bool)]
            public bool Triggered;
            public int DataSize;
            public UInt64 ExtraData;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct StreamData
        {
            [FieldOffset(0)]
            public StreamVideo Video;

            [FieldOffset(0)]
            public StreamAudio Audio;

            [FieldOffset(0)]
            public StreamEvent Event;

            [FieldOffset(0)]
            public StreamStatus Status;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEMTIME
        {
            public UInt16 Year;
            public UInt16 Month;
            public UInt16 DayOfWeek;
            public UInt16 Day;
            public UInt16 Hour;
            public UInt16 Minute;
            public UInt16 Second;
            public UInt16 Milliseconds;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Stream
        {
            public StreamTypes Type;
            public int Channel;
            public int StreamNumber;
            public SYSTEMTIME SystemTime;
            public UInt32 FileTime;
            public UInt16 Milisecond;
            public StreamData Data;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct PtzPositionSpecification
        {
            [MarshalAs(UnmanagedType.Bool)]
            public bool SupportPanTiltPosition;
            [MarshalAs(UnmanagedType.Bool)]
            public bool SupportZoomPosition;
            public double MinPanPosition;
            public double MaxPanPosition;
            public double MinTiltPosition;
            public double MaxTiltPosition;
            public double MinZoomPosition;
            public double MaxZoomPosition;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct PtzPosition
        {
            public double PanPosition;
            public double TiltPosition;
            public double ZoomPosition;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct ViewFont
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string FontName;
            public int Height;
        }

        public enum VmsDataTypes
        {
            Unknown = 0,
            Camera,
            Nrs,
            RecordSchedule,
            User,
            Client,
            Facility
        }

        public enum ExportMessages
        {
            Started = 0,
            Finished,
            Updated
        }

        public delegate void ExportMessageHandler(ExportMessages message, IntPtr param1, IntPtr param2, IntPtr userParam);

        public enum LogSearchMessages
        {
            Data = 0,
            Finished
        }

        public delegate void LogSearchHandler(LogSearchMessages message, IntPtr param1, IntPtr param2, IntPtr userParam);

        public enum VMSErrorCodes : uint
        {
            Ok = 0,
            Invalid = 1,
            NotOnline = 3,
            Internal = 4,
            AlreadyRunning = 5,
            DiskFull = 6,
            SystemError = 7,
            NotFound = 8,
            ServerAuth = 500,
            ServerInvalid = 501,
            Exception = 1000
        }

        public const UInt32 CommandBase = 0x10000000;

        public enum Commands : uint
        {
            Unknown = CommandBase | 0x00000000,
            Connect = CommandBase | 0x00000001,
            Disconnect = CommandBase | 0x00000002,
            OpenVideo = CommandBase | 0x00010001,
            CloseVideo = CommandBase | 0x00010002,
            OpenAudio = CommandBase | 0x00010011,
            CloseAudio = CommandBase | 0x00010012,
            OpenEvent = CommandBase | 0x00010021,
            CloseEvent = CommandBase | 0x00010022,
            GetRecordedData = CommandBase | 0x00011001,
            GetStream = CommandBase | 0x00012001,
            ReleaseStream = CommandBase | 0x00012002,
            PtzMoveLeft = CommandBase | 0x00020001,
            PtzMoveRight = CommandBase | 0x00020002,
            PtzMoveUp = CommandBase | 0x00020003,
            PtzMoveDown = CommandBase | 0x00020004,
            PtzMoveLeftUp = CommandBase | 0x00020005,
            PtzMoveLeftDown = CommandBase | 0x00020006,
            PtzMoveRightUp = CommandBase | 0x00020007,
            PtzMoveRightDown = CommandBase | 0x00020008,
            PtzZoomTele = CommandBase | 0x00020011,
            PtzZoomWide = CommandBase | 0x00020012,
            PtzFocusIn = CommandBase | 0x00020013,
            PtzFocusOut = CommandBase | 0x00020014,
            PtzGetPresetCount = CommandBase | 0x00020021,
            PtzGetPresets = CommandBase | 0x00020022,
            PtzSetPreset = CommandBase | 0x00020023,
            PtzMovePreset = CommandBase | 0x00020024,
            PtzTourStart = CommandBase | 0x00020031,
            PtzTourStop = CommandBase | 0x00020032,

            PtzAux = CommandBase | 0x00020033,
            PtzGetPositionSpecification = CommandBase | 0x00020034,
            PtzGetPosition = CommandBase | 0x00020035,
            PtzSetPosition = CommandBase | 0x00020036,
            StartTalk = CommandBase | 0x00030001,
            StopTalk = CommandBase | 0x00030002,
            SendWave = CommandBase | 0x00030003,
            ViewResize = CommandBase | 0x00040001,
            ViewShowSelection = CommandBase | 0x00040003,
            ViewShowZone = CommandBase | 0x00040004,
            ViewShowDetect = CommandBase | 0x00040005,
            ViewShowName = CommandBase | 0x00040006,
            ViewRotate = CommandBase | 0x00040007,
            ViewShowNameEx = CommandBase | 0x00040008,
            PlaybackOpenVideo = CommandBase | 0x00050001,
            PlaybackCloseVideo = CommandBase | 0x00050002,
            PlaybackPlay = CommandBase | 0x00050003,
            PlaybackPause = CommandBase | 0x00050004,
            PlaybackSpeed = CommandBase | 0x00050005,
            ExportVideo = CommandBase | 0x00060001,
            CancelExportVideo = CommandBase | 0x00060002,
            ExportImage = CommandBase | 0x00060003,
            GetDatas = CommandBase | 0x00100001
        }

        #endregion

        #region Functions for NRS

        #region NZCreate

        protected delegate IntPtr NZCreateDelegate(SessionTypes session);

        protected NZCreateDelegate _NZCreate
        {
            get
            {
                return (NZCreateDelegate)GetProcAddress("NZ_Create", typeof(NZCreateDelegate));
            }
        }

        #endregion

        #region NZCreateEx

        protected delegate IntPtr NZCreateExDelegate(SessionTypes session, Models model);

        protected NZCreateExDelegate _NZCreateEx
        {
            get
            {
                return (NZCreateExDelegate)GetProcAddress("NZ_CreateEx", typeof(NZCreateExDelegate));
            }
        }

        #endregion

        #region NZDelete

        protected delegate void NZDeleteDelegate(IntPtr handle);

        protected NZDeleteDelegate _NZDelete
        {
            get
            {
                return (NZDeleteDelegate)GetProcAddress("NZ_Delete", typeof(NZDeleteDelegate));
            }
        }

        #endregion

        #region NZCommand

        protected delegate bool NZCommandDelegate(IntPtr handle, Commands command, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5);

        protected NZCommandDelegate _NZCommand
        {
            get
            {
                return (NZCommandDelegate)GetProcAddress("NZ_Command", typeof(NZCommandDelegate));
            }
        }

        #endregion

        #endregion

        #region Functions for VMS / NVR

        #region NZVMSCreate

        protected delegate IntPtr NZVMSCreateDelegate();

        protected NZVMSCreateDelegate _NZVMSCreate
        {
            get
            {
                return (NZVMSCreateDelegate)GetProcAddress("NZ_VMS_Create", typeof(NZVMSCreateDelegate));
            }
        }

        #endregion

        #region NZVMSDelete

        protected delegate void NZVMSDeleteDelegate(IntPtr handle);

        protected NZVMSDeleteDelegate _NZVMSDelete
        {
            get
            {
                return (NZVMSDeleteDelegate)GetProcAddress("NZ_VMS_Delete", typeof(NZVMSDeleteDelegate));
            }
        }

        #endregion

        #region NZVMSGetLastError

        protected delegate UInt32 NZVMSGetLastErrorDelegate(IntPtr handle);

        protected NZVMSGetLastErrorDelegate _NZVMSGetLastError
        {
            get
            {
                return (NZVMSGetLastErrorDelegate)GetProcAddress("NZ_VMS_GetLastError", typeof(NZVMSGetLastErrorDelegate));
            }
        }

        #endregion

        #region NZVMSReleaseData

        protected delegate void NZVMSReleaseDataDelegate(IntPtr buffer);

        protected NZVMSReleaseDataDelegate _NZVMSReleaseData
        {
            get
            {
                return (NZVMSReleaseDataDelegate)GetProcAddress("NZ_VMS_ReleaseData", typeof(NZVMSReleaseDataDelegate));
            }
        }

        #endregion

        #region NZVMSCommand

        protected delegate bool NZVMSCommandDelegate(IntPtr handle, Commands command, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5);

        protected NZVMSCommandDelegate _NZVMSCommand
        {
            get
            {
                return (NZVMSCommandDelegate)GetProcAddress("NZ_VMS_Command", typeof(NZVMSCommandDelegate));
            }
        }

        #endregion

        #endregion
    }
}