using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;

using SystemX.Net.BaseProtocol;

namespace SystemX.Net.XAdaptor
{
    public enum SAVE_TABLE_LIST
    {
        HIST_ProdLoad = 0,
        HIST_CapDeassy = 1,
        HIST_PreHeating = 2,
        HIST_PreMeas = 3,
        HIST_Leak = 4,
        HIST_LaserTrim = 5,
        HIST_IsoRes = 6,
        HIST_CapAssy = 7,
        HIST_Function = 8,
        HIST_OutSealPress = 9,
        HIST_PinVision = 10,
        HIST_ProdUnload = 11,
        HIST_GrsDisp = 11
    }

    public enum eResultCheck
    {
        None = -1024,
        InvalidFormat = -4,
        InvalidMacAddressFormat = -2,
        AlreadyIssued = -1,
        NotIssued = 0
    }

    public enum eResultIssued
    {
        None = -1024,
        InvalidFormat = -128,
        InformationThatDoesNotExist = -64,
        InformationWithoutIssuanceHistory = -3,
        AlreadyIssued = -2,
        Failed = -1,
        Success = 0
    }

    public enum eMacAddressType
    {
        InvalidMacAddressFormat = -1,
        Normal = 0,
        Colon = 1,
        Hyphen = 2,
        Dot = 3,
    }

    public enum eLookUpOption
    {
        CompareToSame = 0,
        StartWith = 1,
        EndWith = 2,
        ContainWith = 3
    }

    [Flags]
    public enum eFileSendRecvResult
    {
        None = 0x8000,
        StreamSocketNoConnect = 0x8001,
        ConnectInitializeFail = 0x8002,
        NoFileTransferPermission = 0x8004,
        FileSizeOver = 0x8008,
        FileAccessError = 0x8010,
        FileProcFailed = 0x8020,
        //OppoentRecvNG = 0x8040,
        //OppoentRecvOKProcNG = 0x8080,
        MonitorLockUpState = 0x8100,
        FileProcSuccess = 0x0000,
        //OppoentRecvOKProcOK = 0x0000
    }

    public enum eSetConfigFileResult
    {
        None = 0,
        SetConfigFail = -1,
        SetConfigSuccess = 1
    }

    public enum eSetFileLogCategory
    {
        None = 0,
        FileLog = 1,
        FTPFileLog = 2
    }

    public class ResultIssued
    {
        public eResultIssued eResult;
        public string strMacAddress;
        public string strErrMessage;

        public ResultIssued(eResultIssued setResult) { 
            eResult = setResult;
            strMacAddress = string.Empty;
            strErrMessage = string.Empty;
        }

        public ResultIssued(eResultIssued setResult, string strSetMacAddress, string strSetErrMsg)
        {
            eResult = setResult;
            strMacAddress = strSetMacAddress;
            strErrMessage = strSetErrMsg;
        }
    }

    public class ClientConnInfo
    {
        public string CONNECT_IP { set; get; }
        public string SECTION { set; get; }
        public string HOST_ID { set; get; }
        public string TEST_CODE { set; get; }

        public int COMMAND_PORT { set; get; }
        public int STREAM_PORT { set; get; }

        public bool LOGIN_RESULT { set; get; }
        public string LOGIN_MESSAGE { set; get; }

        public ClientConnInfo()
        {
            CONNECT_IP = string.Empty;
            SECTION = string.Empty;
            HOST_ID = string.Empty;
            TEST_CODE = string.Empty;

            COMMAND_PORT = int.MaxValue;
            STREAM_PORT = int.MaxValue;

            LOGIN_RESULT = false;
            LOGIN_MESSAGE = string.Empty;
        }
    }

    public class SubscriberClient
    {
        public bool bUIMUseMode;

        public bool bSetChangeConnect;

        public bool bReqConnectAbort;

        public int nChangeCommandPort;
        public int nChangeStreamPort;

        public DateTime dtSessionTime;

        public bool bSessionStarted;

        public bool bSubscriberClientResult;

        public SubscriberClient()
        {
            bUIMUseMode = false;

            bSetChangeConnect = false;

            bReqConnectAbort = false;

            nChangeCommandPort = 0;
            nChangeStreamPort = 0;

            dtSessionTime = DateTime.Now;

            bSessionStarted = false;

            bSubscriberClientResult = false;
        }

        public void Initialize()
        {
            bUIMUseMode = false;

            bSetChangeConnect = false;

            bReqConnectAbort = false;

            nChangeCommandPort = 0;
            nChangeStreamPort = 0;

            dtSessionTime = DateTime.Now;

            bSessionStarted = false;

            bSubscriberClientResult = false;
        }

        public void SessionTimeSet()
        {
            dtSessionTime = DateTime.Now;
        }

        public TimeSpan GetSessionTime()
        {
            return DateTime.Now - dtSessionTime;
        }
    }

    public class ClientInfoStore
    {
        public bool ConnectCommandState { set; get; }

        public bool ConnectStreamState { set; get; }

        public bool InitialInfoState { set; get; }

        public int m_iSendCommandCnt { set; get; }
        public int m_iRecvCommandCnt { set; get; }

        public int m_iSendStreamCnt { set; get; }
        public int m_iRecvStreamCnt { set; get; }

        public int m_iSendCommandQueueSize { set; get; }
        public int m_iRecvCommandQueueSize { set; get; }

        public int m_iSendStreamQueueSize { set; get; }
        public int m_iRecvStreamQueueSize { set; get; }

        /// <summary>
        /// Big Size File
        /// </summary>
        public List<Tuple<int, byte[]>> lstRecvFileBytes { set; get; }
        public int nFileRecvPos { set; get; }
        public int nFileRecvEndPos { set; get; }

        public string strRecvFileName { set; get; }
        public string strRecvExtension { set; get; }

        //LastProcessTime
        public Stopwatch stCommandProcessTime;
        public long lCommandTime;

        public Stopwatch stStreamProcessTime;
        public long lStreamTime;

        //Ping Check Time
        public Stopwatch stCommandCheckTime;
        public Stopwatch stStreamCheckTime;
        //
        public bool bHostLoginState;
        public Stopwatch stLoginTimeOut;

        public void OnCommandTime() { stCommandProcessTime.Restart(); }
        public void OffCommandTime() { lCommandTime = stCommandProcessTime.ElapsedMilliseconds; }
        public void OnStreamTime() { stStreamProcessTime.Restart(); }
        public void OffStreamTime() { lStreamTime = stStreamProcessTime.ElapsedMilliseconds; }
        //
        public void OnCommandCheckTime() { stCommandCheckTime.Restart(); }
        public void OnStreamCheckTime() { stStreamCheckTime.Restart(); }
        //

        public ClientInfoStore()
        {
            ConnectCommandState = false;
            ConnectStreamState = false;

            InitialInfoState = false;

            m_iSendCommandCnt = 0;
            m_iRecvCommandCnt = 0;

            m_iSendStreamCnt = 0;
            m_iRecvStreamCnt = 0;

            m_iSendCommandQueueSize = 0;
            m_iRecvCommandQueueSize = 0;

            m_iSendStreamQueueSize = 0;
            m_iRecvStreamQueueSize = 0;

            lstRecvFileBytes = new List<Tuple<int, byte[]>>();
            nFileRecvPos = 0;
            nFileRecvEndPos = 0;

            strRecvFileName = string.Empty;
            strRecvExtension = string.Empty;

            //
            stCommandProcessTime = new Stopwatch();
            stCommandProcessTime.Start();
            lCommandTime = 0;

            stStreamProcessTime = new Stopwatch();
            stStreamProcessTime.Start();
            lStreamTime = 0;
            //
            stCommandCheckTime = new Stopwatch();
            stCommandCheckTime.Start();

            stStreamCheckTime = new Stopwatch();
            stStreamCheckTime.Start();

            bHostLoginState = true;
            stLoginTimeOut = new Stopwatch();
            stLoginTimeOut.Start();
        }
    }
    public static class SelectDataTable
    {
        private static Enum MakeCrrent;
        private static Type MakeType;

        static SelectDataTable()
        {
        }

        public static Type GetCurrentType()
        {
            return MakeType;
        }

        public static void MakeDicList(string[] strTableName)
        {
            // Get the current application domain for the current thread
            AppDomain currentDomain = AppDomain.CurrentDomain;

            // Create a dynamic Assembly in the current application domain,
            // and allow it to be executed and saved to disk.
            AssemblyName name = new AssemblyName("SaveListEnums");
            AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(name,
                                                  AssemblyBuilderAccess.RunAndSave);

            // Define a dynamic module in "SaveListEnums" Assembly.
            // For a single-module Assembly, the module has the same name as the Assembly.
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name,
                                              name.Name + ".dll");

            // Define a public enumeration with the name "SaveListEnum" and an underlying type of Integer.
            EnumBuilder xEnum = moduleBuilder.DefineEnum("EnumeratedTypes.SaveListEnum",
                                     TypeAttributes.Public, typeof(int));

            int iSetKey = 1;
            xEnum.DefineLiteral("None", 0);
            foreach (string strName in strTableName)
                xEnum.DefineLiteral(strName, iSetKey++);

            MakeType = xEnum.CreateType();

            // Create the enum
            MakeCrrent = (Enum)Activator.CreateInstance(xEnum.CreateType());

            var sFilePath = Directory.GetCurrentDirectory() + "\\" + "SaveListEnums.dll";

            if (File.Exists(sFilePath))
                File.Delete(sFilePath);

            // Finally, save the Assembly
            assemblyBuilder.Save(name.Name + ".dll");
        }
    }
    public static class COMMON
    {
        public static bool FIX_INFO_MODE = false;

        [DllImport("winmm.dll")]
        public static extern uint timeGetTime();

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool SetLocalTime(ref SYSTEMTIME st);

        public static T ConvertTextToTryValue<T>(string strText, object objFailValue)
        {
            object obj;
            obj = typeof(T);

            int iGetValue = 0;
            uint uiGetValue = 0;
            double dGetValue = 0;

            if (obj.ToString().IndexOf("Int") >= 0)
            {
                if (!int.TryParse(strText, out iGetValue))
                    obj = objFailValue;
                else
                    obj = iGetValue;
            }
            if (obj.ToString().IndexOf("UInt") >= 0)
            {
                if (!uint.TryParse(strText, out uiGetValue))
                    obj = objFailValue;
                else
                    obj = uiGetValue;
            }
            else if (obj.ToString().IndexOf("Double") >= 0)
            {
                if (!double.TryParse(strText, out dGetValue))
                    obj = objFailValue;
                else
                    obj = dGetValue;
            }

            return (T)Convert.ChangeType(obj, typeof(T));
        }

        public static T FindByName<T>(this object targetClass, string name) where T : class
        {
            System.Reflection.FieldInfo fi = targetClass.GetType().GetField(name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            return fi.GetValue(targetClass) as T;
        }
        public static T FindByName<T>(this string name, object targetClass) where T : class
        {
            System.Reflection.FieldInfo fi = targetClass.GetType().GetField(name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            return fi.GetValue(targetClass) as T;
        }
    }
}
