using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Management;
using System.Data.SqlClient;
using System.Data;
using System.Threading.Tasks;
using System.Net.NetworkInformation;
using System.Net;
using System.Runtime.CompilerServices;

namespace Project
{
    public static class Pub
    {
        public static string[] WaitMessage = new string[] { "", "", "", "", "", "", "", "", "", "", "" };

        public static StdLabelPrint.LabelPrint PrinterL = null;
        public static StdLabelPrint.LabelPrint PrinterR = null;

        //공용변수(시간)
        private static DateTime[] Var_dateTime;//총64개의 가변용 변수
        public static void SetVarTime(eVarTime idx, DateTime value)
        {
            Pub.log.Add("VAR_TIME", "Set Time " + idx.ToString() + " : " + value.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            Var_dateTime[(int)idx] = value;
        }
        public static void SetVarTime(eVarTime idx) { SetVarTime(idx, DateTime.Now); }
        public static DateTime GetVarTime(eVarTime idx) { return Var_dateTime[(int)idx]; }
        public static TimeSpan GetVarRunTime(eVarTime idx) { return DateTime.Now - Var_dateTime[(int)idx]; }

        public static arDev.AzinAxt.DIO dio;    //Ajin 
        public static arDev.AzinAxt.MOT mot;    //Ajin
        public static arDev.RS232 remocon;
		public static WatsonWebsocket.WatsonWsClient wsL;
		public static WatsonWebsocket.WatsonWsClient wsR;

		public static int uploadcount = 0;
        public static DateTime BuzzerTime;
        public static DateTime MGZRunTime;

        public static CounterSetting counter;

        public static Flag flag;
        public static MessageWindow popup;

        //interlock check
        public static CInterLock LockPKX;
        public static CInterLock LockPKZ;
        public static CInterLock LockPKT;
        public static CInterLock LockPLM;
        public static CInterLock LockPLZ;
        public static CInterLock LockPRM;
        public static CInterLock LockPRZ;
        public static CInterLock LockPRL;   //printer -left
        public static CInterLock LockPRR;   //printer -right
        public static CInterLock LockVS0;   //visoin - 0
        public static CInterLock LockVS1;   //vision - 1
        public static CInterLock LockVS2;   //vision - 2

        public static arDev.Joystick.JoystickRaw joystick;

        /// <summary>
        /// database manager
        /// </summary>
        //public static Manager.DatabaseManagerHistory dbmHistory; //트레이기록(날짜기준)
        public static Manager.DatabaseManagerCount dbmCount;     //수량기록(ID기준)
        public static Manager.DatabaseManagerSIDHistory dbmSidHistory;

        //public static Manager.DataBaseMSSQL dbSQL;

        /// <summary>
        /// model manager
        /// </summary>
        public static Manager.ModelManager mdm;

        public static SystemSetting system;
        public static UserSetting uSetting;
        public static CSetting setting;

        public static arUtil.Log logVision;
        public static arUtil.Log log;
        public static arUtil.Log logILStop;
        public static arUtil.Log logDbg;
        public static arUtil.Log logFlag;
        public static arUtil.Log logILock;
        public static arUtil.Log logWS;
        public static arUtil.Log logKeyence;
        // public static arUtil.Log logCV;
        public static arUtil.Log logbarcode;

        public static DataSet1.UsersDataTable userList;
        public static DataSet1.MailRecipientDataTable mailList;
        public static DataSet1.MailFormatDataTable mailForm;

        public static DateTime LastInputTime = DateTime.Now;
        public static CResult Result;

        #region "runstep 1"
        private static byte[] _runStepSeq = new byte[64];

        //public static eRunStep getOtherStep(int idx) { return runStep(idx == 0 ? 1 : 0); }
        private static DateTime[] _runStepSeqStartTime = new DateTime[] { DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now };
        private static eRunStep[] _runstepn = new eRunStep[] { eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET };
        private static eRunStep[] _runstepo = new eRunStep[] { eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET };
        public static eRunStep runStep(int idx) { return _runstepo[idx]; }
        public static eRunStep runStepNew(int idx) { return _runstepn[idx]; }
        public static int runStepSeq(int idx)
        {
            return _runStepSeq[idx];
        }
        public static int runStepSeq(eRunSequence idx = eRunSequence.COMMON)
        {
            return _runStepSeq[(int)idx];
        }
        public static void setNewRunStep(int idx, eRunStep newStep)
        {
            if (_runstepn[idx] != newStep)
            {
                _runstepn[idx] = newStep;
            }
        }
        public static void applyRunStep(int idx)
        {
            if (_runstepn[idx] != _runstepo[idx])
            {
                _runStepSeq[idx] = 0;
                _runstepo[idx] = _runstepn[idx];

                //상태머신의 작업 상태가 바뀌면 모든 SEQ번호를 초기화한다  - 201217               
                var StepSeqList = Enum.GetValues(typeof(eRunSequence));
                foreach (var item in StepSeqList)
                    updateRunStepSeq((eRunSequence)item, -1);
            }
        }
        public static void ClearRunStepSeqTime()
        {
            for (int i = 0; i < _runStepSeqStartTime.Length; i++)
                _runStepSeqStartTime[i] = DateTime.Now;
        }

        public static TimeSpan getRunStepSeqtime(int idx)
        {
            return DateTime.Now - _runStepSeqStartTime[idx];
        }
        public static TimeSpan getRunStepSeqtime(eRunSequence idx)
        {
            return getRunStepSeqtime((int)idx);
        }



        public static void SetStepSeq(eRunSequence idx, byte value)
        {
            _runStepSeq[(int)idx] = value;
            Pub.log.AddI(string.Format("Step [{2}] Sequence Jump {0} to {1}",
                _runStepSeq[(int)idx],
                value, idx));
        }
        public static void UpdaterunStepSeqStartTime(eRunSequence idx = eRunSequence.COMMON)
        {
            _runStepSeqStartTime[(int)idx] = DateTime.Now;
            // Pub.log.Add("Update RunStep Start Time");
        }
        public static void updateRunStepSeq(eRunSequence idx = eRunSequence.COMMON, int newseq = -1)
        {
            //seq값을 지정하면 해당 값으로 사용하고 없다면 증가 시킨다.
            if (newseq == -1)
            {
                _runStepSeq[(int)idx] += 1;
            }
            else
            {
                _runStepSeq[(int)idx] = (byte)newseq;
            }

            UpdaterunStepSeqStartTime(idx);
            //   Pub.log.Add(string.Format("스텝({0}) 시퀀스증가 신규값={1}", runStep, _runStepSeq));
        }
        public static void ResetRunStepSeq(eRunSequence idx = eRunSequence.COMMON)
        {
            _runStepSeq[(int)idx] = 1;
            UpdaterunStepSeqStartTime(idx);
        }
        public static void ClearRunStep(int idx)
        {
            _runStepSeq[idx] = 0;
            _runStepSeqStartTime[idx] = DateTime.Now;
            _runstepn[idx] = eRunStep.NOTSET;
            _runstepo[idx] = eRunStep.NOTSET;
        }
        #endregion

        public static StateMachine sm;    //상태머신분리 190529
        public static Boolean isRunning
        {
            get
            {
                return (Pub.sm.Step == StateMachine.eSMStep.RUN);
            }
        }

        public static void AddDebugLog(string div, string msg, Boolean iserr = false)
        {
            if (Pub.setting.Log_Debug == false) return;
            if (iserr) Pub.logDbg.AddE(msg);
            else Pub.logDbg.Add(div, msg);
        }
        public static void AddDebugLog(string msg, Boolean iserr = false)
        {
            Pub.logDbg.Add("NORMAL", msg, iserr);
        }

        public static void ApplyZplCode()
        {
            string zplfil = string.Empty;
            if (Pub.setting.STDLabelFormat7)
            {
                zplfil = System.IO.Path.Combine(Util.CurrentPath, "zpl7.txt");
            }
            else
            {
                zplfil = System.IO.Path.Combine(Util.CurrentPath, "zpl.txt");
            }

            if (System.IO.File.Exists(zplfil))
            {
                Pub.PrinterL.baseZPL = System.IO.File.ReadAllText(zplfil, System.Text.Encoding.Default);
                Pub.PrinterR.baseZPL = System.IO.File.ReadAllText(zplfil, System.Text.Encoding.Default);
            }
            else
            {
                Pub.log.AddAT("기본 ZPL파일이 없어 설정파일의 내용을 사용합니다");
                if(Pub.setting.STDLabelFormat7)
                {
                    Pub.PrinterL.baseZPL = Properties.Settings.Default.ZPL7;
                    Pub.PrinterR.baseZPL = Properties.Settings.Default.ZPL7;
                }
                else
                {
                    Pub.PrinterL.baseZPL = Properties.Settings.Default.ZPL;
                    Pub.PrinterR.baseZPL = Properties.Settings.Default.ZPL;
                }

                //파일이 없으므로 파일을 생성하도록 한다
                Pub.log.Add("기본 zpl 파일을 생성합니다. filename=" + zplfil);
                System.IO.File.WriteAllText(zplfil, Pub.PrinterL.baseZPL, System.Text.Encoding.Default);
            }
        }

        /// <summary>
        /// 전체 작업목록을 별도파일에 저장한다
        /// </summary>
        /// <param name="seqdate"></param>
        /// <param name="seqno"></param>
        /// <param name="file"></param>
        public static void AddJobList(string seqdate, string seqno, string file)
        {
            //저장된 파일은 아래와같은 데이터를 가지고 있다
            //sb.AppendLine("#Time\tSID\tRID\tRAW");

            //해당 차수로 저장된 파일이 잇는지 체크한다. 
            var savepath = System.IO.Path.Combine(Pub.setting.Path_Data, "JobData", seqdate.Substring(0, 6), seqdate + "-" + seqno + ".txt");
            var fi = new System.IO.FileInfo(savepath);
            if (fi.Directory.Exists == false) fi.Directory.Create(); //폴더가 없다면 생성

            //신규파일이므로, 해당 내용을 모두 옴겨놓는다(번호는 중요치않다)
            List<string> savedList = new List<string>();
            if (fi.Exists)
            {
                var oldlist = System.IO.File.ReadAllLines(fi.FullName, System.Text.Encoding.UTF8);
                savedList.AddRange(oldlist);
            }

            //기존목록을 불러와서 없는 데이터만 추가해준다.
            var newbuffer = System.IO.File.ReadAllLines(file, System.Text.Encoding.UTF8);
            foreach (var line in newbuffer)
            {
                if (line.isEmpty() || line.StartsWith("#")) continue;
                var buffer = line.Split('\t');
                var raw = buffer[3].Trim();
                if (savedList.Where(t => t == raw).Count() == 0)
                    savedList.Add(raw);
            }

            //전체목록을 저장한다
            System.IO.File.WriteAllLines(fi.FullName, savedList.ToArray(), System.Text.Encoding.UTF8);
        }

        public static int RemoveCache(string basefile)
        {
            var fi = new System.IO.FileInfo(basefile);
            //해당폴더에서 해당 차수의 파일 및 다른 확장자 모두를 삭제한다.
            var fisearch = fi.Name.Replace(fi.Extension, ".*");
            var delFiles = fi.Directory.GetFiles(fisearch, System.IO.SearchOption.TopDirectoryOnly);
            if (delFiles.Count() < 1) return 0;
            else
            {
                //파일을 삭제한다.
                var cnt = 0;
                try
                {
                    foreach (var delFile in delFiles)
                    {
                        Pub.log.Add("보관파일삭제: " + delFile.FullName);
                        delFile.Delete();
                        cnt += 1;
                    }
                }
                catch (Exception ex)
                {
                    Pub.log.AddE(ex.Message);
                }
                return cnt;
            }
        }
        public static void initDIOSensitive()
        {
            //인식 딜레이를 건다
            Pub.dio.SetInputSensitivity((int)eDIName.PORT0_DET_UP, Pub.setting.PortDetectFall, Pub.setting.PortDetectRise);
            Pub.dio.SetInputSensitivity((int)eDIName.PORT1_DET_UP, Pub.setting.PortDetectFall, Pub.setting.PortDetectRise);
            Pub.dio.SetInputSensitivity((int)eDIName.PORT2_DET_UP, Pub.setting.PortDetectFall, Pub.setting.PortDetectRise);

            Pub.dio.SetInputSensitivity((int)eDIName.BUT_AIRF, Pub.setting.AirChange);

            Pub.dio.SetInputSensitivity((int)eDIName.DOORF1, Pub.setting.SaftyDetectFall, Pub.setting.SaftyDetectRise);
            Pub.dio.SetInputSensitivity((int)eDIName.DOORF2, Pub.setting.SaftyDetectFall, Pub.setting.SaftyDetectRise);
            Pub.dio.SetInputSensitivity((int)eDIName.DOORF3, Pub.setting.SaftyDetectFall, Pub.setting.SaftyDetectRise);
            Pub.dio.SetInputSensitivity((int)eDIName.DOORR1, Pub.setting.SaftyDetectFall, Pub.setting.SaftyDetectRise);
            Pub.dio.SetInputSensitivity((int)eDIName.DOORR2, Pub.setting.SaftyDetectFall, Pub.setting.SaftyDetectRise);
            Pub.dio.SetInputSensitivity((int)eDIName.DOORR3, Pub.setting.SaftyDetectFall, Pub.setting.SaftyDetectRise);

            Pub.log.AddAT("DIO 센서 감도 설정");
        }

        public static void initCore()
        {
            //system parameter
            system = new SystemSetting();
            system.Load();

            //setting
            setting = new CSetting();
            setting.Load();

            //user setting
            uSetting = new UserSetting();
            uSetting.Load();

            //counter setting
            counter = new CounterSetting();
            counter.Load();


            //log
            log = new arUtil.Log();
            logDbg = new arUtil.Log(); logDbg.FileNameFormat = "{yyyyMMdd}_DEBUG";
            logFlag = new arUtil.Log(); logFlag.FileNameFormat = "{yyyyMMdd}_FG";
            logILock = new arUtil.Log(); logILock.FileNameFormat = "{yyyyMMdd}_IL";
            logbarcode = new arUtil.Log(); logbarcode.FileNameFormat = "{yyyyMMdd}_BC";
            logWS = new arUtil.Log(); logWS.FileNameFormat = "{yyyyMMdd}_WS";
            logKeyence = new arUtil.Log(); logKeyence.FileNameFormat = "{yyyyMMdd}_KEY";
            logILStop = new arUtil.Log(); logKeyence.FileNameFormat = "{yyyyMMdd}_ILOCK";
            logVision = new arUtil.Log(); logVision.FileNameFormat = "{yyyyMMdd}_VISION";

            //popupmessage
            popup = new MessageWindow();
            popup.WindowClose += popup_WindowClose;
            popup.WindowOpen += popup_WindowOpen;


            //스텝관련 변수 초기화 - 201228
            var stepLen = 255;
            _runStepSeq = new byte[stepLen];
            _runStepSeqStartTime = new DateTime[stepLen];// { DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now };
            _runstepn = new eRunStep[stepLen];// { eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET };
            _runstepo = new eRunStep[stepLen];// { eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET, eRunStep.NOTSET };
            for (int i = 0; i < stepLen; i++)
            {
                _runStepSeq[i] = 0;
                _runStepSeqStartTime[i] = DateTime.Now;
                _runstepn[i] = eRunStep.NOTSET;
                _runstepo[i] = eRunStep.NOTSET;
            }

            //zpl파일 만든다.
            var fn = System.IO.Path.Combine(Util.CurrentPath, "zpl.txt");
            if (System.IO.File.Exists(fn) == false)
            {
                System.IO.File.WriteAllText(fn, Properties.Settings.Default.ZPL, System.Text.Encoding.Default);
            }

        }



        static void popup_WindowOpen(object sender, EventArgs e)
        {
            var msgdata = sender as MessageWindow.CMessageData;
            Console.WriteLine("window open : " + msgdata.Tag);
        }

        static void popup_WindowClose(object sender, EventArgs e)
        {
            var msgdata = sender as MessageWindow.CMessageData;
            Console.WriteLine("window close : " + msgdata.Tag);
        }
        public static void LogFlush()
        {
            Pub.log.Flush();
            Pub.logbarcode.Flush();
            Pub.logDbg.Flush();
            Pub.logFlag.Flush();
            Pub.logILock.Flush();
            Pub.logKeyence.Flush();
            Pub.logILStop.Flush();
            Pub.logVision.Flush();
        }

        public static void init()
        {
            Result = new CResult();

            //state machine
            sm = new StateMachine();

            //database
            mdm = new Manager.ModelManager(
                Util.CurrentPath + "Model\\modelv.csv",
                Util.CurrentPath + "Model\\modelc.csv");

            //dbSQL = new Manager.DataBaseMSSQL();
            //dbmHistory = new Manager.DatabaseManagerHistory();
            dbmSidHistory = new Manager.DatabaseManagerSIDHistory();

            dbmCount = new Manager.DatabaseManagerCount();
            dbmCount.dataPath = Pub.setting.Path_Data;   //200113

            dio = new arDev.AzinAxt.DIO();
            mot = new arDev.AzinAxt.MOT();

            flag = new Flag();
            LockPKX = new CInterLock("PKX");
            LockPKZ = new CInterLock("PKZ");
            LockPKT = new CInterLock("PKT");
            LockPLM = new CInterLock("PLM");
            LockPLZ = new CInterLock("PLZ");
            LockPRM = new CInterLock("PRM");
            LockPRZ = new CInterLock("PRZ");
            LockPRL = new CInterLock("PRL");
            LockPRR = new CInterLock("PRR");
            LockVS0 = new CInterLock("VS0");
            LockVS1 = new CInterLock("VS1");
            LockVS2 = new CInterLock("VS2");

            //가변 데이트타임변수
            Var_dateTime = new DateTime[64];
            for (int i = 0; i < Var_dateTime.Length; i++)
                Var_dateTime[i] = DateTime.Parse("1982-11-23");

            //language
            Lang.Loading(Pub.setting.Language + ".ini");

            LoadDataTable();

            //allow list
            userList = new DataSet1.UsersDataTable();
            string fn = AppDomain.CurrentDomain.BaseDirectory + "users.xml";
            if (System.IO.File.Exists(fn)) userList.ReadXml(fn);
            else userList.WriteXml(fn, true);

            BuzzerTime = DateTime.Parse("1982-11-23");
            MGZRunTime = DateTime.Parse("1982-11-23");
            LoadSIDList(); //사용자sid목록 가져옴
        }


        public static void CheckNRegister3(string prgmName, string develop, string prgmVersion)
        {
            if (prgmName.Length > 50) prgmName = prgmName.Substring(0, 50); //길이제한
            var task = Task.Factory.StartNew(() =>
            {
                try
                {
                    string ip = "";
                    string mac = "";
                    //      string prgmName = Application.ProductName;

                    var nif = NetworkInterface.GetAllNetworkInterfaces();
                    var host = Dns.GetHostEntry(Dns.GetHostName());
                    string fullname = System.Net.Dns.GetHostEntry("").HostName;
                    foreach (IPAddress r in host.AddressList)
                    {
                        string str = r.ToString();

                        if (str != "" && str.Substring(0, 3) == "10.")
                        {
                            ip = str;
                            break;
                        }
                    }

                    string rtn = string.Empty;
                    ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled='TRUE'");
                    ManagementObjectSearcher query1 = new ManagementObjectSearcher(oq);
                    foreach (ManagementObject mo in query1.Get())
                    {
                        string[] address = (string[])mo["IPAddress"];
                        if (address[0] == ip && mo["MACAddress"] != null)
                        {
                            mac = mo["MACAddress"].ToString();
                            break;
                        }
                    }

                    if (ip == "" || mac == "")
                    {
                        return;
                    }


                    SqlConnection conn = new SqlConnection("Data Source=10.131.15.18;Initial Catalog=EE;Persist Security Info=True;User ID=eeuser;Password=Amkor123!");
                    conn.Open();
                    string ProcName = "AddPrgmUser3";
                    SqlCommand cmd = new SqlCommand(ProcName, conn);
                    cmd.CommandType = CommandType.StoredProcedure;

                    SqlParameter param = cmd.Parameters.Add("@mac", SqlDbType.NVarChar, 50);
                    param.Value = mac;

                    param = cmd.Parameters.Add("@ip", SqlDbType.NVarChar, 50);
                    param.Value = ip;

                    param = cmd.Parameters.Add("@pgrm", SqlDbType.NVarChar, 50);
                    param.Value = prgmName;

                    param = cmd.Parameters.Add("@develop", SqlDbType.NVarChar, 50);
                    param.Value = develop;

                    param = cmd.Parameters.Add("@pgver", SqlDbType.NVarChar, 50);
                    param.Value = prgmVersion;

                    param = cmd.Parameters.Add("@prgmLogin", SqlDbType.VarChar, 20);
                    param.Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                    param = cmd.Parameters.Add("@account", SqlDbType.NVarChar, 50);
                    param.Value = System.Environment.UserName;

                    param = cmd.Parameters.Add("@hostname", SqlDbType.NVarChar, 100);
                    param.Value = fullname;

                    cmd.ExecuteNonQuery();
                    conn.Close();
                }
                catch (Exception ex)
                {
                    Pub.log.AddE(ex.Message);
                }

            });
        }

        /// <summary>
        /// 디버깅정보르를 포함한 시스템 로그를 넣습니다.
        /// </summary>
        /// <param name="prgmVersion"></param>
        /// <param name="Screen"></param>
        /// <param name="Message"></param>
        /// <param name="TraceInfo"></param>
        public static void AddSystemLog(string prgmVersion, string Screen, string Message,
            [CallerFilePath] string filenpath = null,
            [CallerLineNumber] int linenumer = -1,
            [CallerMemberName] string callMember = null)
        {

            var stackFrame = new System.Diagnostics.StackTrace(1).GetFrame(1);
            string fileName = stackFrame.GetFileName();
            if (fileName.isEmpty()) fileName = filenpath;

            string methodName = stackFrame.GetMethod().ToString();
            if (methodName.isEmpty()) methodName = callMember;

            int lineNumber = stackFrame.GetFileLineNumber();
            if (linenumer != -1) lineNumber = linenumer;

            var maxlen = 100;
            if (Screen.Length > maxlen) Screen = Screen.Substring(0, maxlen - 1); //길이제한
            maxlen = 255;
            if (Message.Length > maxlen) Message = Message.Substring(0, maxlen - 1); //길이제한
            maxlen = 3000;

            var TraceInfo = stackFrame.ToString();
            if (TraceInfo.Length > maxlen) TraceInfo = TraceInfo.Substring(0, maxlen - 1); //길이제한


            var task = Task.Factory.StartNew(() =>
            {
                try
                {
                    string HostName = System.Net.Dns.GetHostEntry("").HostName;

                    SqlConnection conn = new SqlConnection("Data Source=10.131.15.18;Initial Catalog=EE;Persist Security Info=True;User ID=eeuser;Password=Amkor123!");
                    conn.Open();
                    string ProcName = "insert into SystemLog_STDLabelAttach(HostName,Version,Screen,Message,TraceInfo,wdate,FileName,LineNumber) values(@p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8)";
                    SqlCommand cmd = new SqlCommand(ProcName, conn);
                    cmd.CommandType = CommandType.Text;
                    var param = cmd.Parameters.Add("@p1", SqlDbType.VarChar, 50);
                    param.Value = HostName;

                    param = cmd.Parameters.Add("@p2", SqlDbType.VarChar, 20);
                    param.Value = prgmVersion;

                    param = cmd.Parameters.Add("@p3", SqlDbType.VarChar, 100);
                    param.Value = Screen;

                    param = cmd.Parameters.Add("@p4", SqlDbType.VarChar, 255);
                    param.Value = Message;

                    param = cmd.Parameters.Add("@p5", SqlDbType.VarChar);
                    param.Value = TraceInfo;

                    param = cmd.Parameters.Add("@p6", SqlDbType.DateTime);
                    param.Value = DateTime.Now;

                    param = cmd.Parameters.Add("@p7", SqlDbType.VarChar, 1000);
                    param.Value = fileName;

                    param = cmd.Parameters.Add("@p8", SqlDbType.Int);
                    param.Value = lineNumber;

                    var cnt = cmd.ExecuteNonQuery();
                    conn.Close();
                }
                catch (Exception ex)
                {
                    Pub.log.AddE(ex.Message);
                }

            });
        }

        public static void LoadDataTable()
        {
            mailForm = new DataSet1.MailFormatDataTable();
            string fn = AppDomain.CurrentDomain.BaseDirectory + "mailForm.xml";
            if (System.IO.File.Exists(fn)) mailForm.ReadXml(fn);
            else
            {
                var nr = mailForm.NewMailFormatRow();
                nr.subject = "";
                nr.content = "";
                mailForm.AddMailFormatRow(nr);
                mailForm.AcceptChanges();
                mailForm.WriteXml(fn, true);
            }
            mailList = new DataSet1.MailRecipientDataTable();
            string fn1 = AppDomain.CurrentDomain.BaseDirectory + "mailList.xml";
            if (System.IO.File.Exists(fn1)) mailList.ReadXml(fn1);
            else mailList.WriteXml(fn, true);
        }
        public static Rectangle GetVisionOrientSearchArea(
           Rectangle baserect,
            int offsetX,
            int offsetY,
            out string VisionOrientMessage)
        {
            VisionOrientMessage = "";
            var newORectW = baserect.Width + offsetX;
            var newORectH = baserect.Height + offsetY;

            var newORectX = baserect.X - ((newORectW - baserect.Width) / 2.0);
            var newORectY = baserect.Y - ((newORectH - baserect.Height) / 2.0);
            if (newORectX < 1)
            {
                newORectW += (int)newORectY;
                newORectX = 1;
            }
            if (newORectY < 1)
            {
                newORectH += (int)newORectY;
                newORectY = 1;
            }
            if (newORectW < 4) newORectW = 0;
            if (newORectH < 4) newORectH = 0;
            var newORect = new Rectangle((int)newORectX, (int)newORectY, (int)newORectW, (int)newORectH);
            if (newORect.Width < 1 || newORect.Height < 1)
            {
                VisionOrientMessage = string.Format("기준영역 크기 오류({0},{1},{2},{3})", newORect.Left, newORect.Top, newORect.Width, newORect.Height);
                return Rectangle.Empty;
            }
            else return newORect;
        }

        public static void GetJobColor(Class.JobData.ErrorCode result, Color baseBack, out Color fColor, out Color bColor)
        {
            if (result == Class.JobData.ErrorCode.BarcodeRead)
            {
                //배출됫엇다면 색상을 변경한다.
                fColor = Color.Tomato;
                bColor = baseBack;
            }
            else
            {
                fColor = Color.WhiteSmoke;
                bColor = baseBack;
            }
        }

        public static DataSet1.UserSIDDataTable DTUserSID;
        public static void LoadSIDList()
        {
            if (DTUserSID == null) DTUserSID = new DataSet1.UserSIDDataTable();
            else DTUserSID.Clear();
            var fi = new System.IO.FileInfo(Util.CurrentPath + "Data\\UserSID.csv");


            if (fi.Exists == true)
            {
                string[] lines = null;
                try
                {
                    lines = System.IO.File.ReadAllLines(fi.FullName, System.Text.Encoding.UTF8);
                }
                catch (Exception ex)
                {
                    Util.MsgE(ex.Message, true);
                    lines = new string[] { };
                }
                foreach (var line in lines)
                {
                    if (line.isEmpty()) continue;
                    if (line.StartsWith("#")) continue; //주석문
                    var buffer = line.Split(',');
                    if (buffer.Length < 2) continue;
                    var port = buffer[0];
                    var sid = buffer[1];
                    if (sid.isEmpty()) continue;
                    if (port == "0") port = "11";
                    if (port == "1") port = "12";
                    if (port == "2") port = "21";
                    if (port == "3") port = "22";
                    if (port == "4") port = "31";
                    if (port == "5") port = "32";
                    if (port == "6") port = "41";
                    if (port == "7") port = "42";

                    //중복체크
                    var Exist = DTUserSID.Where(t => t.SID == sid && t.Port == port).Count() > 0;
                    if (Exist == false)
                    {
                        var newdr = DTUserSID.NewUserSIDRow();
                        newdr.Port = port;
                        newdr.SID = sid;
                        DTUserSID.AddUserSIDRow(newdr);
                    }
                }
            }
            else if (fi.Directory.Exists == false) fi.Directory.Create();

            DTUserSID.AcceptChanges();
            Pub.log.Add("사용자 SID 목록 : " + DTUserSID.Count.ToString() + " 건 불러옴");
        }
        public static void SaveSIDList()
        {
            if (DTUserSID == null) return;
            var fi = new System.IO.FileInfo(Util.CurrentPath + "Data\\UserSID.csv");
            if (fi.Directory.Exists == false) fi.Directory.Create();

            if (DTUserSID.Count < 1) fi.Delete();
            else
            {
                //자료를 저장한다.
                var sb = new System.Text.StringBuilder();
                sb.AppendLine("#PORT,SID");
                var orderlist = from m in DTUserSID
                                orderby m.Port
                                orderby m.SID
                                select m;

                var cnt = 0;
                foreach (DataSet1.UserSIDRow dr in orderlist)
                {
                    if (dr.SID.isEmpty() || dr.Port.isEmpty()) continue;
                    sb.AppendLine(string.Format("{0},{1}", dr.Port, dr.SID));
                    cnt += 1;
                }
                System.IO.File.WriteAllText(fi.FullName, sb.ToString(), System.Text.Encoding.UTF8);
                Pub.log.Add(string.Format("{0}건의 사용자 sid가 저장되었습니다", cnt));
            }
        }

        public static double GetFreeSpace(string driveletter)
        {
            try
            {
                var di = new System.IO.DriveInfo(driveletter);
                var freespace = di.TotalFreeSpace;
                var totalspace = di.TotalSize;
                var freeSpaceRate = (freespace * 1.0 / totalspace) * 100.0;
                return freeSpaceRate;
            }
            catch
            {
                return 100.0;
            }
        }

        public static string getSavePath(out double freespace)
        {
            Boolean path1Exist = false;
            double freespace1 = 100.0;
            string savePath1 = "";

            freespace = 100.0;

            savePath1 = System.IO.Path.Combine(Pub.setting.Path_Data, "Images");
            if (savePath1 != "" && System.IO.Directory.Exists(savePath1))
            {
                path1Exist = true;
                //이폴더를 사용
                if (savePath1.StartsWith("\\")) return savePath1;
                //남은잔량을 체크한다.
                freespace1 = GetFreeSpace(savePath1.Substring(0, 1));
                if (freespace1 >= Pub.setting.AutoDeleteThreshold) return savePath1;
            }

            if (path1Exist)
            {
                freespace = freespace1;
                return savePath1;
            }

            //이제 문제가 좀 심각? (폴더가 없다)
            var savePath = System.IO.Path.Combine(Util.CurrentPath, "Images");
            if (System.IO.Directory.Exists(savePath) == false)
                System.IO.Directory.CreateDirectory(savePath);

            freespace = GetFreeSpace(savePath.Substring(0, 1));
            return savePath;
        }
        public static double ChangeValuePopup(double value, string title)
        {
            Dialog.fInput f = new Dialog.fInput(value.ToString(), title);
            if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                var val = double.Parse(f.tbInput.Text);
                return val;
            }
            else return value;

        }

        public static UInt16[] SIDtoUInt16(string sid)
        {
            var sidstr = sid.PadLeft(10, '0'); //총 10자리로 만들어놓는다
            var getbytes = System.Text.Encoding.Default.GetBytes(sidstr);

            var c1 = getbytes[1].ToString("X2") + getbytes[0].ToString("x2");
            var c2 = getbytes[3].ToString("X2") + getbytes[2].ToString("x2");
            var c3 = getbytes[5].ToString("X2") + getbytes[4].ToString("x2");
            var c4 = getbytes[7].ToString("X2") + getbytes[6].ToString("x2");
            var c5 = getbytes[9].ToString("X2") + getbytes[8].ToString("x2");

            var Buffer = new UInt16[5];
            var index = 0;
            Buffer[index++] = Convert.ToUInt16(c1, 16);
            Buffer[index++] = Convert.ToUInt16(c2, 16);
            Buffer[index++] = Convert.ToUInt16(c3, 16);
            Buffer[index++] = Convert.ToUInt16(c4, 16);
            Buffer[index++] = Convert.ToUInt16(c5, 16);
            return Buffer;
        }

        public static void ChangeUIPopup(System.Windows.Forms.NumericUpDown valueCtl)
        {
            var value = valueCtl.Value.ToString();
            Dialog.fInput f = new Dialog.fInput(value);
            if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                var val = decimal.Parse(f.tbInput.Text);
                if (val < valueCtl.Minimum)
                {
                    Util.MsgE(string.Format("최소 입력값은 {0} 입니다.", valueCtl.Minimum));
                    val = valueCtl.Minimum;
                }
                if (val > valueCtl.Maximum)
                {
                    Util.MsgE(string.Format("최대 입력값은 {0} 입니다.", valueCtl.Maximum));
                    val = valueCtl.Maximum;
                }
                valueCtl.Value = val;
            }

        }

    }
}
