using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Cosmos.Common;
using Cosmos.UserFrame;
using Cosmos.BaseFrame;

namespace Cosmos.KPS
{
    class LANPrint
    {
        PrinterCommand prtCmd = new PrinterCommand();

        private TcpSocket m_cKtchSocket = null;

        #region Printer OPEN / CLOSE
        public int OpenDevice(string sIp, int iPort)
        {
            int iRet = UserCom.NG;
            try
            {
                // PING 테스트로 프린터 가능여부 확인(2017.05.30)
                if (CmUtil.PingTest(sIp) == false)
                {
                    if (CmUtil.PingTest(sIp) == false) return iRet;
                }

                m_cKtchSocket = new TcpSocket(sIp, iPort, 5000);

                if(m_cKtchSocket == null)
                {
                    return -9;
                }

                // 주방프린터 접속 3회 시도
                for(int nLoop = 0;nLoop < 1;nLoop++)
                {
                    try
                    {
                        iRet = m_cKtchSocket.Connect(-1);
                    }
                    catch (Exception ex)
                    {
                        iRet = UserCom.NG;
                        UserLog.WriteLogFile(UserCom.LOG_IOS, 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 (함수명))
                                             "KPS Exception Error=" + ex.Message);
                        m_cKtchSocket.Close();
                        continue;
                    }
                    // 접속 실패
                    if (iRet != UserCom.OK)
                    {
                        iRet = UserCom.NG;
                        UserLog.WriteLogFile(UserCom.LOG_IOS, 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 (함수명))
                                             "KPS(Ethernet) Connect Error");
                        m_cKtchSocket.Close();
                        continue;
                    }
                    /*
                    // Cover Check
                    iRet = PrinterStatusCheckByLan("CHK1");
                    if (iRet != UserCom.OK)
                    {
                        iRet = UserCom.NG;
                        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 (함수명))
                                             "KPS(Ethernet) Cover Check Error");
                        m_cKtchSocket.Close();
                        continue;
                    }

                    // Paper Check
                    iRet = PrinterStatusCheckByLan("CHK2");
                    if (iRet != UserCom.OK)
                    {
                        iRet = UserCom.NG;
                        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 (함수명))
                                             "KPS(Ethernet) Paper Check Error");
                        m_cKtchSocket.Close();
                        continue;
                    }
                    */
                    break;
                }

                return iRet;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_IOS,
                                     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);
                return -99;
            }
        }

        public void CloseDevice()
        {
            try
            {
                if(m_cKtchSocket != null)
                {
                    m_cKtchSocket.Close();
                    m_cKtchSocket = null;
                }
            }
            catch(Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_IOS,
                                     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);
            }
        }
        #endregion

        #region Status Check
        public int PrinterStatusCheckByLan(string sType)
        {
            int iRet = 0;
            string sRet = string.Empty;

            byte[] recvData = null;

            try
            {
                #region Printer CHK1
                if (sType == "CHK1")
                {
                    iRet = m_cKtchSocket.SendReceiveFoodPrintData(PosConst.ESCP_COMMAND.TRANSMIT_OFFLINE_STATUS, ref recvData, 5000);

                    if (recvData != null)
                    {
                        if (recvData[0] == PosConst.ESCP_COMMAND.STATUS_OK[0])
                        {
                            iRet = UserCom.OK;
                        }
                        else
                        {
                            iRet = UserCom.NG;
                            UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                                 System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +               
                                                 System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                             
                                                 "COVER Opened");
                        }
                    }
                    return iRet;
                }
                #endregion

                #region Printer CHK2
                if (sType == "CHK2")
                {
                    iRet = m_cKtchSocket.SendReceiveFoodPrintData(PosConst.ESCP_COMMAND.TRANSMIT_CONTINUOUS_PAPER_DETECTOR_STATUS, ref recvData, 5000);

                    if (recvData != null)
                    {
                        if (recvData[0] == PosConst.ESCP_COMMAND.STATUS_OK[0])
                        {
                            iRet = UserCom.OK;
                        }
                        else
                        {
                            iRet = UserCom.NG;
                            string sRecvData = Encoding.Default.GetString(recvData);

                            string NEAR_END = Encoding.Default.GetString(new byte[] { 0x1E });
                            string NOT_PRESENT = Encoding.Default.GetString(new byte[] { 0x72 });

                            string sErrMsg = string.Empty;
                            if (sRecvData == NEAR_END)
                            {
                                iRet = UserCom.OK;
                                sErrMsg = "PAPER_NEAR_END";
                            }
                            else if (sRecvData == NOT_PRESENT) sErrMsg = "PAPER_NOT_PRESENT";
                            else sErrMsg = "ETC_ERROR";

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

                    return iRet;
                }
                #endregion
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +             
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                           
                                     "StatusCheck Failed");
            }
            return iRet;
        }
        #endregion

        #region Cut Paper
        public bool CutPaper(int LineFeedCnt)
        {
            long nRet = -1;
            try
            {
                for(int i = 0;i < LineFeedCnt;i++)
                {
                    nRet = m_cKtchSocket.SendFoodPrintData(Encoding.Default.GetBytes("\r\n"));
                }

                if(m_cKtchSocket.SendFoodPrintData(PosConst.ESCP_COMMAND.PAPER_CUT) == BaseCom.OK)
                {
                    nRet = m_cKtchSocket.SendFoodPrintData(Encoding.Default.GetBytes("\r\n"));
                }

                // BEEP 커맨더 전송(2017.05.30)
                byte[] bytBEEP = new byte[] { 0x1B, 0x70, 0x01, 0x20, 0x80 };
                m_cKtchSocket.SendFoodPrintData(bytBEEP);
            }
            catch(Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_IOS,
                                     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 (함수명))
                                     "Cut Paper Exception");
            }
            return nRet == BaseCom.OK ? true : false;
        }
        #endregion

        #region 문자열 출력
        /// <summary>
        /// Print Text
        /// </summary>
        /// <param name="sValue"></param>
        /// <param name="eAlignment"></param>
        /// <param name="eVerticalSize"></param>
        /// <param name="eHorizontalSize"></param>
        /// <param name="eBold"></param>
        /// <param name="eTextUnderLine"></param>
        /// <param name="eTextReverseMode"></param>
        /// <param name="bLineFeed"></param>
        /// <returns></returns>
        public bool TextPrint(string sValue, PrinterCommand.Alignment eAlignment, PrinterCommand.CharactersizeV eVerticalSize, PrinterCommand.CharactersizeH eHorizontalSize, PrinterCommand.TextBold eBold, PrinterCommand.TextUnderLine eTextUnderLine, PrinterCommand.TextReverseMode eTextReverseMode, bool bLineFeed)
        {
            bool bRet = false;
            string sCmdctrlTmp = "";

            try
            {
                // 확대 Command를 설정
                sCmdctrlTmp = GetCharactersizeCmd(eVerticalSize, eHorizontalSize);

                // UnerLine
                sCmdctrlTmp += GetUnderLineCmd(eTextUnderLine);

                // Bold
                sCmdctrlTmp += GetBoldCmd(eBold);

                // 정렬
                sCmdctrlTmp += GetAlignment(eAlignment);

                // Reverse
                sCmdctrlTmp += GetReverseCmd(eTextReverseMode);

                // 출력
                byte[] byteCmdctrl = Encoding.Default.GetBytes(sCmdctrlTmp);
                if (m_cKtchSocket.SendFoodPrintData(byteCmdctrl) != BaseCom.OK) bRet = false;       // Command 전송

                byte[] byteData = Encoding.Default.GetBytes(sValue);
                if (m_cKtchSocket.SendFoodPrintData(byteData) != BaseCom.OK) bRet = false;          // 출력 Data 전송

                if (bLineFeed == true && m_cKtchSocket.SendFoodPrintData(Encoding.Default.GetBytes("\n")) != BaseCom.OK) bRet = false;
            }
            catch(Exception ex)
            {

            }

            return bRet;
        }
        /// <summary>
        /// Print Text
        /// </summary>
        /// <param name="sValue"></param>
        /// <param name="eAlignment"></param>
        /// <param name="eVerticalSize"></param>
        /// <param name="eHorizontalSize"></param>
        /// <param name="eBold"></param>
        /// <param name="eTextUnderLine"></param>
        /// <param name="bLineFeed"></param>
        /// <returns></returns>
        public bool TextPrint(string sValue, PrinterCommand.Alignment eAlignment, PrinterCommand.CharactersizeV eVerticalSize, PrinterCommand.CharactersizeH eHorizontalSize, PrinterCommand.TextBold eBold, PrinterCommand.TextUnderLine eTextUnderLine, bool bLineFeed)
        {
            return TextPrint(sValue, eAlignment, eVerticalSize, eHorizontalSize, eBold, eTextUnderLine, PrinterCommand.TextReverseMode.Nomal, bLineFeed);
        }
        /// <summary>
        /// Print Text
        /// </summary>
        /// <param name="sValue"></param>
        /// <param name="bLineFeed"></param>
        /// <returns></returns>
        public bool TextPrint(string sValue, bool bLineFeed)
        {
            return TextPrint(sValue, PrinterCommand.Alignment.Left, PrinterCommand.CharactersizeV.V_1, PrinterCommand.CharactersizeH.H_1, PrinterCommand.TextBold.Nomal, PrinterCommand.TextUnderLine.Nomal, PrinterCommand.TextReverseMode.Nomal, bLineFeed);
        }
        /// <summary>
        /// Print Text
        /// </summary>
        /// <param name="sValue"></param>
        /// <param name="eAlignment"></param>
        /// <param name="bLineFeed"></param>
        /// <returns></returns>
        public bool TextPrint(string sValue, PrinterCommand.Alignment eAlignment, bool bLineFeed)
        {
            return TextPrint(sValue, eAlignment, PrinterCommand.CharactersizeV.V_1, PrinterCommand.CharactersizeH.H_1, PrinterCommand.TextBold.Nomal, PrinterCommand.TextUnderLine.Nomal, PrinterCommand.TextReverseMode.Nomal, bLineFeed);
        }
        /// <summary>
        /// Print Text
        /// </summary>
        /// <param name="sValue"></param>
        /// <param name="eAlignment"></param>
        /// <param name="eVerticalSize"></param>
        /// <param name="eHorizontalSize"></param>
        /// <param name="bLineFeed"></param>
        /// <returns></returns>
        public bool TextPrint(string sValue, PrinterCommand.Alignment eAlignment, PrinterCommand.CharactersizeV eVerticalSize, PrinterCommand.CharactersizeH eHorizontalSize, bool bLineFeed)
        {
            return TextPrint(sValue, eAlignment, eVerticalSize, eHorizontalSize, PrinterCommand.TextBold.Nomal, PrinterCommand.TextUnderLine.Nomal, PrinterCommand.TextReverseMode.Nomal, bLineFeed);
        }
        /// <summary>
        /// Print Text
        /// </summary>
        /// <param name="sValue"></param>
        /// <param name="eAlignment"></param>
        /// <param name="eBold"></param>
        /// <param name="bLineFeed"></param>
        /// <returns></returns>
        public bool TextPrint(string sValue, PrinterCommand.Alignment eAlignment, PrinterCommand.TextBold eBold, bool bLineFeed)
        {
            return TextPrint(sValue, eAlignment, PrinterCommand.CharactersizeV.V_1, PrinterCommand.CharactersizeH.H_1, eBold, PrinterCommand.TextUnderLine.Nomal, PrinterCommand.TextReverseMode.Nomal, bLineFeed);
        }
        /// <summary>
        /// Print Text
        /// </summary>
        /// <param name="sValue"></param>
        /// <param name="eAlignment"></param>
        /// <param name="eTextUnderLine"></param>
        /// <param name="bLineFeed"></param>
        /// <returns></returns>
        public bool TextPrint(string sValue, PrinterCommand.Alignment eAlignment, PrinterCommand.TextUnderLine eTextUnderLine, bool bLineFeed)
        {
            return TextPrint(sValue, eAlignment, PrinterCommand.CharactersizeV.V_1, PrinterCommand.CharactersizeH.H_1, PrinterCommand.TextBold.Nomal, eTextUnderLine, PrinterCommand.TextReverseMode.Nomal, bLineFeed);
        }
        /// <summary>
        /// Print Text
        /// </summary>
        /// <param name="sValue"></param>
        /// <param name="eAlignment"></param>
        /// <param name="eTextReverseMode"></param>
        /// <param name="bLineFeed"></param>
        /// <returns></returns>
        public bool TextPrint(string sValue, PrinterCommand.Alignment eAlignment, PrinterCommand.TextReverseMode eTextReverseMode, bool bLineFeed)
        {
            return TextPrint(sValue, PrinterCommand.Alignment.Left, PrinterCommand.CharactersizeV.V_1, PrinterCommand.CharactersizeH.H_1, PrinterCommand.TextBold.Nomal, PrinterCommand.TextUnderLine.Nomal, eTextReverseMode, bLineFeed);
        }

        private string GetCharactersizeCmd(PrinterCommand.CharactersizeV eVerticalSize, PrinterCommand.CharactersizeH eHorizontalSize)
        {
            string sRet = "";

            try
            {
                int Hvalue = 0;
                int Vvalue = 0;

                switch(eVerticalSize)
                {
                    case PrinterCommand.CharactersizeV.V_1: Vvalue = 0; break;
                    case PrinterCommand.CharactersizeV.V_2: Vvalue = 1; break;
                    case PrinterCommand.CharactersizeV.V_3: Vvalue = 2; break;
                    case PrinterCommand.CharactersizeV.V_4: Vvalue = 3; break;
                    case PrinterCommand.CharactersizeV.V_5: Vvalue = 4; break;
                    case PrinterCommand.CharactersizeV.V_6: Vvalue = 5; break;
                    case PrinterCommand.CharactersizeV.V_7: Vvalue = 6; break;
                    case PrinterCommand.CharactersizeV.V_8: Vvalue = 7; break;
                    default: Vvalue = 0; break;
                }

                switch(eHorizontalSize)
                {
                    case PrinterCommand.CharactersizeH.H_1: Hvalue = 16 * 0; break;
                    case PrinterCommand.CharactersizeH.H_2: Hvalue = 16 * 1; break;
                    case PrinterCommand.CharactersizeH.H_3: Hvalue = 16 * 2; break;
                    case PrinterCommand.CharactersizeH.H_4: Hvalue = 16 * 3; break;
                    case PrinterCommand.CharactersizeH.H_5: Hvalue = 16 * 4; break;
                    case PrinterCommand.CharactersizeH.H_6: Hvalue = 16 * 5; break;
                    case PrinterCommand.CharactersizeH.H_7: Hvalue = 16 * 6; break;
                    case PrinterCommand.CharactersizeH.H_8: Hvalue = 16 * 7; break;
                    default: Hvalue = 16 * 0; break;
                }
                sRet = Encoding.Default.GetString(prtCmd.ESC_VHMAG) + Convert.ToChar(Vvalue + Hvalue).ToString();
            }
            catch (Exception ex)
            {

            }

            return sRet;
        }
        /// <summary>
        /// 진한 문자(Bold)
        /// </summary>
        /// <param name="eBold"></param>
        /// <returns></returns>
        private string GetBoldCmd(PrinterCommand.TextBold eBold)
        {
            string sRet = "";
            try
            {
                switch(eBold)
                {
                    case PrinterCommand.TextBold.Nomal: sRet = Encoding.Default.GetString(prtCmd.ESC_BOLD_OFF); break;
                    case PrinterCommand.TextBold.Bold: sRet = Encoding.Default.GetString(prtCmd.ESC_BOLD_ON); break;
                    default: sRet = Encoding.Default.GetString(prtCmd.ESC_BOLD_OFF); break;
                }
            }
            catch (Exception ex)
            {

            }

            return sRet;
        }
        /// <summary>
        /// UnderLine
        /// </summary>
        /// <param name="eUnderLine"></param>
        /// <param name="nDot"></param>
        /// <returns></returns>
        private string GetUnderLineCmd(PrinterCommand.TextUnderLine eUnderLine, int nDot)
        {
            string sRet = "";
            try
            {
                if(eUnderLine == PrinterCommand.TextUnderLine.UnderLine)
                {
                    if(nDot == 2)
                    {
                        sRet = Encoding.Default.GetString(prtCmd.ESC_UNDERLINEON1DOT);
                    }
                    else
                    {
                        sRet = Encoding.Default.GetString(prtCmd.ESC_UNDERLINEON2DOT);
                    }
                }
                else
                {
                    sRet = Encoding.Default.GetString(prtCmd.ESC_UNDERLINEOFF);
                }
            }
            catch(Exception ex)
            {

            }

            return sRet;
        }
        /// <summary>
        /// UnderLine Text
        /// </summary>
        /// <param name="eUnderLine"></param>
        /// <returns></returns>
        private string GetUnderLineCmd(PrinterCommand.TextUnderLine eUnderLine)
        {
            return GetUnderLineCmd(eUnderLine, 1);
        }
        /// <summary>
        /// 반전 텍스트
        /// </summary>
        /// <param name="eTextReverseMode"></param>
        /// <returns></returns>
        private string GetReverseCmd(PrinterCommand.TextReverseMode eTextReverseMode)
        {
            string sRet = "";
            try
            {
                switch(eTextReverseMode)
                {
                    case PrinterCommand.TextReverseMode.ReverseMode: sRet = Encoding.Default.GetString(prtCmd.ESC_REVERSE_MODE_ON); break;
                    default: sRet = Encoding.Default.GetString(prtCmd.ESC_REVERSE_MODE_OFF); break;
                }
            }
            catch(Exception ex)
            {

            }

            return sRet;
        }
        /// <summary>
        /// 정렬 Command를 가져온다.
        /// </summary>
        /// <param name="eAlignment"></param>
        /// <returns></returns>
        private string GetAlignment(PrinterCommand.Alignment eAlignment)
        {
            string sRet = "";
            try
            {
                switch(eAlignment)
                {
                    case PrinterCommand.Alignment.Center:
                        sRet = Encoding.Default.GetString(prtCmd.ESC_CENTER);
                        break;
                    case PrinterCommand.Alignment.Right:
                        sRet = Encoding.Default.GetString(prtCmd.ESC_RIGHT);
                        break;
                    case PrinterCommand.Alignment.Left:
                    default:
                        sRet = Encoding.Default.GetString(prtCmd.ESC_LEFT);
                        break;
                }
            }
            catch (Exception ex)
            {

            }

            return sRet;
        }
        #endregion
    }
}
