using System;
using System.Text;
using System.IO;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Media;
using System.Threading;

using Microsoft.Speech.Synthesis;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using System.Runtime.InteropServices;
using Cosmos.UserFrame;

/*-----------------------------------------------------------------------------------------------*/
// 설      명 : 공통 모듈
// 작  성  자 : 
// 변경  이력 : 
/*-----------------------------------------------------------------------------------------------*/
namespace Cosmos.Common
{
    /// <summary>
    /// Common Utility 
    /// </summary>
    public class CmUtil : UsUtil
    {
        [DllImport("Sensapi.dll")]
        private static extern int IsNetworkAlive(ref int dwFlags);

        //private static int NETWORK_LAN = 0x01;           // 랜 카드 신호 유무
        //private static int NETWORK_WAN = 0x02;           // WAN 관련 유무
        //private static int NETWORK_AOL = 0x04;           // 랜 카드 AOL 신호 유무


        ///// <summary>
        ///// 수량 표시형식으로 변환
        ///// </summary>
        ///// <param name="sQty"></param>
        ///// <returns></returns>
        //public static string NumToQty(string sQty)
        //{
        //    try
        //    {
        //        if (sQty.Trim().Length > 0)
        //        {
        //            return NumToQty((long)double.Parse(sQty.Trim()));
        //        }
        //    }
        //    catch { }
        //    return "0";
        //}

        ///// <summary>
        ///// 수량 표시형식으로 변환
        ///// </summary>
        ///// <param name="nQty"></param>
        ///// <returns></returns>
        //public static string NumToQty(long nQty)
        //{
        //    try
        //    {
        //        return String.Format("{0:N0}", nQty);
        //    }
        //    catch { }
        //    return "0";
        //}

        /// <summary>
        /// 문자열의 숫자(Long)로 변환 - 글로벌 금액표시 문자열 변환에 사용하면 안됨
        /// </summary>
        /// <param name="sValue"></param>
        /// <returns></returns>
        public static long LongParse(string sValue)
        {
            try
            {
                if (sValue.Trim().Length > 0)
                {
                    return (long)DoubleParse(sValue);
                }
            }
            catch { }

            return 0;
        }
        /// <summary>
        /// 문자열의 숫자(Int)로 변환 - 글로벌 금액표시 문자열 변환에 사용하면 안됨
        /// </summary>
        /// <param name="sValue"></param>
        /// <returns></returns>
        public static int IntParse(string sValue)
        {
            try
            {
                if (sValue.Trim().Length > 0)
                {
                    return (int)DoubleParse(sValue);
                }
            }
            catch { }

            return 0;
        }

        /// <summary>
        /// 문자열의 숫자(Double)로 변환 - 글로벌 금액표시 문자열 변환에 사용하면 안됨
        /// </summary>
        /// <param name="sValue"></param>
        /// <returns></returns>
        public static double DoubleParse(string sValue)
        {
            double dValue = 0;
            try
            {
                if (sValue.Trim().Length > 0)
                {
                    dValue = double.Parse(sValue.Trim());
                }
            }
            catch { }

            return dValue;
        }
        
        /// <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 { }

            return "";
        }

        /// <summary>
        /// Round Up, Round Off, Round Down Calculation(올림 반올림 버림 계산)
        /// </summary>
        /// <param name="Value">Calculated(계산)</param>
        /// <param name="Type">0:Round Up(올림) 1: Round Off(반올림) 2: Round Down(버림)</param>
        /// <param name="Digits">Digit Number(자릿수)</param>
        /// <returns></returns>
        public static double MathRounds(double Value, string Type, int Digits)
        {
            double Sum = 0;

            try
            {
                double n = Math.Pow(10.0, Digits);

                switch (Type)
                {
                    case PosConst.MATH_ROUND.CEILING:   //Round Up(올림)
                        Sum = CmUtil.DoubleDivision(Math.Ceiling(CmUtil.DoubleMultiplication(Value, n)), n);
                        break;
                    case PosConst.MATH_ROUND.ROUND:     //Round Off(반올림)
                        //#20171109 반올림 계산시 5인 경우 올림이 되지 않고 내림이 됨 start
                        //기존
                        Sum = CmUtil.DoubleDivision(Math.Round(CmUtil.DoubleMultiplication(Value, n)), n);
                        //변경
                        //Sum = CmUtil.DoubleDivision(Math.Round(CmUtil.DoubleMultiplication(Value, n), MidpointRounding.AwayFromZero), n);
                        //#20171109 반올림 계산시 5인 경우 올림이 되지 않고 내림이 됨 end
                        //Sum = Math.Round(Value, Digits, MidpointRounding.AwayFromZero);
                        break;
                    case PosConst.MATH_ROUND.TRANCATE: //Round Down(버림)
                        Sum = CmUtil.DoubleDivision(Math.Truncate(CmUtil.DoubleMultiplication(Value, n)), n);
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return Sum;
        }

        /// <summary>
        /// Cut as many as designated No. of digits.(지정한 자리만큼 절사한다.)
        /// </summary>
        /// <param name="pAmt">AMOUNT(금액)</param>
        /// <param name="pPos">No. of Cut Digits(절사 자리수)</param>
        /// <param name="cut_Amt"> The amount of No. of Cut(절사된 금액)</param>
        /// <returns></returns>
        public static double AmountCut(double Amt, int Digits, out double cut_Amt)
        {
            double n = Math.Pow(10.0, Digits);
            double Sum = 0;
            cut_Amt = 0.0;
            try
            {
                Sum = DoubleDivision(Math.Truncate(DoubleMultiplication(Amt, n)), n);
                cut_Amt = DoubleSubtraction(Amt, Sum);
            }
            catch (Exception ex)
            {
                Sum = Amt;
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return Sum;

        }
        public static double AmountCut(double Amt, int Digits)
        {
            double cut_Amt;

            return AmountCut(Amt, Digits, out cut_Amt);
        }

        /// <summary>
        /// 율 금액 계산
        /// </summary>
        /// <param name="nValue"></param>
        /// <param name="dPercent"></param>
        /// <returns></returns>
        public static double MathAmtPercent(double nValue, double dPercent)
        {
            try
            {
                return DoubleMultiplication(nValue, (dPercent / 100.00));
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return 0;
        }

        /// <summary>
        /// Double Type Add (더블형 더하기)
        /// </summary>
        /// <param name="Sum1">Calculation Value1(계산값1)</param>
        /// <param name="Sum2">Calculation Value1(계간값2)</param>
        /// <returns>Result Value(결과값)</returns>
        public static double DoubleAdd(double Sum1, double Sum2)
        {
            decimal Sum = 0;
            try
            {
                Sum = Convert.ToDecimal(Sum1) + Convert.ToDecimal(Sum2);
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return Convert.ToDouble(Sum);
        }

        /// <summary>
        /// Double Type Subtraction (더블형 빼기)
        /// </summary>
        /// <param name="Sum1">Calculation Value1(계산값1)</param>
        /// <param name="Sum2">Calculation Value1(계간값2)</param>
        /// <returns>Result Value(결과값)</returns>
        public static double DoubleSubtraction(double Sum1, double Sum2)
        {
            decimal Sum = 0;
            try
            {
                Sum = Convert.ToDecimal(Sum1) - Convert.ToDecimal(Sum2);
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return Convert.ToDouble(Sum);
        }

        /// <summary>
        /// Double Type Subtraction (더블형 곱하기)
        /// </summary>
        /// <param name="Sum1">Calculation Value1(계산값1)</param>
        /// <param name="Sum2">Calculation Value1(계간값2)</param>
        /// <returns>Result Value(결과값)</returns>
        public static double DoubleMultiplication(double Sum1, double Sum2)
        {
            decimal Sum = 0;
            try
            {
                Sum = Convert.ToDecimal(Sum1) * Convert.ToDecimal(Sum2);
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return Convert.ToDouble(Sum);
        }

        /// <summary>
        /// Double Type Division (더블형 나누기)
        /// </summary>
        /// <param name="Sum1">Calculation Value1(계산값1)</param>
        /// <param name="Sum2">Calculation Value1(계간값2)</param>
        /// <returns>Result Value(결과값)</returns>
        public static double DoubleDivision(double Sum1, double Sum2)
        {
            decimal Sum = 0;
            try
            {
                Sum = Convert.ToDecimal(Sum1) / Convert.ToDecimal(Sum2);
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return Convert.ToDouble(Sum);
        }

        public static string IsNull(string sDestStr, string sSwitchStr)
        {
            try
            {
                if(sDestStr == null || sDestStr.Trim() == string.Empty)
                {
                    sDestStr = string.Empty;
                    sDestStr = sSwitchStr;
                }
            }
            catch
            {

            }

            return sDestStr;
        }

        /// <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>
        /// 문자열 특정 갯수만큼 생성 처리
        /// </summary>
        /// <param name="sValue"></param>
        /// <returns></returns>
        public static string StringChar(string sValue, int nLen)
        {
            string sRetValue = "";
            try
            {
                for (int nIndex = 0; nIndex < nLen; nIndex++)
                {
                    sRetValue += sValue;
                }
            }
            catch (Exception ex)
            {
                return sRetValue;
            }
            return sRetValue;
        }
        /// <summary>
        /// 특정문자 특정 갯수만큼 생성 처리
        /// </summary>
        /// <author>Yoo</author>
        /// <param name="sValue"></param>
        /// <param name="sSource"></param>
        /// <param name="nLen"></param>
        /// <param name="sOrder"></param>
        /// <returns>sRetValue</returns>
        /// ex sValue "abc", sSource " ", nLen 10, nOrder "L" -> "       abc"
        /// ex sValue "abc", sSource " ", nLen 10, nOrder "L" -> "abc       "
        public static string StringfillChar(string sValue, string sSource, int nLen, string sOrder)
        {
            string sRetValue = sSource;
            int nGap = nLen - sValue.Length -1 ;
            try
            {
                if (nGap > 0)
                {
                    for (int nIndex = 0; nIndex < nGap; nIndex++)
                    {
                        sRetValue += sSource;
                    }
                    if (sOrder == "L")
                    {
                        sRetValue += sValue;
                    }
                    else
                    {
                        sValue += sRetValue;
                        sRetValue = sValue;
                    }
                }
                else
                {
                    if (sOrder == "L")
                    {
                        sRetValue = sSource + sValue;
                    }
                    else
                    {
                        sRetValue = sValue + sSource;
                    }
                    
                }
            }
            catch (Exception ex)
            {
                return sRetValue;
            }
            return sRetValue;
        }
        /// <summary>
        /// 특정 위치만 반환
        /// </summary>
        /// <author>Yoo</author>
        /// <param name="sSrc"></param>
        /// <param name="iPos"></param>
        /// <param name="iLength"></param>
        /// <returns>sRetValue</returns>        
        private string GetStringFromByteArray(byte[] sSrc, int iPos, int iLen)
        {
            string retStr = "";
            byte[] tmp = new byte[4096];

            Array.Clear(tmp, 0x0, tmp.Length);

            Array.Copy(sSrc, iPos, tmp, 0, iLen);

            retStr = System.Text.Encoding.Default.GetString(tmp).Trim('\0');

            return retStr;
        }
        /// <summary>
        /// 고객식별정보 마스킹 처리
        /// </summary>
        /// <param name="sPersonInfo"></param>
        /// <returns></returns>
        public static string MakePersonInfo(string sPersonInfo)
        {
            string sRet = sPersonInfo.TrimEnd();
            try
            {
                //if (sPersonInfo.TrimEnd().Length == 18) // 현금영수증 카드번호인 경우
                //    sRet = sPersonInfo.Substring(0, 4) + "-" + sPersonInfo.Substring(4, 4) + "-" + sPersonInfo.Substring(8, 2) + "**-**" + sPersonInfo.Substring(14, 4);
                //else if (sPersonInfo.TrimEnd().Length != 18 && sPersonInfo.TrimEnd().Length > 15) // 카드번호인 경우
                //    //sRet = sPersonInfo.Substring(0, 4) + "********" + sPersonInfo.Substring(12, 4);
                //    sRet = sPersonInfo.Substring(0, 4) + "********" + "****";
                //else if (sPersonInfo.TrimEnd().Length == 13)
                //    sRet = sPersonInfo.Substring(0, 5) + "*-***" + sPersonInfo.Substring(9, 4);
                //else if (sPersonInfo.TrimEnd().Length == 12)
                //    sRet = sPersonInfo.Substring(0, 4) + "****" + sPersonInfo.Substring(8, 4);
                //else if (sPersonInfo.TrimEnd().Length == 10)
                //    sRet = sPersonInfo.Substring(0, 2) + "*-**-*" + sPersonInfo.Substring(6, 4);
                //else if (sPersonInfo.TrimEnd().Length == 11)
                //    sRet = sPersonInfo.Substring(0, 3) + "-****-" + sPersonInfo.Substring(7, 4);
                
                //SPC 여전법 요청!

                //if (sPersonInfo.TrimEnd().Length == 11)
                //{
                //    sRet = sPersonInfo.Substring(0, 7) + "****";
                //}
                if (sPersonInfo.TrimEnd().Length > 6)
                {
                    sRet = CmUtil.MidH(sPersonInfo, 0, 6) + new string('*', sPersonInfo.TrimEnd().Length - 6);
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return sRet;
        }

        /// <summary>
        /// DateTime을 HHMMSS string으로 바꾼다
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string TimeToStringHHMMSS(DateTime dt)
        {
            return dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00");
        }

        /// <summary>
        /// 대상문자열배열에 특정문자자 존재하는지 체크 한다.
        /// </summary>
        /// <param name="aDstStr"></param>
        /// <param name="sCompStr"></param>
        /// <returns></returns>
        public static bool ExistArrayString(string[] aDstStr, string sCompStr)
        {
            try
            {
                for (int i = 0; i < aDstStr.Length; i++)
                {
                    if (aDstStr[i] == sCompStr) return true;
                }
            }
            catch (Exception ex)
            {

            }
            return false;
        }

        /// <summary>
        /// 파일 사이즈 체크
        /// </summary>
        /// <param name="sCheckFile"></param>
        /// <returns></returns>
        public static long GetFileSize(string sCheckFile)
        {
            try
            {
                FileInfo FileInfo = new System.IO.FileInfo(sCheckFile);
                return FileInfo.Length;
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 텍스트 파일의 최종 라인 읽기
        /// </summary>
        /// <param name="sFileName"></param>
        /// <returns></returns>
        public static string ReadFileLastLine(string sFileName)
        {
            string sReadLine = "";

            try
            {
                if (File.Exists(sFileName))
                {
                    FileStream fs = new FileStream(sFileName, FileMode.Open, FileAccess.Read);
                    StreamReader sr = new StreamReader(fs, Encoding.Default);

                    try
                    {
                        sr.BaseStream.Seek(0, SeekOrigin.Begin);

                        while (sr.Peek() > -1)
                        {
                            string sLine = sr.ReadLine();
                            if (sLine.Trim().Length == 0) continue;

                            sReadLine = sLine;
                        }
                    }
                    catch { }
                    finally
                    {
                        sr.Close();
                        fs.Close();
                    }
                }
            }
            catch { }

            return sReadLine;
        }

        /// <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)
        {
            try
            {
                if (File.Exists(sSrcFileName) == false) return false;

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

                if ( bSrcDelete == true) File.Delete(sSrcFileName);

                return true;
            }
            catch { }

            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 { }

            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 + @"\";
                        DirectoryCopy(sSrcPath + fi.Name + @"\", sDstPath + fi.Name + @"\", sBckSubPath);
                        //DirectoryCopy(sSrcPath + fi.Name + @"\", sDstPath + fi.Name + @"\", sBackPath + fi.Name + @"\");
                    }
                }

                return true;
            }
            catch { }

            return false;
        }

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

                File.Delete(sFileFullName);

                return true;
            }
            catch { }

            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)
        {
            return FileMove(sFileName, sSrcPath, sDstPath, sBackPath, sFileName);
        }
        public static bool FileMove(string sFileName, string sSrcPath, string sDstPath, string sBackPath, string sDstFileName)
        {
            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 + sDstFileName);            // 파일이동 처리

                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;
        }

        /// <summary>
        /// Ping 테스트
        /// </summary>
        /// <param name="sIpAddress"></param>
        /// <returns></returns>
        public static bool PingTest(string sIpAddress)
        {
            try
            {
                if (sIpAddress.Trim().Replace(".", "").Length == 0) return false;

                System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
                System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();

                // Use the default Ttl value which is 128,but change the fragmentation behavior.
                options.DontFragment = true;

                // Create a buffer of 32 bytes of data to be transmitted.
                string data = "Create a buffer of 32 bytes of d";
                byte[] buffer = Encoding.ASCII.GetBytes(data);
                int timeout = 120;
                System.Net.NetworkInformation.PingReply reply = pingSender.Send(sIpAddress, timeout, buffer, options);

                if (reply.Status == System.Net.NetworkInformation.IPStatus.Success) return true;
                else return false;
            }
            catch { return false; }
        }

        /// <summary>
        /// String Null값 변환
        /// </summary>
        /// <param name="nAmt"></param>
        /// <returns></returns>
        public static string StringNullEmpty(string sValue)
        {
            try
            {
                if (string.IsNullOrEmpty(sValue)) return String.Empty;
                else return sValue;
            }
            catch (Exception ex)
            {

            }
            return "";
        }

        /// <summary>
        /// 화면표시용 카드번호 마스킹 처리
        /// </summary>
        /// <param name="sCardNo"></param>
        /// <returns></returns>
        public static string MakeDisplayCardNo(string sCardNo)
        {
            string sRet = sCardNo.TrimEnd();
            try
            {
                sRet = CmUtil.MidH(sCardNo, 0, 6) + "******" + "****";
                //if (sCardNo.TrimEnd().Length > 12)
                //{
                //    //sRet = sCardNo.Substring(0, 6) + "******" + sCardNo.Substring(12);
                //    sRet = sCardNo.Substring(0, 6) + "******" + "****";
                //}
                //else if (sCardNo.TrimEnd().Length > 6)
                //{
                //    sRet = sCardNo.Substring(0, 6).PadRight(sCardNo.Length, '*');
                //}
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return sRet;
        }

        /// <summary>
        /// DataRow 에서 값 획득
        /// </summary>
        /// <param name="drData"></param>
        /// <param name="sColumnName"></param>
        /// <returns></returns>
        public static string GetDataRowStr(DataRow drData, string sColumnName)
        {
            try
            {
                return drData[sColumnName].ToString();
            }
            catch
            {
                return "";
            }
        }

        /// <summary>
        /// DataRow 에서 값 획득
        /// </summary>
        /// <param name="drData"></param>
        /// <param name="sColumnName"></param>
        /// <returns></returns>
        public static long GetDataRowLong(DataRow drData, string sColumnName)
        {
            try
            {
                return (long)double.Parse(drData[sColumnName].ToString());
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// DataRow 에서 값 획득
        /// </summary>
        /// <param name="drData"></param>
        /// <param name="sColumnName"></param>
        /// <returns></returns>
        public static double GetDataRowDouble(DataRow drData, string sColumnName)
        {
            try
            {
                return double.Parse(drData[sColumnName].ToString());
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// DataRow 에서 값 획득
        /// </summary>
        /// <param name="drData"></param>
        /// <param name="sColumnName"></param>
        /// <returns></returns>
        public static int GetDataRowInt(DataRow drData, string sColumnName)
        {
            try
            {
                return (int)double.Parse(drData[sColumnName].ToString());
            }
            catch
            {
                return 0;
            }
        }
        /// <summary>
        /// DataRow 에서 값 획득
        /// </summary>
        /// <param name="drData"></param>
        /// <param name="sColumnName"></param>
        /// <returns></returns>
        public static float GetDataRowFloat(DataRow drData, string sColumnName)
        {
            try
            {
                return float.Parse(drData[sColumnName].ToString());
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 문자열에서 컬러 획득
        /// </summary>
        /// <param name="sColorStr"></param>
        /// <returns></returns>
        public static Color GetColorToString(string sColorStr)
        {
            try
            {
                if (sColorStr.Length >= 9) return Color.FromArgb(int.Parse(sColorStr.Substring(0, 3)), int.Parse(sColorStr.Substring(3, 3)), int.Parse(sColorStr.Substring(6, 3)));
            }
            catch { }
            return Color.White;
        }

        /// <summary>
        /// 사운드 파일 출력
        /// </summary>
        /// <param name="sFileName"></param>
        public static void PlaySound(string sFileName)
        {
            try
            {
                if (File.Exists(sFileName))
                {
                    SoundPlayer cPlayer = new SoundPlayer(sFileName);
                    cPlayer.Play();
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
        }

        /// <summary>
        /// Get System Date/Time Second
        /// </summary>
        /// <returns></returns>
        public static long GetSystemSecond()
        {
            long lSecond = 0;
            int[] arDays1 = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
            int[] arDays2 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

            try
            {
                // 시스템 시간을 얻음 
                DateTime dtNow = DateTime.Now;

                // 초계산
                for (int nLoop = 1; nLoop < dtNow.Year; nLoop++)
                {
                    // 윤년
                    if ((nLoop % 4) == 0)
                    {
                        lSecond += (366 * 24 * 60 * 60);
                    }
                    // 평년
                    else
                    {
                        lSecond += (365 * 24 * 60 * 60);
                    }
                }

                // 윤년
                if ((dtNow.Year % 4) == 0)
                {
                    for (int nLoop = 1; nLoop < dtNow.Month; nLoop++)
                    {
                        lSecond += arDays2[nLoop - 1] * 24 * 60 * 60;
                    }
                }
                // 평년
                else
                {
                    for (int nLoop = 1; nLoop < dtNow.Month; nLoop++)
                    {
                        lSecond += arDays1[nLoop - 1] * 24 * 60 * 60;
                    }
                }

                // 일자 초계산
                lSecond += (dtNow.Day - 1) * 24 * 60 * 60;

                // 시간초계산
                lSecond += dtNow.Hour * 60 * 60;

                // 분초계산
                lSecond += dtNow.Minute * 60;

                // 초계산
                lSecond += dtNow.Second;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

            return lSecond;
        }

        /// <summary>
        /// Datetime to Second
        /// </summary>
        /// <param name="strDateTime"></param>
        /// <returns></returns>
        public static long GetYYYYMMDDHHMISSToSecond(string strDateTime)
        {
            int nYear, nMonth, nDay, nHour, nMinute, nSecond;
            long lSecond = 0;
            int[] arDays1 = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
            int[] arDays2 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

            try
            {
                // 일자 / 시간 자리수 체크
                if (strDateTime.Length != 14)
                {
                    return -1;
                }

                // 숫자값이 아니면 에러
                if (IsNumber(strDateTime) == false)
                {
                    return -1;
                }

                // 년
                nYear = int.Parse(strDateTime.Substring(0, 4));

                // 월
                nMonth = int.Parse(strDateTime.Substring(4, 2));
                if (nMonth < 1 || nMonth > 12)
                {
                    return -1;
                }

                // 일
                nDay = int.Parse(strDateTime.Substring(6, 2));
                if (nDay < 1 || nDay > 31)
                {
                    return -1;
                }

                // 시
                nHour = int.Parse(strDateTime.Substring(8, 2));
                if (nHour < 0 || nHour > 24)
                {
                    return -1;
                }

                // 분
                nMinute = int.Parse(strDateTime.Substring(10, 2));
                if (nMinute < 0 || nMinute > 60)
                {
                    return -1;
                }

                // 초
                nSecond = int.Parse(strDateTime.Substring(12, 2));
                if (nSecond < 0 || nSecond > 60)
                {
                    return -1;
                }

                // 시스템 시간을 얻음 
                DateTime dtDateTime = new DateTime(nYear, nMonth, nDay, nHour, nMinute, nSecond);

                // 초계산
                for (int nLoop = 1; nLoop < dtDateTime.Year; nLoop++)
                {
                    // 윤년
                    if ((nLoop % 4) == 0)
                    {
                        lSecond += (366 * 24 * 60 * 60);
                    }
                    // 평년
                    else
                    {
                        lSecond += (365 * 24 * 60 * 60);
                    }
                }

                // 윤년
                if ((dtDateTime.Year % 4) == 0)
                {
                    for (int nLoop = 1; nLoop < dtDateTime.Month; nLoop++)
                    {
                        lSecond += arDays2[nLoop - 1] * 24 * 60 * 60;
                    }
                }
                // 평년
                else
                {
                    for (int nLoop = 1; nLoop < dtDateTime.Month; nLoop++)
                    {
                        lSecond += arDays1[nLoop - 1] * 24 * 60 * 60;
                    }
                }

                // 일자 초계산
                lSecond += (dtDateTime.Day - 1) * 24 * 60 * 60;

                // 시간초계산
                lSecond += dtDateTime.Hour * 60 * 60;

                // 분초계산
                lSecond += dtDateTime.Minute * 60;

                // 초계산
                lSecond += dtDateTime.Second;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

            return lSecond;
        }

        /// <summary>
        /// Second to Time
        /// </summary>
        /// <returns></returns>
        public static string ConvertSecondToHhMmDd(long lConvertSecond, bool bFormatFlag)
        {
            long lHour = 0, lMinute = 0, lSecond = 0;
            string strHhMmDd = "0:0:0";

            try
            {
                if (lConvertSecond < 0)
                {
                    return strHhMmDd;
                }

                // 시간계산
                lHour = lConvertSecond / (60 * 60);
                lConvertSecond = lConvertSecond - (lHour * (60 * 60));

                // 분계산
                lMinute = lConvertSecond / 60;
                lConvertSecond = lConvertSecond - (lMinute * 60);

                // 초계산
                lSecond = lConvertSecond;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

            if (bFormatFlag)
            {
                strHhMmDd = string.Format("{0}:{1:D2}:{2:D2}", lHour, lMinute, lSecond);
            }
            else
            {
                strHhMmDd = string.Format("{0}:{1}:{2}", lHour, lMinute, lSecond);
            }
            return strHhMmDd;
        }

        /// <summary>
        /// Second to Time
        /// </summary>
        /// <param name="lConvertSecond"></param>
        /// <returns></returns>
        public static string ConvertSecondToHhMmDd(long lConvertSecond)
        {
            return ConvertSecondToHhMmDd(lConvertSecond, false);
        }

        /// <summary>
        /// 메모리 변수 ZeroFill 초기화 함수 - 여신법대응
        /// </summary>
        /// <param name="sValue"></param>
        public static void ZeroFillClear(ref string sValue)
        {
            try
            {
                if (string.IsNullOrEmpty(sValue)) return;
                int nLen = sValue.Length;

                string sFill = "";
                sFill = new string('A', nLen); sValue = sFill;
                sFill = new string('0', nLen); sValue = sFill;
                sFill = new string('X', nLen); sValue = sFill;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + 
                                                        System.Reflection.MethodBase.GetCurrentMethod().Name + "()", 
                                                        ex.Message);
            }
            finally
            {
                sValue = string.Empty;
            }
        }

        /// <summary>
        /// 메모리 변수 ZeroFill 초기화 함수 - 배열
        /// </summary>
        /// <param name="sVaules"></param>
        public static void ZeroFillClear(ref string[] sVaules)
        {
            try
            {
                if (sVaules == null) return;

                for (int iRow = 0; iRow < sVaules.Length; iRow++)
                {
                    ZeroFillClear(ref sVaules[iRow]);
                }
    
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
        }


        /// <summary>
        /// 마스터 출력크기 구분에 따른 출력 형태 획득
        /// </summary>
        /// <param name="sSizeDiv"></param>
        /// <returns></returns>
        public static string GetPrtMstToPrtHeadConst(string sSizeDiv, string sBoldYn)
        {
            string sPrtHead = PosConst.PRT_HDR.PRT_NOR;
            try
            {
                // 0:보통, 1:굵게, 2:가로확대, 3:세로확대, 4:전체확대
                switch (sSizeDiv)
                {
                    case PosConst.PRT_EXPAND_TYPE.BOLD:   // 굵게
                        sPrtHead = PosConst.PRT_HDR.PRT_BLD;
                        break;
                    case PosConst.PRT_EXPAND_TYPE.HOR:   // 가로확대
                        if (sBoldYn == "1")  // 0:보통, 1:BOLD
                            sPrtHead = PosConst.PRT_HDR.PRT_HRB;
                        else
                            sPrtHead = PosConst.PRT_HDR.PRT_HOR;;
                        break;
                    case PosConst.PRT_EXPAND_TYPE.VER:   // 세로확대
                        if (sBoldYn == "1")  // 0:보통, 1:BOLD
                            sPrtHead = PosConst.PRT_HDR.PRT_VRB;
                        else
                            sPrtHead = PosConst.PRT_HDR.PRT_VER;
                        break;
                    case PosConst.PRT_EXPAND_TYPE.BOTH:   // 전체확대
                        if (sBoldYn == "1")  // 0:보통, 1:BOLD
                            sPrtHead = PosConst.PRT_HDR.PRT_BGB;
                        else
                            sPrtHead = PosConst.PRT_HDR.PRT_BIG;
                        break;
                    default:   // 보통
                        if (sBoldYn == "1")  // 0:보통, 1:BOLD
                            sPrtHead = PosConst.PRT_HDR.PRT_BLD;
                        else
                            sPrtHead = PosConst.PRT_HDR.PRT_NOR;
                        break;
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return sPrtHead;
        }

        /// <summary>
        /// 이미지 파일 로딩
        /// </summary>
        /// <param name="sFileName"></param>
        /// <returns></returns>
        public static Image LoadImage( string sFileName)
        {
            try
            {
                if (sFileName == "" || File.Exists(sFileName) == false) return null;

                return Image.FromFile(sFileName);
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 압축된 파일을 지정한 폴더에 푼다.
        /// </summary>
        /// <param name="sDirectoryNameToExtract">압축을 해방할 폴더(Full Path)</param>
        /// <param name="sZipFileName">압축된 파일명(Full Path)</param>
        public static bool UnZipFile(string sDirectoryNameToExtract, string sZipFileName)
        {
            bool bRet = false;

            try
            {
                // 압축을 풀 대상 파일이 존재하는지 확인
                if (!File.Exists(sZipFileName))
                    throw new Exception();

                // 압축을 풀 대상 폴더가 존재하지 않으면 생성
                if (!Directory.Exists(sDirectoryNameToExtract))
                    Directory.CreateDirectory(sDirectoryNameToExtract);

                // 압축을 풀 대상 폴더 내 디렉토리 생성
                using(ZipInputStream zis = new ZipInputStream(File.OpenRead(sZipFileName)))
                {
                    ZipEntry theEntry;
                    while((theEntry = zis.GetNextEntry()) != null)
                    {
                        if(theEntry.IsDirectory)
                        {
                            if (!Directory.Exists(sDirectoryNameToExtract + theEntry.Name))
                                Directory.CreateDirectory(sDirectoryNameToExtract + theEntry.Name);
                        }
                    }
                }

                // 압축을 풀 대상 폴더 내 파일 생성
                using(ZipInputStream zis = new ZipInputStream(File.OpenRead(sZipFileName)))
                {
                    ZipEntry theEntry;
                    while((theEntry = zis.GetNextEntry()) != null)
                    {
                        if(theEntry.IsFile)
                        {
                            string sFileName = Path.GetFileName(theEntry.Name);

                            if(sFileName != String.Empty)
                            {
                                // On some compression programs such as PangZip, etc., (빵집등 일부 압축 프로그램에서는) 
                                // theEntry.IsDirectory is not identified. (theEntry.IsDirectory 구분이 되지 않는다.)
                                // As the directory is recognized as like a file, the file format without extension is determined as a directory. (디렉토리도 파일처럼 인식하므로 확장자가 없는 파일형을 디렉토리로 판단한다.)
                                FileInfo fiTemp = new FileInfo(Path.Combine(sDirectoryNameToExtract, theEntry.Name));
                                if(fiTemp.Extension == "")
                                {
                                    if (!Directory.Exists(sDirectoryNameToExtract + theEntry.Name))
                                        Directory.CreateDirectory(sDirectoryNameToExtract + theEntry.Name);

                                    continue;
                                }
                                else
                                {
                                    if (!Directory.Exists(fiTemp.DirectoryName))
                                        Directory.CreateDirectory(fiTemp.DirectoryName);
                                }

                                using(FileStream streamWriter = File.Create(sDirectoryNameToExtract + theEntry.Name))
                                {
                                    int iReadLen = 2048;
                                    byte[] data = new byte[2048];
                                    while(true)
                                    {
                                        iReadLen = zis.Read(data, 0, data.Length);
                                        if(iReadLen > 0)
                                        {
                                            streamWriter.Write(data, 0, iReadLen);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                bRet = true;
            }
            catch (Exception ex)
            {
                bRet = false;
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return bRet;
        }

        /// <summary>
        /// Compress all files to the target folder . (including subdirectory) (대상폴더에 모든 파일을 압축한다. (하위 디렉토리 포함))
        /// </summary>
        /// <param name="pTargetFolder">Target Folder (대상폴더)</param> 
        /// <param name="pZipFileName">Zip Filename (압축파일명)</param>
        public static bool ZipFile(string pTargetFolder, string pZipFileName)
        {
            return ZipFile(pTargetFolder, pZipFileName, "");
        }
        public static bool ZipFile(string pTargetFolder, string pZipFileName, string pOnlyFileName)
        {
            bool bRet = false;

            // Designation of Target Folder for Compression (압축할 폴더 지정)
            DirectoryInfo diTarget = null;

            // For Files to be compressed (압축당할 파일용)
            FileStream fsTargetFile = null;

            // For Zip Files (압축파일용)
            FileStream fsZipFile = null;

            // Connect File Stream for Zip Files (압축파일용 파일스트림을 연결) 
            ICSharpCode.SharpZipLib.Zip.ZipOutputStream zips = null;

            try
            {
                if (File.Exists(pZipFileName))
                    File.Delete(pZipFileName);

                diTarget = new DirectoryInfo(pTargetFolder);

                // Target Directory Check (대상 디렉토리 체크)
                if (!diTarget.Exists)
                {
                    // In case of no compression object (압축할 대상이 없는경우)
                    throw new Exception();
                }

                fsZipFile = new FileStream(pZipFileName, FileMode.Create);

                zips = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(fsZipFile);

                // The Fastest Compression Level (압축율 Lenvel 최고 빠르게)
                zips.SetLevel(9);

                bRet = ZipDirectoryFile(diTarget, "", pZipFileName, pOnlyFileName, zips);
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
                bRet = false;
            }
            finally
            {
                // File Object Close Work (파일객체 Close 작업)
                if (zips != null)
                {
                    zips.Finish();
                    zips.Close();
                }

                if (fsZipFile != null)
                    fsZipFile.Close();
                if (fsTargetFile != null)
                    fsTargetFile.Close();
            }
            return bRet;
        }

        /// <summary>
        /// File Compression (Including Subdirectory (파일 압축 (서브 디렉토리 포함)) 
        /// </summary>
        /// <param name="pTarget"></param>
        /// <param name="pDescFolder"></param>
        /// <param name="pZipFileName"></param>
        /// <param name="pZip"></param>
        /// <returns></returns>
        private static bool ZipDirectoryFile(DirectoryInfo pTarget, string pDescFolder, string pZipFileName, string pOnlyFileName, ZipOutputStream pZip)
        {
            bool bRet = false;

            try
            {
                // For Files to be compressed (압축당할 파일용)
                FileStream fsTargetFile = null;

                byte[] buffer = new byte[2048];
                int size;

                string pZFileName = Path.GetFileName(pZipFileName);

                foreach (FileInfo fiTemp in pTarget.GetFiles())
                {
                    if (pZFileName == fiTemp.ToString()) continue;   // 자신은 압축에서 제외
                    
                    if (pOnlyFileName.Trim() != "")
                    {
                        if (pOnlyFileName != fiTemp.ToString()) continue;   // 지정 파일이 아닌경우 제외
                    }

                    ICSharpCode.SharpZipLib.Zip.ZipEntry theEntry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(pDescFolder + fiTemp.Name);

                    // Registration to Zip Entry (zip 엔트리에 등록)
                    pZip.PutNextEntry(theEntry);

                    // Get stream of file (파일의 스트림을 가져와서)
                    using (fsTargetFile = fiTemp.OpenRead())
                    {
                        // Read all and input into Zip stream as it is. (모두 읽어서 Zip 스트림에다가 그데로 넣어준다.)
                        while (true)
                        {
                            size = fsTargetFile.Read(buffer, 0, 2048);
                            if (size == 0)
                                break;

                            pZip.Write(buffer, 0, size);
                        }
                    }

                    // Entry Close (엔트리 닫기.)
                    pZip.CloseEntry();

                    if (pOnlyFileName.Trim() != "")
                    {
                        if (pOnlyFileName == fiTemp.ToString()) break;   // 지정 파일만 압축하고 Skip
                    }
                }
                bRet = true;

                foreach (DirectoryInfo diTemp in pTarget.GetDirectories())
                {
                    ICSharpCode.SharpZipLib.Zip.ZipEntry theEntry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(pDescFolder + diTemp.Name + "\\");

                    // Registration on Zip Entry (zip 엔트리에 등록)
                    pZip.PutNextEntry(theEntry);

                    bRet = ZipDirectoryFile(diTemp, pDescFolder + diTemp.Name + "\\", pZipFileName, pOnlyFileName, pZip);

                    if (bRet != true) return bRet;
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
                bRet = false;
            }
            return bRet;
        }

        /// <summary>
        /// 텍스트 파일 읽기
        /// </summary>
        /// <param name="sFileName"></param>
        /// <returns></returns>
        public static string ReadTextFile(string sFileName)
        {
            return ReadTextFile(sFileName, System.Text.Encoding.Default);
        }
        public static string ReadTextFile(string sFileName, Encoding encoding)
        {
            string sReadData = "";
            try
            {
                if (File.Exists(sFileName) == false) return "";

                using (StreamReader sr = new StreamReader(sFileName, encoding))
                {
                    sr.BaseStream.Seek(0, SeekOrigin.Begin);
                    
                    sReadData = sr.ReadToEnd();
                    
                    sr.Close();
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return sReadData;
        }

        /// <summary>
        /// 텍스트 파일 쓰기
        /// </summary>
        /// <param name="sFileName"></param>
        /// <param name="sTextData"></param>
        /// <returns></returns>
        public static bool WriteTextFile(string sFileName, string sTextData)
        {
            return WriteTextFile(sFileName, sTextData, System.Text.Encoding.Default);
        }
        public static bool WriteTextFile(string sFileName, string sTextData, Encoding encoding)
        {
            try
            {
                //#20180322 휴게소pos매출연동 start,phj

                int iEndPos = 0;
                iEndPos = sFileName.LastIndexOf(@"\") + 1;
                // 해당 경로에 해당 하는 폴더가 없으면 만들어 줌 
                if (iEndPos > 0)
                {
                    string sRestAreaPosDir = string.Empty;
                    sRestAreaPosDir = sFileName.Substring(0, iEndPos);

                    if (Directory.Exists(sRestAreaPosDir) == false)
                    {
                        //DirectoryInfo di = new DirectoryInfo(sRestAreaPosDir);
                        //if (!di.Exists)
                        //{
                        //    di.Create();
                        //}
                        Directory.CreateDirectory(sRestAreaPosDir);
                    }

                }
                //#20180322 휴게소pos매출연동 end,phj

                using (StreamWriter sw = new StreamWriter(sFileName, false, encoding))
                {
                    sw.Write(sTextData);

                    sw.Close();

                    return true;
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return false;
        }

        /// <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)
        {
            ExecuteWaitProcess(sProcessName, arguments, System.Diagnostics.ProcessWindowStyle.Normal);
        }
        public static void ExecuteWaitProcess(string sProcessName, string arguments, System.Diagnostics.ProcessWindowStyle sWinSty, int millisecounds = 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 = sWinSty;
                prc.StartInfo = pcInfo;
                prc.Start();
                if (millisecounds <= 0)
                    prc.WaitForExit();
                else
                    prc.WaitForExit(millisecounds);
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
        }

        /// <summary>
        /// Execute process
        /// (프로세스를 실행)
        /// </summary>
        /// <param name="sProcessName"></param>
        /// <param name="arguments"></param>
        public static void ExecuteProcess(string sProcessName, string arguments)
        {
            ExecuteProcess(sProcessName, arguments, System.Diagnostics.ProcessWindowStyle.Normal);
        }
        public static void ExecuteProcess(string sProcessName, string arguments, System.Diagnostics.ProcessWindowStyle sWinSty)
        {
            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 = sWinSty;
                prc.StartInfo = pcInfo;
                prc.Start();
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
        }

        /// <summary>
        /// 해피포인트 앱카드 체크
        /// </summary>
        /// <param name="sCardNo"></param>
        /// <returns></returns>
        public static bool CheckHappyMobileCard(string sCardNo)
        {
            try
            {
                if ( sCardNo.Trim().Length != 17) return true;

                if ("=" == sCardNo.Substring(16, 1)) return true;

                int nSum = 0;
                for (int i = 1 ; i <= 16 ; i++)
                {
                    // 카드번호각자리에 2, 1을 반복적으로 곱해서 그합을 10으로 나눈 몫과 나머지를 더한 합 을 구한다
                    int nNum = 0;
                    if (i % 2 == 1) 
                        nNum = CmUtil.IntParse(sCardNo.Substring(i - 1, 1)) * 2;
                    else
                        nNum = CmUtil.IntParse(sCardNo.Substring(i - 1, 1)) * 1;

                    nSum += (int)(nNum / 10) + (int)(nNum % 10);
                }
                
                // 구한값에 10으로 나눈 몫과 나머지를 뺀다
                int nCheck = 10 - ( nSum % 10);
                switch (nCheck)
                {
                    case 1:
                        if ("#" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 2:
                        if (")" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 3:
                        if ("&" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 4:
                        if ("$" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 5:
                        if ("@" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 6:
                        if ("%" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 7:
                        if ("!" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 8:
                        if ("^" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 9:
                        if ("~" == sCardNo.Substring(16, 1)) return true;
                        break;
                    case 0:
                    case 10:
                        if ("(" == sCardNo.Substring(16, 1)) return true;
                        break;
                }
                return false;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return false;
        }

        /// <summary>
        /// Text To Speech
        /// </summary>
        /// <param name="sCountryCd"></param>
        /// <param name="sScript"></param>
        /// <param name="iVoulume"></param>
        public static void SpeakByTTSEngine(string sCountryCd, string sScript, int iVoulume)
        {
            try
            {
                string sVoiceName;
                if (sCountryCd == "en-US")
                {
                    sVoiceName = PosConst.TTS_VOICE_NAME.VOICE_en_US;
                }
                if (sCountryCd == "ja-JP")
                {
                    sVoiceName = PosConst.TTS_VOICE_NAME.VOICE_ja_JP;
                }
                if (sCountryCd == "zh-CN")
                {
                    sVoiceName = PosConst.TTS_VOICE_NAME.VOICE_zh_CN;
                }
                else
                {
                    sVoiceName = PosConst.TTS_VOICE_NAME.VOICE_ko_KR;
                }

                SpeakByTTS cTTS = new SpeakByTTS();
                cTTS.sVoiceName = sVoiceName;
                cTTS.sVoiceStr = sScript;
                cTTS.iVoulume = iVoulume;

                Thread t = new Thread(new ThreadStart(cTTS.DoWork));
                t.Start();
                
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                     ex.Message);
            }
        }

        /// <summary>
        /// 인터넷 연결 체크
        /// </summary>
        /// <param name="dwFlags"></param>
        /// <returns></returns>
        public static int IsNetConnection()
        {

            int iRet = 1;
            int dwFlags = 0x02;

            try
            {
                // 0은 접속안됨, 1은 접속됨
                iRet = IsNetworkAlive(ref dwFlags);
            }
            catch (Exception ex)
            {

                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }

            return iRet;
        }


        /// <summary>
        /// 색상코드값으로 해당 색상 리턴
        /// </summary>
        /// <param name="sColorCode"></param>
        /// <returns></returns>
        public static Color GetRainbowColor(string sColorCode)
        {

            Color clrRetColor = Color.White;

            try
            {
                switch (sColorCode)
                {
                    case "0":
                    case "1":
                        clrRetColor = Color.Red;
                        break;
                    case "2":
                        clrRetColor = Color.Orange;
                        break;
                    case "3":
                        clrRetColor = Color.Yellow;
                        break;
                    case "4":
                        clrRetColor = Color.Green;
                        break;
                    case "5":
                        clrRetColor = Color.Blue;
                        break;
                    case "6":
                        clrRetColor = Color.Indigo;
                        break;
                    case "7":
                        clrRetColor = Color.Purple;
                        break;
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }

            return clrRetColor;
        }

        /// <summary>
        /// 화면 활성화시 초기 마우스 클릭 무시 처리
        /// </summary>
        /// <param name="frmForm"></param>
        public static void IgnoreMouseClick(Form frmForm)
        {
            try
            {
                Control cActive = frmForm.ActiveControl;        // 활성컨트롤

                Point nPoint = System.Windows.Forms.Cursor.Position;
                Cursor.Clip = new System.Drawing.Rectangle(1024, 0, 1, 1);

                frmForm.Update();
                System.Threading.Thread.Sleep(50);
                frmForm.Update();
                System.Threading.Thread.Sleep(50);
                frmForm.Update();
                System.Threading.Thread.Sleep(50);
                frmForm.Update();
                System.Threading.Thread.Sleep(50);
                frmForm.Update();
                System.Threading.Thread.Sleep(50);
                frmForm.Update();

                Cursor.Clip = Screen.PrimaryScreen.Bounds;
                Cursor.Position = nPoint;

                if (cActive != null && cActive != frmForm.ActiveControl) cActive.Focus();
            }
            catch { }
        }

        /// <summary>
        /// 지정한 일자의 로그파일을 압축파일로 백업 처리
        /// </summary>
        /// <param name="sSrcPath"></param>
        /// <param name="dtDelDate"></param>
        /// <returns></returns>
        public static bool BackUpLogToZipFile(string sSrcPath, DateTime dtDelDate)
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(sSrcPath);
                if (di.Exists == false) return false;

                string sLogBackPath = di.Name + dtDelDate.ToString("yyyyMMdd");
                if (File.Exists(sSrcPath + sLogBackPath + ".zip")) return true;

                try
                {
                    Directory.CreateDirectory(sSrcPath + sLogBackPath);
                }
                catch { }

                bool bFileExist = false;
                foreach (FileInfo fi in di.GetFiles())
                {
                    int Index = 0;
                    Index = fi.Name.IndexOf(dtDelDate.ToString("yyyyMMdd").Substring(2, 6));
                 //   if (fi.LastAccessTime.ToString("yyyyMMdd") == dtDelDate.ToString("yyyyMMdd"))
                    if(Index > 0)
                    {
                        if (fi.Extension.ToUpper() == "ZIP") continue;
                        try
                        {
                            fi.MoveTo(sSrcPath + sLogBackPath + @"\" + fi.Name);
                            bFileExist = true;
                        }
                        catch { }
                    }
                }

                if (bFileExist == true)
                {
                    if (ZipFile(sSrcPath + sLogBackPath, sSrcPath + sLogBackPath + ".zip") == true)
                    {
                        DeleteDirectoryInFile(sSrcPath + sLogBackPath, 2);
                        Directory.Delete(sSrcPath + sLogBackPath);
                    }
                }
                else
                {
                    Directory.Delete(sSrcPath + sLogBackPath);
                }
                return true;
            }
            catch { }

            return false;
        }

        /// <summary>
        /// 로그 저장 데이터 생성(카드번호 마스킹 처리)
        /// </summary>
        /// <param name="bIcUseYn"></param>
        /// <param name="sMaskData"></param>
        /// <param name="sWriteData"></param>
        /// <returns></returns>
        public static string MakeLogDataToMask(bool bIcUseYn, string sMaskData, string sLogData)
        {
            try
            {
                if (bIcUseYn == false)
                {
                    if (sMaskData.Length > 6)
                    {
                        string sReplaceData = sMaskData.Substring(0, 6).PadRight(sMaskData.Length, '*');

                        return sLogData.Replace(sMaskData, sReplaceData);
                    }
                }
            }
            catch { }

            return sLogData;
        }
    }

    /// <summary>
    /// TTS 처리 클레스
    /// </summary>
    class SpeakByTTS
    {
        /// <summary>
        /// 언어
        /// </summary>
        public string sVoiceName;
        /// <summary>
        /// 출력데이터
        /// </summary>
        public string sVoiceStr;
        /// <summary>
        /// 볼륨
        /// </summary>
        public int iVoulume;
        public void DoWork()
        {
            try
            {
                using (SpeechSynthesizer tts = new SpeechSynthesizer())
                {
                    tts.SelectVoice(sVoiceName);
                    tts.SetOutputToDefaultAudioDevice();
                    tts.Volume = iVoulume > 100 ? 100 : iVoulume;

                    tts.Speak(sVoiceStr);
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
        }

    }
}
