using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetSDKCS;
using System.Runtime.InteropServices;
using System.Windows.Threading;

namespace NetClient
{
    /// <summary>
    /// base client class.
    /// </summary>
    public class BaseClient : DispatcherObject, IDisposable
    {
        private IntPtr m_LoginID = IntPtr.Zero;
        /// <summary>
        /// LoginID property.only can get.
        /// </summary>
        public IntPtr LoginID
        {
            get { return m_LoginID; }
            set { m_LoginID = value; }
        }

        private string m_IP = "";
        /// <summary>
        /// ip property.only can get.
        /// </summary>
        public string IP
        {
            get { return m_IP; }
        }

        private int m_Port = 0;
        /// <summary>
        /// port property.only can get.
        /// </summary>
        public int Port
        {
            get { return m_Port; }
        }

        private NET_DEVICEINFO m_DeviceInfo;
        /// <summary>
        /// device information property.only can get.
        /// </summary>
        public NET_DEVICEINFO DeviceInfo
        {
            get { return m_DeviceInfo; }
        }

        private uint m_WaitTime = 3000;
        /// <summary>
        /// wait time property.
        /// </summary>
        public uint WaitTime
        {
            get { return m_WaitTime; }
            set { m_WaitTime = value; }
        }

        /// <summary>
        /// disconnect event.must subscription before call login function.
        /// </summary>
        public event DeviceHandler DisConnectChanged;
        internal void OnDisConnectChanged(object sender, DeviceEventArgs args)
        {
            if (DisConnectChanged != null)
            {
                IntPtr n_LoginID = (IntPtr)sender;
                if (n_LoginID == LoginID)
                {
                    DisConnectChanged(this, args);
                }
            }
        }
        /// <summary>
        /// reconnect event.must subscription before call login function.
        /// </summary>
        public event DeviceHandler ReConnectChanged;
        internal void OnReConnectChanged(object sender, DeviceEventArgs args)
        {
            if (ReConnectChanged != null)
            {
                IntPtr n_LoginID = (IntPtr)sender;
                if (n_LoginID == LoginID)
                {
                    ReConnectChanged(this, args);
                }
            }
        }

        /// <summary>
        /// singleton object.for call init function only one.
        /// </summary>
        private BaseDevice Parent
        {
            get;
            set;
        }

        public BaseClient()
        {
            Parent = BaseDevice.GetInstance();
        }

        /// <summary>
        /// login device function.
        /// </summary>
        /// <param name="ip">device ip</param>
        /// <param name="port">device port</param>
        /// <param name="username">username</param>
        /// <param name="password">password</param>
        public virtual void Login(string ip, ushort port, string username, string password)
        {
            NET_DEVICEINFO_Ex deviceInfo = new NET_DEVICEINFO_Ex();
            try
            {
                //call netsdk login function.use tcp login.
                m_LoginID = NETClient.Login(ip, port, username, password, EM_LOGIN_SPAC_CAP_TYPE.TCP, IntPtr.Zero, ref deviceInfo);
                m_DeviceInfo.sSerialNumber = deviceInfo.sSerialNumber;
                m_DeviceInfo.nAlarmInPortNum = deviceInfo.nAlarmInPortNum;
                m_DeviceInfo.nAlarmOutPortNum = deviceInfo.nAlarmOutPortNum;
                m_DeviceInfo.nDiskNum = deviceInfo.nDiskNum;
                m_DeviceInfo.nDVRType = deviceInfo.nDVRType;
                m_DeviceInfo.nChanNum = deviceInfo.nChanNum;
                m_DeviceInfo.byLimitLoginTime = deviceInfo.byLimitLoginTime;
                m_DeviceInfo.byLeftLogTimes = deviceInfo.byLeftLogTimes;
                m_DeviceInfo.bReserved = deviceInfo.bReserved;
                m_DeviceInfo.nLockLeftTime = deviceInfo.nLockLeftTime;
                m_DeviceInfo.Reserved = deviceInfo.Reserved;
                m_IP = ip;
                m_Port = (int)port;
                Parent.AddDisConnectHandler(OnDisConnectChanged);
                Parent.AddDisConnectHandler(OnReConnectChanged);
            }
            catch (NetSDKCS.NETClientExcetion ex)
            {
                throw new NETClientExcetion(ex.ErrorCode, ex.Message);
            }
        }

        /// <summary>
        /// logout device.
        /// </summary>
        public virtual void Logout()
        {
            if (m_LoginID != IntPtr.Zero)
            {
                try
                {
                    NETClient.Logout(m_LoginID);
                    Parent.RemoveDisConnectHandler(OnDisConnectChanged);
                    Parent.RemoveDisConnectHandler(OnReConnectChanged);
                }
                catch
                {
                }
                finally
                {
                    m_LoginID = IntPtr.Zero;
                    m_IP = "";
                    m_Port = 0;
                    m_DeviceInfo = new NET_DEVICEINFO();
                }
            }
        }

        /// <summary>
        /// query device system info.
        /// </summary>
        /// <param name="nSystemType"></param>
        /// <param name="obj"></param>
        public void QuerySystemInfo(EM_SYS_ABILITY nSystemType, ref object obj)
        {
            try
            {
                NETClient.QuerySystemInfo(LoginID, (NetSDKCS.EM_SYS_ABILITY)nSystemType, ref obj, (int)m_WaitTime);
            }
            catch (NetSDKCS.NETClientExcetion ex)
            {
                throw new NETClientExcetion(ex.ErrorCode, ex.Message);
            }
        }

        ~BaseClient()
        {
            Logout();
        }

        public virtual void Dispose()
        {
            Logout();
        }
    }

    /// <summary>
    /// device information struct.
    /// </summary>
    public struct NET_DEVICEINFO
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
        public byte[] sSerialNumber;	                        // serial number
        public int nAlarmInPortNum;                             // count of DVR alarm input
        public int nAlarmOutPortNum;                            // count of DVR alarm output
        public int nDiskNum;                                    // number of DVR disk
        public int nDVRType;                                    // DVR type, refer to EM_NET_DEVICE_TYPE
        public int nChanNum;                                    // number of DVR channel
        public byte byLimitLoginTime;                           // Online Timeout, Not Limited Access to 0, not 0 Minutes Limit Said
        public byte byLeftLogTimes;                             // When login failed due to password error, notice user by this parameter.This parameter is invalid when remaining login times is zero.
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] bReserved;                                // keep bytes for aligned
        public int nLockLeftTime;                               // when log in failed,the left time for users to unlock (seconds), -1 indicate the device haven't set the parameter 
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
        public byte[] Reserved;                                 // reserved
    }

    /// <summary>
    /// enum device system ability.
    /// </summary>
    public enum EM_SYS_ABILITY
    {
        DYNAMIC_CONNECT = 1,                                                // dynamic connect capacity
        WATERMARK_CFG = 17,			                                        // Watermark configuration capacity
        WIRELESS_CFG = 18,			                                        // wireless  configuration capacity
        DEVALL_INFO = 26,			                                        // Device capacity list 
        CARD_QUERY = 0x0100,		                                        // Card number search capacity 
        MULTIPLAY = 0x0101,			                                        // Multiple-window preview capacity 
        QUICK_QUERY_CFG = 0x0102,	                                        // Fast query configuration Capabilities
        INFRARED = 0x0121,			                                        // Wireless alarm capacity 
        TRIGGER_MODE = 0x0131,		                                        // Alarm activation mode function 
        DISK_SUBAREA = 0x0141,		                                        // Network hard disk partition
        DSP_CFG = 0x0151,			                                        // Query DSP Capabilities
        STREAM_MEDIA = 0x0161,		                                        // Query SIP,RTSP Capabilities
        INTELLI_TRACKER = 0x0171,                                           // Search intelligent track capability.
    }

    /// <summary>
    /// device enable information struct.
    /// </summary>
    public struct NET_DEV_ENABLE_INFO
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
        public uint[] IsFucEnable;			                                // Function list capacity set. Corresponding to the above mentioned enumeration. Use bit to represent sub-function.
    }

    /// <summary>
    /// enum device enable type.
    /// </summary>
    public enum EM_DEV_ENABLE_TYPE
    {
        FTP = 0,						                                    // FTP bitwise, 1: send out record file;  2: Send out snapshot file
        SMTP,						                                        // SMTP bitwise,1: alarm send out text mail 2: Alarm send out image3:support HealthMail
        NTP,							                                    // NTP	 Bitwise:1:Adjust system time 
        AUTO_MAINTAIN,				                                        // Auto maintenance  Bitwise:1:reboot 2:close  3:delete file
        VIDEO_COVER,					                                    // Privacy mask Bitwise  :1:multiple-window privacy mask 
        AUTO_REGISTER,				                                        // Auto registration	Bitwise:1:SDK auto log in after registration 
        DHCP,						                                        // DHCP	Bitwise 1:DHCP
        UPNP,						                                        // UPNP	Bitwise 1:UPNP
        COMM_SNIFFER,				                                        // COM sniffer  Bitwise :1:CommATM
        NET_SNIFFER,					                                    // Network sniffer Bitwise : 1:NetSniffer
        BURN,						                                        // Burn function Bitwise 1:Search burn status 
        VIDEO_MATRIX,				                                        // Video matrix Bitwise  1:Support video matrix or not 2:Support SPOT video matrix or not
        AUDIO_DETECT,				                                        // Video detection Bitwise :1:Support video detection or not 
        STORAGE_STATION,				                                    // Storage position Bitwise:1:Ftp server (Ips) 2:SBM 3:NFS 16:DISK 17:Flash disk 
        IPSSEARCH,					                                        // IPS storage search  Bitwise  1:IPS storage search 	
        SNAP,						                                        // Snapshot Bitwise  1:Resoluiton 2:Frame rate 3:Snapshoot  4:Snapshoot file image; 5:Image quality 
        DEFAULTNIC,					                                        // Search default network card search  Bitwise  1:Support
        SHOWQUALITY,					                                    // Image quality configuration time in CBR mode 1:support 
        CONFIG_IMEXPORT,				                                    // Configuration import& emport function capacity.  Bitwise   1:support 
        LOG,							                                    // Support search log page by page or not. Bitwise 1:support 
        SCHEDULE,					                                        // Record setup capacity. Bitwise  1:Redandunce  2:Pre-record 3:Record period
        NETWORK_TYPE,				                                        // Network type. Bitwise 1:Wire Network 2:Wireless Network 3:CDMA/GPRS,4:CDMA/GPRS multi network card
        MARK_IMPORTANTRECORD,		                                        // Important record. Bitwise 1:Important record mark
        ACFCONTROL,					                                        // Frame rate control activities. Bitwise 1:support frame rate control activities;2:support timing alarm type activate frame rate control(it does not support dynamic detection), this ability mutually exclusive with ACF ability.
        MULTIASSIOPTION,				                                    // Multiple-channel extra stream. Bitwise:1:support three channel extra stream
        DAVINCIMODULE,				                                        // Component modules bitwise: 1.Separate processing the schedule 2.Standard I franme Interval setting
        GPS,                                                                // GPS function bitwise:1:Gps locate function	
        MULTIETHERNET,				                                        // Support multi net card query   bitwise: 1: support
        LOGIN_ATTRIBUTE,                                                    // Login properties   bitwise: 1: support query login properties  
        RECORD_GENERAL,				                                        // Recording associated  bitwise: 1:Normal recording; 2:Alarm recording; 
        // 3:Motion detection recording;  4:Local storage; 5: Network storage ;  
        // 6:Redundancy storage;  7:Local emergency storage
        JSON_CONFIG,					                                    // Whether support Json configuration, bitwise: 1: support Json
        HIDE_FUNCTION,				                                        // Hide function:bitwise::1,hide PTZ function
        DISK_DAMAGE,                                                        // Harddisk damage information support ability: bitwise:1,harddisk damage information
        PLAYBACK_SPEED_CTRL,			                                    // Support playback network transmission speed control, bitwise::1 support playback acceleration 
        HOLIDAYSCHEDULE,				                                    // Support holiday period setup : bitwise:1,Support holiday period setup 
        FETCH_MONEY_TIMEOUT,			                                    // ATM fetch money overtime
        BACKUP_VIDEO_FORMAT,			                                    // Device backup support format. DAV, ASF
        QUERY_DISK_TYPE,                                                    // backup disk type query
        CONFIG_DISPLAY_OUTPUT,                                              // backup device output of display (such as VGA) configuration, by bit: 1: configuration on tour of frame segmentation 
        SUBBITRATE_RECORD_CTRL,                                             // backup extra stream control configuration, by bit: 1-extra stream control configuration
        IPV6,                                                               // backup IPV6 configuration, by bit:1-IPV6 configuration
        SNMP,                                                               // SNMP
        QUERY_URL,                                                          // back up query device's URL info, by bit: 1-query device's config URL info
        ISCSI,						                                        // ISCSI
        RAID,						                                        // Raid
        HARDDISK_INFO,				                                        // Support disk info query
        PICINPIC,                                                           // support picture in pictu,by bit:1,set; 2,preview , record , query record , download record
        PLAYBACK_SPEED_CTRL_SUPPORT,                                        // same to EN_PLAYBACK_SPEED_CTRL
        LF_XDEV,						                                    // support LF-X series of 24, 32, 64 channels, label their encode ability with sepcial calculation, by bit 1: able;
        DSP_ENCODE_CAP,				                                        // support F5 DSP encode
        MULTICAST,                                                          // support different multicast config for different channel
        NET_LIMIT,   				                                        // query the limit ability of net, bitwise,1-limit size of net send code stream  
        COM422, 						                                    // serial port 422
        PROTOCAL_FRAMEWORK,			                                        // support three generations of framework agrement or not(need actualize listMethod(),listService()),by F6 to visit
        WRITE_DISK_OSD,				                                        // write disk OSD overlying ,bitwise, 1-write disk OSD overlying configuration
        DYNAMIC_MULTI_CONNECT,		                                        // dynamic multi-connect,bitise,1-request reply video data
        CLOUDSERVICE,  				                                        // cloud service,bitwise,1- support private cloud service
        RECORD_INFO,					                                    // Video Information Report, by bit. 1-Active video information report, 2-Frame numbers inquiry support
        DYNAMIC_REG,                                                        // Active Register Support, by bit. 1- Dynamic active register support.
        MULTI_PLAYBACK,                                                     // Multi-channel Preview and Playback, by bit. 1-Multi-channel preview and playback support.
        ENCODE_CHN,					                                        // Encoding Channel, by bit. 1- Audio-only channel support
        SEARCH_RECORD,                                                      // Record search, by bit, 1-support sync search record, 2-support 3rd generation protocol search record
        UPDATE_MD5,                                                         // Support MD5 check after update file send finish，1- support MD5
    }
}
