using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using SystemX.Net.Platform.Common.ExtensionMethods;

using static SystemX.Product.CP.TRA.Commons;

namespace SystemX.Product.CP.TRA
{
    public class AccessLevelAlarm : EventArgs
    {
        public AccessLevelAlarm(LoginAccessLevel CurrentAccessLevel, bool bLoginState)
        {
            this.CurrentLevel = CurrentAccessLevel;

            this.GetLoginState = bLoginState;
        }

        public LoginAccessLevel CurrentLevel { get; private set; }

        public bool GetLoginState { get; private set; }
    }

    public static class Commons
    {
        static public bool DEBUG_MODE = false;

        [Flags]
        public enum LoginAccessLevel
        {
            None = 0x01,
            Basic = 0x02,
            Admin = 0x04
        }

        public enum eSelectDataView
        {
            DataDocumentViewC1 = 0,
            DataDocumentViewC2
        }

        public enum eOverviewModelNameInfo
        {
            L = 0,
            P1,
            P2
        }

        public static bool isHasRow(DataSet ds)
        {
            return (ds != null) ? ds.Tables.Cast<DataTable>().Any(table => table.Rows.Count != 0) : false;
        }

        public static bool isHasRow(DataTable dt)
        {
            return (dt != null) ? dt.Rows.Count > 0 : false;
        }

        public static bool IsValidEmail(string email)
        {
            bool valid = Regex.IsMatch(email, @"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?");
            
            return valid;
        }

        public static bool CheckGateLetter(char letter)
        {
            Regex engRegex = new Regex(@"[A-Z]");

            return engRegex.IsMatch(letter.ToString());
        }

        public static byte[] ConvertHexStringToByte(string convertString)
        {
            byte[] convertArr = new byte[convertString.Length / 2];

            for (int i = 0; i < convertArr.Length; i++)
            {
                convertArr[i] = Convert.ToByte(convertString.Substring(i * 2, 2), 16);
            }

            return convertArr;
        }

        [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern int memcmp(byte[] b1, byte[] b2, long count);

        public static bool ByteArrayCompare(byte[] b1, byte[] b2)
        {
            if (b1 == null || b2 == null)
                return false;

            // Validate buffers are the same length.
            // This also ensures that the count does not exceed the length of either buffer. 
            return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;
        }

        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 class INICtrl
        {
            public static int MAX_INFORMATION = 10;

            protected static int FILE_ATTRIBUTE_HIDDEN = 2;

            [DllImport("kernel32")]
            protected static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
            [DllImport("kernel32")]
            protected static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
            [DllImport("kernel32")]
            protected static extern int SetFileAttributes(string lpFileName, int dwFileAttributes);

            public virtual void SetValue(string Section, string Key, string Value, string path = "")
            {
                WritePrivateProfileString(Section, Key, Value, path);
            }

            public virtual string GetValue(string Section, string Key, string Default, string path = "")
            {
                StringBuilder temp = new StringBuilder(255);
                int i = GetPrivateProfileString(Section, Key, Default, temp, 255, path);
                if (temp != null && temp.Length > 0) return temp.ToString();
                else return Default;
            }
        }

        public class ConnectInfoINICtrl : INICtrl
        {
            private static string ConnectHistoryINIPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\ConnectConfig_TRA_CPXV2.ini";

            public ConnectInfoINICtrl()
            {
                if (File.Exists(ConnectHistoryINIPath) == false)
                {
                    using (File.Create(ConnectHistoryINIPath)) { }

                    SetFileAttributes(ConnectHistoryINIPath, FILE_ATTRIBUTE_HIDDEN);

                    SetValue("LastestConnect", "Info", "");
                }
            }

            public string GetUserTheme()
            {
                return GetValue("UserSelectTheme", "ThemeName", "Basic");
            }

            public void SetUserTheme(string strThemeName)
            {
                SetValue("UserSelectTheme", "ThemeName", strThemeName);
            }

            public void SetLastestConnectInfo(string strSuccessInfo1, string strSuccessInfo2, string strSuccessInfo3, 
                bool bCheckedInfo, int nOverInfoC1, int nOverInfoC2)
            {
                string strSetUpperText = strSuccessInfo1.ToUpper();

                string[] strInfoSet = null;

                int? findIdx = null;

                if (strSuccessInfo1.CompareTo("") == 0 ||
                   strSuccessInfo1.CompareTo("127.0.0.1") == 0 ||
                   strSetUpperText.CompareTo("LOCALHOST") == 0 ||
                   strSuccessInfo1.IndexOf("If you do not enter the ip, will be connected to the local area.") >= 0)
                {
                    ;//
                }
                else
                {
                    SetValue("LastestConnect", "Info1", strSuccessInfo1);

                    strInfoSet = new string[MAX_INFORMATION];

                    for (int i = 0; i < MAX_INFORMATION; i++)
                        strInfoSet[i] = GetValue("HistoryConnect" + i.ToString(), "Info1", "");

                    findIdx = strInfoSet.FindIndex(x => x == strSuccessInfo1);

                    if (findIdx == null)
                    {
                        for (int i = MAX_INFORMATION - 1; i > 0; i--)
                        {
                            if (i > 0)
                                strInfoSet[i] = strInfoSet[i - 1];
                        }

                        strInfoSet[0] = strSuccessInfo1;

                        for (int i = 0; i < MAX_INFORMATION; i++)
                            SetValue("HistoryConnect" + i.ToString(), "Info1", strInfoSet[i]);
                    }
                }
                //
                strSetUpperText = strSuccessInfo2.ToUpper();

                if (strSuccessInfo2.CompareTo("") == 0 ||
                   strSuccessInfo2.CompareTo("127.0.0.1") == 0 ||
                   strSetUpperText.CompareTo("LOCALHOST") == 0 ||
                   strSuccessInfo2.IndexOf("If you do not enter the ip, will be connected to the local area.") >= 0)
                {
                    ;//
                }
                else
                {
                    SetValue("LastestConnect", "Info2", strSuccessInfo2);

                    strInfoSet = new string[MAX_INFORMATION];

                    for (int i = 0; i < MAX_INFORMATION; i++)
                        strInfoSet[i] = GetValue("HistoryConnect" + i.ToString(), "Info2", "");

                    findIdx = strInfoSet.FindIndex(x => x == strSuccessInfo2);

                    if (findIdx == null)
                    {
                        for (int i = MAX_INFORMATION - 1; i > 0; i--)
                        {
                            if (i > 0)
                                strInfoSet[i] = strInfoSet[i - 1];
                        }

                        strInfoSet[0] = strSuccessInfo2;

                        for (int i = 0; i < MAX_INFORMATION; i++)
                            SetValue("HistoryConnect" + i.ToString(), "Info2", strInfoSet[i]);
                    }
                }
                //
                if (bCheckedInfo)
                    SetValue("LastestConnect", "UseDataServer2", "True");
                else
                    SetValue("LastestConnect", "UseDataServer2", "False");
                //
                SetValue("LastestConnect", "OverviewModelInfoC1", nOverInfoC1.ToString());
                SetValue("LastestConnect", "OverviewModelInfoC2", nOverInfoC2.ToString());
                //
                if (bCheckedInfo == false)
                {
                    ;//
                }
                else
                { 
                    strSetUpperText = strSuccessInfo3.ToUpper();

                    if (strSuccessInfo3.CompareTo("") == 0 ||
                       strSuccessInfo3.CompareTo("127.0.0.1") == 0 ||
                       strSetUpperText.CompareTo("LOCALHOST") == 0 ||
                       strSuccessInfo3.IndexOf("If you do not enter the ip, will be connected to the local area.") >= 0)
                    {
                        ;//
                    }
                    else
                    {
                        SetValue("LastestConnect", "Info3", strSuccessInfo3);

                        strInfoSet = new string[MAX_INFORMATION];

                        for (int i = 0; i < MAX_INFORMATION; i++)
                            strInfoSet[i] = GetValue("HistoryConnect" + i.ToString(), "Info3", "");

                        findIdx = strInfoSet.FindIndex(x => x == strSuccessInfo3);

                        if (findIdx == null)
                        {
                            for (int i = MAX_INFORMATION - 1; i > 0; i--)
                            {
                                if (i > 0)
                                    strInfoSet[i] = strInfoSet[i - 1];
                            }

                            strInfoSet[0] = strSuccessInfo3;

                            for (int i = 0; i < MAX_INFORMATION; i++)
                                SetValue("HistoryConnect" + i.ToString(), "Info3", strInfoSet[i]);
                        }
                    }
                }
            }

            public override void SetValue(string Section, string Key, string Value, string path = "")
            {
                if (path.Length <= 0)
                    path = ConnectHistoryINIPath;

                WritePrivateProfileString(Section, Key, Value, path);
            }

            public override string GetValue(string Section, string Key, string Default, string path = "")
            {
                if (path.Length <= 0)
                    path = ConnectHistoryINIPath;

                StringBuilder temp = new StringBuilder(255);
                int i = GetPrivateProfileString(Section, Key, Default, temp, 255, path);
                if (temp != null && temp.Length > 0) return temp.ToString();
                else return Default;
            }
        }
    }
}
