using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading; 

namespace NewPosInstaller
{
    public class ComLib
    {
        /// <summary>
        /// OK(정상)
        /// </summary>
        public const string RST_OK = "RSTOK|";
        /// <summary>
        /// ERROR(에러)
        /// </summary>
        public const string RST_ERR = "ERROR|";
        /// <summary>
        /// IGNORE(무시)
        /// </summary>
        public const string RST_IGNORE = "IGNOR|";
        /// <summary>
        /// RETRY(재시도)
        /// </summary>
        public const string RST_RETRY = "RETRY|";

        /// <summary>
        /// Normal
        /// <para>(정상:1)</para>
        /// </summary>
        public const int OK = 1;
        /// <summary>
        /// Error0-Detail
        /// <para>(에러0-상세)</para>
        /// </summary>
        public const int NG = 0;
        /// <summary>
        /// Error1-Detail
        /// <para>(에러1-상세)</para>
        /// </summary>
        public const int NG1 = -1;
        /// <summary>
        /// Error2-Detail
        /// <para>(에러2-상세)</para>
        /// </summary>
        public const int NG2 = -2;
        /// <summary>
        /// Error3-Detail
        /// <para>(에러3-상세)</para>
        /// </summary>
        public const int NG3 = -3;
        /// <summary>
        /// Error4-Detail
        /// <para>(에러4-상세)</para>
        /// </summary>
        public const int NG4 = -4;

        /// <summary>
        /// 각종 Debug 로그 FrameworkYYMMDD.log 파일에 기록
        /// </summary>
        public const string LOG_DEBUG = "Debug";
        /// <summary>
        /// Logging Phase "ERROR"
        /// </summary>
        public const string LOG_ERROR = "Error";
        /// <summary>
        /// Socket 로그 구분
        /// </summary>
        public const string LOG_SOCK = "Socket";
        /// <summary>
        /// Operation Flow 로그 구분
        /// </summary>
        public const string LOG_OP = "OpFlow";
        /// <summary>
        /// IO 관련 로그 구분
        /// </summary>
        public const string LOG_IOS = "IOS";

        /// <summary>
        /// LOG LEVEL
        /// </summary>
        public const int ERROR_LEVEL = 1;
        public const int WARNING_LEVEL = 2;
        public const int INFO_LEVEL = 3;

        /// <summary>
        /// 로그파일 최대 사이즈. 1MB 단위로 분할
        /// </summary>
        public const int LOG_MAX_SIZE = 1000000;

        ///// <summary>
        ///// Logging Phase "FATAL"
        ///// <para>(로깅 단계 "FATAL")</para>
        ///// </summary>
        //public const    string  LOG_ERROR       = "Fatal";
        ///// <summary>
        ///// 로깅 단계 "WARNNING"
        ///// <para>(Logging Phase "WARNNING")</para>
        ///// </summary>
        //public const    string  LOG_WARN        = "Warn";

        ///// <summary>
        ///// Logging Phase "INFORMATION"
        ///// <para>(로깅 단계 "INFORMATION")</para>
        ///// </summary>
        //public const    string  LOG_INFO        = "Info";
        /// <summary>
        /// Normal
        /// <para>(정상)</para>
        /// </summary>
        public const string NORMAL = "Success";
        /// <summary>
        /// Error
        /// <para>(에러)</para>
        /// </summary>
        public const string ERROR = "Error";


        /// <summary>
        /// HKEY_CURRENT_USERS Route of Registry
        /// <para>(레지스트리의 HKEY_CURRENT_USERS 루트)</para>
        /// </summary>
        public const string HKCU = "HKEY_CURRENT_USERS\\";

        /// <summary>
        /// HKEY_LOCAL_MACHINE Route of Registry
        /// <para>(레지스트리의 HKEY_LOCAL_MACHINE 루트)</para>
        /// </summary>
        public const string HKLM = "HKEY_LOCAL_MACHINE\\";

        //public int     COMM_MSGLEN_START   = 2;                    // 메시지 길이 시작 위치
        //public int     COMM_MSGLEN         = 5;                    // 메시지 길이
        //public int     COMM_HEAD_LEN       = 42;                   // 6 --> 5


        /// <summary>
        /// 디렉토리 생성
        /// </summary>
        /// <param name="sPath"></param>
        /// <returns></returns>
        public static void CreateDirectory(string sPath)
        {
            try
            {
                if (Directory.Exists(sPath) == false) Directory.CreateDirectory(sPath);
            }
            catch { }
        }

        /// <summary>
        /// 파일복사 처리
        /// </summary>
        /// <param name="sSrcFileName"></param>
        /// <param name="sDstFileName"></param>
        /// <param name="bSrcDelete"></param>
        /// <returns></returns>
        public static bool FileCopy(string sSrcFileName, string sDstFileName, bool bSrcDelete = false)
        {
            try
            {
                if (File.Exists(sSrcFileName) == false) return false;

                // 파일복사 처리
                File.Copy(sSrcFileName, sDstFileName, true);

                if (bSrcDelete == true)
                {
                    //File.Delete(sSrcFileName);
                    for (var i = 0; i < 5; i++)
                    {
                        FileDelete(sSrcFileName);
                        if (File.Exists(sSrcFileName) == false) break;
                        Thread.Sleep(30);
                    }
                }

                return true;    // File.Exists(sDstFileName);
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , ex.Message);
            }
            return false;
        }

        /// <summary>
        /// 파일복사 처리
        /// </summary>
        /// <param name="sFileName">파일명</param>
        /// <param name="sSrcPath"></param>
        /// <param name="sDstPath"></param>
        /// <param name="sBackPath"></param>
        /// <returns></returns>
        public static bool FileCopy(string sFileName, string sSrcPath, string sDstPath, string sBackPath)
        {
            try
            {
                if (File.Exists(sSrcPath + sFileName) == false) return false;

                // 원 파일 백업
                if (sBackPath.Length > 0)
                {
                    CreateDirectory(sBackPath);
                    FileMove(sDstPath + sFileName, sBackPath + sFileName);          // 백업 처리
                }

                CreateDirectory(sDstPath);                                          // 대상폴더 생성
                File.Copy(sSrcPath + sFileName, sDstPath + sFileName, true);        // 파일복사 처리

                return true;
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , ex.Message);
            }
            return false;
        }

        /// <summary>
        /// 디렉토리의 모든 파일복사 처리
        /// </summary>
        /// <param name="sSrcPath"></param>
        /// <param name="sDstPath"></param>
        /// <param name="sBackPath"></param>
        /// <returns></returns>
        public static bool DirectoryCopy(string sSrcPath, string sDstPath, string sBackPath = "")
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(sSrcPath);
                if (di.Exists)
                {
                    foreach (FileInfo fi in di.GetFiles())
                    {
                        FileCopy(fi.Name, sSrcPath, sDstPath, sBackPath);
                    }

                    foreach (DirectoryInfo fi in di.GetDirectories())
                    {
                        string sBckSubPath = string.IsNullOrEmpty(sBackPath) ? string.Empty : sBackPath + fi.Name + @"\";
                        CreateDirectory(sDstPath + fi.Name);
                        DirectoryCopy(sSrcPath + fi.Name + @"\", sDstPath + fi.Name + @"\", sBckSubPath);
                        //DirectoryCopy(sSrcPath + fi.Name + @"\", sDstPath + fi.Name + @"\", sBackPath + fi.Name + @"\");
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , ex.Message);
            }

            return false;
        }

        public static bool DirectoryMove(string sourcePath, string destPath)
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(sourcePath);

                foreach (FileInfo fi in di.GetFiles())
                {
                    fi.MoveTo(Path.Combine(destPath, fi.Name));
                }
                foreach (DirectoryInfo fi in di.GetDirectories())
                {
                    fi.MoveTo(Path.Combine(destPath, fi.Name));
                }
                return true;
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 파일 삭제
        /// </summary>
        /// <param name="sFileFullName"></param>
        /// <returns></returns>
        public static bool FileDelete(string sFileFullName, bool isReadonly = false)
        {
            try
            {
                if (File.Exists(sFileFullName) == false) return false;

                if (isReadonly)
                {
                    FileInfo f = new FileInfo(sFileFullName);
                    f.IsReadOnly = false; 
                }

                File.Delete(sFileFullName);

                return true;
            }
            catch (UnauthorizedAccessException ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , ex.Message);
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , ex.Message);
            }

            return false;
        }

        /// <summary>
        /// 파일이동 처리
        /// </summary>
        /// <param name="sFileName">파일명</param>
        /// <param name="sSrcPath"></param>
        /// <param name="sDstPath"></param>
        /// <param name="sBackPath"></param>
        /// <returns></returns>
        public static bool FileMove(string sFileName, string sSrcPath, string sDstPath, string sBackPath)
        {
            try
            {
                if (File.Exists(sSrcPath + sFileName) == false) return false;

                // 원 파일 백업
                if (sBackPath.Length > 0)
                {
                    CreateDirectory(sBackPath);                                     // 백업폴더 생성
                    FileMove(sDstPath + sFileName, sBackPath + sFileName);          // 백업 처리
                }

                CreateDirectory(sDstPath);                                          // 폴더 생성
                FileMove(sSrcPath + sFileName, sDstPath + sFileName);               // 파일이동 처리

                return true;
            }
            catch { }

            return false;
        }
        public static void FileMove(string sSrcPath, string sDstPath)
        {
            for (int i = 0; i < 3; i++)
            {
                // 기존파일 삭제
                try
                {
                    File.Delete(sDstPath);
                }
                catch { }

                // 파일이동 처리
                try
                {
                    File.Move(sSrcPath, sDstPath);
                    break;
                }
                catch
                {
                    System.Threading.Thread.Sleep(100);
                }
            }
        }

        /// <summary>
        /// 디렉토리의 모든 파일이동 처리
        /// </summary>
        /// <param name="sSrcPath"></param>
        /// <param name="sDstPath"></param>
        /// <param name="sBackPath"></param>
        /// <returns></returns>
        public static bool DirectoryMove(string sSrcPath, string sDstPath, string sBackPath)
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(sSrcPath);
                if (di.Exists)
                {
                    foreach (FileInfo fi in di.GetFiles())
                    {
                        FileMove(fi.Name, sSrcPath, sDstPath, sBackPath);
                    }

                    foreach (DirectoryInfo fi in di.GetDirectories())
                    {
                        string sBckSubPath = string.IsNullOrEmpty(sBackPath) ? string.Empty : sBackPath + fi.Name + @"\";
                        DirectoryMove(sSrcPath + fi.Name + @"\", sDstPath + fi.Name + @"\", sBckSubPath);
                        //DirectoryMove(sSrcPath + fi.Name + @"\", sDstPath + fi.Name + @"\", sBackPath + fi.Name + @"\");
                    }
                }

                return true;
            }
            catch { }

            return false;
        }

        /// <summary>
        /// 디렉토리의 모든파일 삭제
        /// </summary>
        /// <param name="sSrcPath"></param>
        /// <param name="dtDelDate">삭제기준날짜</param>
        /// <param name="nDelSubDir">0:하위폴더삭제안함, 1:하위폴더삭제, 2:하위폴더삭제후폴더삭제 </param>
        /// <returns></returns>
        public static bool DeleteDirectoryInFile(string sSrcPath, DateTime dtDelDate, int nDelSubDir)
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(sSrcPath);
                if (di.Exists)
                {
                    if (nDelSubDir != 0)        // 하위폴더 삭제 여부
                    {
                        foreach (DirectoryInfo fi in di.GetDirectories())
                        {
                            DeleteDirectoryInFile(sSrcPath + fi.Name + @"\", dtDelDate, nDelSubDir);
                            try
                            {
                                if (nDelSubDir == 2) fi.Delete();
                            }
                            catch { }
                        }
                    }

                    foreach (FileInfo fi in di.GetFiles())
                    {
                        if (dtDelDate == null || fi.LastAccessTime < dtDelDate)
                        {
                            try
                            {
                                fi.Delete();
                            }
                            catch { }
                        }
                    }
                }

                return true;
            }
            catch { }

            return false;
        }

        /// <summary>
        /// 디렉토리의 모든파일 삭제
        /// </summary>
        /// <param name="sSrcPath"></param>
        /// <param name="nDelSubDir">0:하위폴더삭제안함, 1:하위폴더삭제, 2:하위폴더삭제후폴더삭제 </param>
        public static bool DeleteDirectoryInFile(string sSrcPath, int nDelSubDir)
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(sSrcPath);
                if (di.Exists)
                {
                    if (nDelSubDir != 0)        // 하위폴더 삭제 여부
                    {
                        foreach (DirectoryInfo fi in di.GetDirectories())
                        {
                            DeleteDirectoryInFile(sSrcPath + fi.Name + @"\", nDelSubDir);
                            try
                            {
                                if (nDelSubDir == 2) fi.Delete();
                            }
                            catch { }
                        }
                    }

                    foreach (FileInfo fi in di.GetFiles())
                    {
                        try
                        {
                            fi.Delete();
                        }
                        catch { }
                    }
                }

                return true;
            }
            catch { }

            return false;
        }

        public static bool ExistDirectory(string path)
        {
            return Directory.Exists(path);
        }

        public static int IntParse(string value)
        {
            try
            {
                return int.Parse(value);
            }
            catch{}
            return 0;
        }

        public static double DoubleParse(string sValue)
        {
            try
            {
                if (sValue.Trim().Length > 0)
                {
                    return double.Parse(sValue.Trim().Replace(",", ""));
                }
            }
            catch { }
            return 0;
        }

        public static long LongParse(string sValue)
        {
            try
            {
                if (sValue.Trim().Length > 0)
                {
                    return (long)DoubleParse(sValue);
                }
            }
            catch{}
            return 0;
        }

        /// <summary>
        /// 숫자인지 체크
        /// </summary>
        /// <param name="strValue"></param>
        /// <returns></returns>
        public static bool IsNumber(string strValue)
        {
            return IsNumber(strValue, false);
        }

        public static bool IsNumber(string sValue, bool bDotFlag)
        {
            int nDotCnt = 0;

            try
            {
                if (sValue == "") return false;

                if (sValue.Substring(0, 1) == "-")
                {
                    sValue = sValue.Substring(1, sValue.Length - 1);
                }

                for (int i = 0; i < sValue.Length; i++)
                {
                    if (sValue.Substring(i, 1).CompareTo("0") < 0 || sValue.Substring(i, 1).CompareTo("9") > 0)
                    {
                        if (bDotFlag == true && sValue.Substring(i, 1).CompareTo(".") == 0)
                        {
                            nDotCnt++;
                            if (nDotCnt > 1) return false;
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
            }
            catch
            {
                return false;
            }

            return true;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Return Trim processed (except 0) IP address
        /// <para>(Trim 처리(0을 제외)한 IP주소를 반환한다.)</para>
        /// </summary>
        /// <param name="pStringIp">IP Address to be edited</param>
        ///                   <para>(편집할 IP주소)</para>
        /// <returns>Processed Result Value</returns>
        ///    <para>(처리결과값)</para>
        /* --------------------------------------------------------------------------------- */
        public static string TrimNetworkIpAddress(string pStringIp)
        {
            // Ip에서 왼쪽 0을 삭제하고, 000은 0으로 변환합니다.
            //**************************************************************************************
            if (pStringIp == null || pStringIp == "") return "0.0.0.0";


            string strReturn = "";
            string[] strSplitDot = pStringIp.Split('.');
            for (int i = 0; i < strSplitDot.Length; i++)
            {
                strReturn += strSplitDot[i].TrimStart('0').PadLeft(1, '0') + ".";
            }
            return strReturn.Substring(0, strReturn.Length - 1);
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Return IP address filled with 0s.
        /// <para>(0을 채운 IP주소를 반환한다.)</para>
        /// </summary>
        /// <param name="pStringIp">IP Address to be edited</param>
        ///                   <para>(편집할 IP주소)</para>
        /// <returns>Processed Result Value</returns>
        ///    <para>(처리결과값)</para>
        /* --------------------------------------------------------------------------------- */
        public static string FillNetworkIpAddress(string pStringIp)
        {
            // Ip의 각부분에 3자리의 정수를 만들어 리턴합니다.
            //**************************************************************************************
            if (pStringIp == null || pStringIp == "") return "0.0.0.0";

            string strReturn = "";
            string[] strSplitDot = pStringIp.Split('.');
            for (int i = 0; i < strSplitDot.Length; i++)
            {
                strReturn += strSplitDot[i].PadLeft(3, '0') + ".";
            }
            return strReturn.Substring(0, strReturn.Length - 1);
        }

        #region ##### UsUtil - String Edit Utility #####
        /* ----------------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// <para>(한글(2byte)을 포함한 문자열의 길이 반환)</para>
        /// </summary>
        /// <param name="sStr">대상 문자열</param>
        /// <returns>길이</returns>
        /* ----------------------------------------------------------------------------------------- */
        public static int LenH(string sStr)
        {
            return System.Text.Encoding.Default.GetByteCount(sStr);
        }

        /* ----------------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// <para>(한글(2byte)을 포함한 문자열을 원하는 길이의 문자열로 생성 후 좌측정렬)</para>
        /// </summary>
        /// <param name="sStr">원본 문자열</param>
        /// <param name="nLen">문자열 길이</param>
        /// <returns>반환 문자열</returns>
        /* ----------------------------------------------------------------------------------------- */
        public static string LPadH(string sStr, int nLen)
        {
            if (sStr == null) return "";

            byte[] bt1 = System.Text.Encoding.Default.GetBytes(sStr);

            int nL = bt1.Length;
            //if (nL == 0) return ""; //->스트링이 empty여도 Pad해주기 위해 주석처리 20100902

            if (nL > nLen)
            {
                return MidH(sStr, 0, nLen, 1);
                //return System.Text.Encoding.Default.GetString(bt1, 0, nLen);
            }
            else
            {
                return "".PadLeft(nLen - nL) + sStr;
            }

        }
        /* ----------------------------------------------------------------------------------------- */
        /// <summary>
        /// <para>(한글(2byte)을 포함한 문자열을 원하는 길이의 문자열로 생성 후 우측정렬)</para>
        /// </summary>
        /// <param name="sStr">원본 문자열</param>
        /// <param name="nLen"></param>
        /// <returns>반환 문자열</returns>
        /* ----------------------------------------------------------------------------------------- */
        public static string RPadH(string sStr, int nLen)
        {
            if (sStr == null) return "";

            byte[] bt1 = System.Text.Encoding.Default.GetBytes(sStr);

            int nL = bt1.Length;
            //if (nL == 0) return ""; //->스트링이 empty여도 Pad해주기 위해 주석처리 20100902


            if (nL > nLen)
            {

                return MidH(sStr, 0, nLen, 0);
                //return System.Text.Encoding.Default.GetString(bt1, 0, nLen);
            }
            else
            {

                return sStr + "".PadLeft(nLen - nL);
            }

        }
        /* ----------------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// <para>(한글(2byte)을 포함한 문자열에서 좌측기준으로 원하는 길이만큼 문자열 반환)</para>
        /// </summary>
        /// <param name="sStr">원본 문자열</param>
        /// <param name="nLength">길이</param>
        /// <returns>String Data</returns>
        /* ----------------------------------------------------------------------------------------- */
        public static string LeftH(string sStr, int nLength)
        {
            if (sStr == null) return "";

            //byte[] bt1 = System.Text.Encoding.Default.GetBytes(sStr);
            /*
            int nL = bt1.Length;
            if (nL == 0) return "";

            //시작점보다 크고 원하는 길이보다 작으면 시작점부터 나머지를 반환

            if (nL - nLen < 0)
            {
                nLen = nL;
            }
            return System.Text.Encoding.Default.GetString(bt1, 0, nLen);
            */
            return MidH(sStr, 0, nLength, 0);
        }
        /* ----------------------------------------------------------------------------------------- */
        /// <summary>
        /// <para>(한글(2byte)을 포함한 문자열에서 우측기준으로 원하는 길이만큼 문자열 반환)</para>
        /// </summary>
        /// <param name="sStr">원본 문자열</param>
        /// <param name="nLength">길이</param>
        /// <returns>반환 문자열</returns>
        /* ----------------------------------------------------------------------------------------- */
        public static string RightH(string sStr, int nLength)
        {
            try
            {

                if (sStr == null) return "";

                byte[] bt1 = System.Text.Encoding.Default.GetBytes(sStr);

                int nL = bt1.Length;
                if (nL == 0) return "";

                //시작점보다 크고 원하는 길이보다 작으면 시작점부터 나머지를 반환
                int nStart = nL - nLength;
                /*
                if (nL - nStart < nLength)
                {
                    nLength = nL - nStart;
                }
                return System.Text.Encoding.Default.GetString(bt1, nStart, nLength);
                */
                return MidH(sStr, nStart, nLength, 1);
            }
            catch
            {
                return sStr;
            }
        }
        /* ----------------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// <para>(한글(2byte)을 포함한 문자열에서 원하는 위치의 문자열 반환)</para>
        /// </summary>
        /// <param name="sStr">원본 문자열</param>
        /// <param name="nStart">시작점</param>
        /// <param name="nLength">길이</param>
        /// <returns>반환 문자열</returns>
        /* ----------------------------------------------------------------------------------------- */
        public static string MidH(string sStr, int nStart, int nLength)
        {
            /*
            if (sStr == null) return "";

            byte[] bt1 = System.Text.Encoding.Default.GetBytes(sStr);

            int nL = bt1.Length;
            if (nL == 0) return "";

            if (nL <= nStart) return "";

            //시작점보다 크고 원하는 길이보다 작으면 시작점부터 나머지를 반환

            if (nL - nStart < nLength)
            {
                nLength = nL - nStart;
            }
            return System.Text.Encoding.Default.GetString(bt1, nStart, nLength);
            */

            int nOrgLenth = nLength;

            try
            {
                return MidH(sStr, nStart, nLength, 0);
            }
            catch (Exception ex)
            {
                ex.ToString();
            }

            return " ".PadRight(nOrgLenth);

        }
        /* ----------------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// <para>(한글(2byte)을 포함한 문자열에서 원하는 위치의 문자열 반환)</para>
        /// </summary>
        /// <param name="sStr">원본 문자열</param>
        /// <param name="nStart">시작점</param>
        /// <param name="nLength">길이</param>
        /// <param name="nArrType"></param>
        /// <returns>반환 문자열</returns>
        /* ----------------------------------------------------------------------------------------- */
        private static string MidH(string sStr, int nStart, int nLength, int nArrType)
        {
            /*
            if (sStr == null) return "";

            byte[] bt1 = System.Text.Encoding.Default.GetBytes(sStr);

            int nL = bt1.Length;
            if (nL == 0) return "";

            if (nL <= nStart) return "";

            //시작점보다 크고 원하는 길이보다 작으면 시작점부터 나머지를 반환

            if (nL - nStart < nLength)
            {
                nLength = nL - nStart;
            }
            return System.Text.Encoding.Default.GetString(bt1, nStart, nLength);
            */

            int nOrgLenth = nLength;

            try
            {

                if (sStr != null && sStr != String.Empty)
                {
                    //Encoding encoding = Encoding.GetEncoding("euc-kr");
                    byte[] abyBuf = System.Text.Encoding.Default.GetBytes(sStr);  //encoding.GetBytes(sStr);
                    int nBuf = abyBuf.Length;

                    if (nStart < 0)
                    {
                        nStart = 0;
                    }
                    else if (nStart > nBuf)
                    {
                        nStart = nBuf;
                    }

                    if (nLength < 0)
                    {
                        nLength = 0;
                    }
                    else if (nLength > nBuf - nStart)
                    {
                        nLength = nBuf - nStart;
                    }

                    if (nStart < nBuf)
                    {
                        int nCopyStart = 0;
                        int nCopyLen = 0;

                        // 시작 위치를 결정한다.
                        if (nStart >= 1)
                        {
                            while (true)
                            {
                                if (abyBuf[nCopyStart] >= 0x80)
                                {
                                    nCopyStart++;
                                }

                                nCopyStart++;

                                if (nCopyStart >= nStart)
                                {
                                    if (nCopyStart > nStart)
                                    {
                                        nLength--;
                                    }

                                    break;
                                }
                            }
                        }

                        // 길이를 결정한다.
                        int nI = 0;

                        while (nI < nLength)
                        {
                            if (abyBuf[nCopyStart + nI] >= 0x80)
                            {
                                nI++;
                            }

                            nI++;
                        }

                        nCopyLen = (nI <= nLength) ? nI : nI - 2;

                        if (nCopyLen >= 1)
                        {
                            string sResult = "";
                            if (nOrgLenth - nCopyLen > 0)         // nLength -->
                            {
                                if (nArrType == 0)   // 우측 공백
                                    sResult = System.Text.Encoding.Default.GetString(abyBuf, nCopyStart, nCopyLen) + " ".PadRight(nOrgLenth - nCopyLen);
                                else
                                    sResult = " ".PadRight(nOrgLenth - nCopyLen) + System.Text.Encoding.Default.GetString(abyBuf, nCopyStart, nCopyLen);
                            }
                            else
                                sResult = System.Text.Encoding.Default.GetString(abyBuf, nCopyStart, nCopyLen);
                            return sResult;//encoding.GetString(abyBuf, nCopyStart, nCopyLen);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ex.ToString();
            }
            finally
            {
                //ZeroFillClear(ref sStr);
            }

            return " ".PadRight(nOrgLenth);

        }


        /* ----------------------------------------------------------------------------------------- */
        /// <summary>
        /// Determine of string input of Control is number
        /// <para>(Control의 문자열 입력값이 숫자인지 판별함. )</para>
        /// </summary>
        /// <param name="s">String to be checked if it is a number
        ///           <para>(숫자인지 체크할 문자열)</para></param>
        /// <returns>If it is a number, return true
        ///           <para>(숫자일 경우 true 리턴)</para></returns>
        /* ----------------------------------------------------------------------------------------- */
        public static bool ChkIsNum(string s)
        {
            bool CheckVal = false;

            for (int i = 0; i < s.Length; i++)
            {
                if (System.Char.IsNumber(s, i))
                    CheckVal = true;
                else
                {
                    if ((s.Substring(i, 1) == ".") || (s.Substring(i, 1) == ","))
                        CheckVal = true;
                    else
                    {
                        CheckVal = false;
                        break;
                    } //end of IF
                } //end of IF
            } //end of FOR
            return CheckVal;
        }

        #endregion

        /// <summary>
        /// 시간변환(HHMMSS => HH:MM:SS)
        /// </summary>
        /// <param name="sTimeStr"></param>
        /// <returns></returns>
        public static string StrToTime(string sTimeStr)
        {
            try
            {
                string sTime = sTimeStr.Replace(":", "").Trim();
                if (sTime.Length == 6)
                {
                    return sTime.Substring(0, 2) + ":" + sTime.Substring(2, 2) + ":" + sTime.Substring(4, 2);
                }
                else if (sTime.Length == 4)
                {
                    return sTime.Substring(0, 2) + ":" + sTime.Substring(2, 2);
                }
            }
            catch (Exception ex)
            {

            }
            return "";
        }

        public static string StrToDate(string sDateStr)
        {
            try
            {
                string temp = sDateStr.Replace("-", "").Replace("/", "");
                if (temp.Length == 8)
                {
                    return temp.Substring(0, 4) + "-" + temp.Substring(4, 2) + "-" + temp.Substring(6, 2); 
                }
                else if (temp.Length == 6)
                {
                    return temp.Substring(0, 4) + "-" + temp.Substring(4, 2);
                }
                else
                {
                    return sDateStr;
                }
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }

        #region POS IRT 전문 송/수신

        public bool ExecutePosIrt(string sMsgType, string sSvrIP, int nSvrPort, int nTimeout, Hashtable htSendData, ref Hashtable htRecvData)
        {
            try
            {
                string sCommHead = ItemColumn.MakeCommHeader(0, sMsgType);        // 통신해더 생성

                NetworkJSON netJson = new NetworkJSON();
                int ret = netJson.IRTSendReceive(sSvrIP, nSvrPort, nTimeout, sCommHead, htSendData, ref htRecvData);
                return ret == ComLib.OK ? true : false;
            }
            catch (Exception ex)
            {
                //WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                //   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);

                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , ex.Message);
                return false; 
            }
        }
        #endregion

        

        /// <summary>
        /// Executes process and waits until it has finished
        /// <para>(프로세스를 실행하고 종료될 때 까지 대기)</para>
        /// </summary>
        /// <param name="sProcessName"></param>
        /// <param name="arguments"></param>
        public static void ExecuteWaitProcess(string sProcessName, string arguments, System.Diagnostics.ProcessWindowStyle pwStyle = ProcessWindowStyle.Hidden, int milliseconds = 0)
        {
            try
            {
                System.Diagnostics.Process prc = new System.Diagnostics.Process();
                System.Diagnostics.ProcessStartInfo pcInfo = new System.Diagnostics.ProcessStartInfo();
                pcInfo.FileName = sProcessName;
                pcInfo.Arguments = arguments;
                pcInfo.WindowStyle = pwStyle;
                prc.StartInfo = pcInfo;
                prc.Start();

                if (milliseconds <= 0)
                    prc.WaitForExit();
                else
                    prc.WaitForExit(milliseconds);
            }
            catch (Exception ex)
            {
                ComLog.WriteLogFile(ComLib.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
        }

        /// <summary>
        /// 압축 (7za.exe를 이용한 zip 압축처리)
        /// </summary>
        /// <param name="zipFile"></param>
        /// <param name="scrPath"></param>
        /// <returns></returns>
        public static bool ExcuteZip(string zipFile, string scrPath, System.Diagnostics.ProcessWindowStyle pwStyle = ProcessWindowStyle.Hidden)
        {
            try
            {
                string cmd = "7za.exe";
                string arg = string.Format("{0} {1} {2}", "a", zipFile, scrPath);
                ExecuteWaitProcess(cmd, arg, pwStyle);
                System.Threading.Thread.Sleep(100);

                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 압축해제 (7za.exe를 이용한 zip 압축해제처리)
        /// </summary>
        /// <param name="zipFile"></param>
        /// <param name="trgPath"></param>
        /// <returns></returns>
        public static bool ExcuteUnzip(string zipFile, string trgPath, System.Diagnostics.ProcessWindowStyle pwStyle = ProcessWindowStyle.Hidden)
        {
            try
            {
                var cmd = "7za.exe";

                if (File.Exists(cmd) == false) return false; 

                var arg = string.Format("{0} {1} {2}{3}", "x -aoa", zipFile, "-o", trgPath);
                ExecuteWaitProcess(cmd, arg, pwStyle);
                System.Threading.Thread.Sleep(100);

                return true;
            }
            catch
            {
                return false;
            }
        }
        public static bool ExcuteUnzip(string toolPath, string zipFile, string trgPath, ProcessWindowStyle pwStyle = ProcessWindowStyle.Hidden)
        {
            try
            {
                var cmd = toolPath + @"\7za.exe";

                if (File.Exists(cmd) == false) return false; 

                var arg = string.Format("{0} {1} {2}{3}", "x -aoa", zipFile, "-o", trgPath);
                ExecuteWaitProcess(cmd, arg, pwStyle);
                System.Threading.Thread.Sleep(100);

                return true;
            }
            catch
            {
                return false;
            }
        }

        public static string GetLocalIpAddress()
        {
            string retValue = string.Empty;
            try
            {
                System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
                string posip = string.Empty;

                foreach (System.Net.IPAddress ip in host.AddressList)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        retValue = ip.ToString();
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                retValue = string.Empty;
            }
            return retValue;
        }

        /// <summary>
        /// 설정 파일 읽기
        /// </summary>
        /// <param name="cCfgInfo"></param>
        /// <param name="sGroup"></param>
        /// <param name="sValueName"></param>
        /// <returns></returns>
        public static string GetConfigInfo(CmMessage cCfgInfo, string sGroup, string sValueName)
        {
            return GetConfigInfo(cCfgInfo, sGroup, sValueName, "");
        }
        public static string GetConfigInfo(CmMessage cCfgInfo, string sGroup, string sValueName, string sDefault)
        {
            try
            {
                string sValue = cCfgInfo.GetMessage(sGroup).GetMessageValue(sValueName);
                if (sValue == null)
                    return sDefault;
                else
                    return sValue;
            }
            catch { }

            return sDefault;
        }

        /// <summary>
        /// OS 버전 정보 
        /// (Environment.OSVersion 정보)
        /// </summary>
        /// <returns></returns>
        public static string GetOSVersionString(bool isFullName = false)
        {
            try
            {
                string retValue = string.Empty;

                Version v = Environment.OSVersion.Version;

                if (v.Major == 5 && v.Minor > 0)
                {
                    retValue = "Windows XP ";
                }
                else if (v.Major == 6 && v.Minor == 0)
                {
                    retValue = "Windows VISTA ";
                }
                else if (v.Major == 6 && v.Minor == 1)
                {
                    retValue = "Windows 7 ";
                }
                else if (v.Major == 6 && v.Minor >= 2)
                {
                    retValue = "Windows 8/10 ";
                }

                if (isFullName)
                {
                    retValue += Environment.Is64BitOperatingSystem ? "(64Bit) " : "(32Bit) ";
                    retValue += Environment.OSVersion.ToString() + " ";
                    retValue += Environment.OSVersion.ServicePack + " ";
                }

                return retValue.Trim();
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// OS 버전 정보 
        /// (레지스트리 참조 관리자권한 일때 조회 가능)
        /// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
        /// </summary>
        /// <returns></returns>
        public static string GetOSProductName(bool isFullName = false)
        {
            try
            {
                string subKey = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion";

                string product = Registry.GetValue(Microsoft.Win32.Registry.LocalMachine, subKey, "ProductName");
                if (string.IsNullOrWhiteSpace(product)) return string.Empty;

                string version = Registry.GetValue(Microsoft.Win32.Registry.LocalMachine, subKey, "CurrentVersion");
                string service = Registry.GetValue(Microsoft.Win32.Registry.LocalMachine, subKey, "CSDVersion");
                string process = Environment.Is64BitOperatingSystem ? "(64Bit)" : "(32Bit)";

                if (isFullName)
                    return string.Format("{0} {1} {2} {3}", product, process, version, service).Trim();
                else
                    return product.Trim();
            }
            catch
            {
                return string.Empty; 
            }
        }

        public static bool IsAdministrator()
        {
            System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
            if (null != identity)
            {
                System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);
                return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
            }
            return false;
        }

        public static string GetCurrentPermission()
        {
            System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
            if (null != identity)
            {
                System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);
                if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
                {
                    return "Administrator"; 
                }

                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.PowerUser))
                {
                    return "PowerUser";
                }
                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.User))
                {
                    return "User";
                }
                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Guest))
                {
                    return "Guest";
                }

                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.AccountOperator))
                {
                    return "AccountOperator";
                }
                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.BackupOperator))
                {
                    return "BackupOperator";
                }

                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.PrintOperator))
                {
                    return "PrintOperator";
                }
                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Replicator))
                {
                    return "Replicator";
                }
                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Replicator))
                {
                    return "Replicator";
                }
                else if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.SystemOperator))
                {
                    return "SystemOperator";
                }

            }
            return string.Empty;
        }

        public static string GetIpAddress(string hostName)
        {
            var retValue = hostName;
            try
            {
                if (ComLib.IsNumber(hostName.Replace(".", "").Replace(":", "")) == false)
                {
                    //System.Net.IPHostEntry hostEntry = System.Net.Dns.GetHostByName(hostName);
                    System.Net.IPHostEntry hostEntry = System.Net.Dns.GetHostEntry(hostName);
                    foreach (System.Net.IPAddress ip in hostEntry.AddressList)
                    {
                        retValue = ip.ToString();
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , ex.Message);
            }
            finally
            {
                if (retValue != hostName)
                    ComLog.WriteLog(ComLog.Level.trace
                                  , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                                  + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                                  , string.Format("HostName:{0} => IPAddress:{1}", hostName, retValue));
            }
            return retValue;
        }
    }
}
