using System;
using System.Windows.Forms;
using System.Threading;
using System.Collections;
using System.Reflection;
using System.Text;

using Cosmos.BaseFrame;
using Cosmos.UserFrame;
using Cosmos.ServiceProvider;
using Cosmos.Common;
using Cosmos.CommonManager;

/*-----------------------------------------------------------------------------------------------*/
// 설      명 : TCP 클라이언트 통신 처리
// 작  성  자 : 
// 변경  이력 : 
/*-----------------------------------------------------------------------------------------------*/
namespace Cosmos.Service
{
    public partial class frmTcpClientMsg : Form
    {
        private SManager sManager = new SManager(); // 이 객체를 통해 업무 Service 호출

        private bool m_bSecondDisp = false;         // 초 표시여부
        private int m_nSecondCount = 0;             // 초(경과)

        string m_sMessageStr;
        /// <summary>
        /// 화면표시 메시지
        /// </summary>
        public string MessageStr
        {
            get { return this.m_sMessageStr; }
            set
            {
                this.m_sMessageStr = value;
                try
                {
                    lblMessage.Text = m_sMessageStr;
                }
                catch { }
            }
        }

        string m_sServerIp;
        /// <summary>
        /// 서버IP
        /// </summary>
        public string ServerIp
        {
            get { return this.m_sServerIp; }
            set { this.m_sServerIp = value; }
        }

        int m_nServerPort;
        /// <summary>
        /// 서버PORT
        /// </summary>
        public int ServerPort
        {
            get { return this.m_nServerPort; }
            set { this.m_nServerPort = value; }
        }

        int m_nTimeOut;
        /// <summary>
        /// 서버 Timeout
        /// </summary>
        public int TimeOut
        {
            get { return this.m_nTimeOut; }
            set { this.m_nTimeOut = value; }
        }

        // Byte 통신 전송값
        byte[] m_bytSendByteData;
        public byte[] SendByteData
        {
            get { return this.m_bytSendByteData; }
            set { this.m_bytSendByteData = value; }
        }

        // Byte 통신 응답값
        byte[] m_bytRecvByteData;
        public byte[] RecvByteData
        {
            get { return this.m_bytRecvByteData; }
            set { this.m_bytRecvByteData = value; }
        }

        int m_nRecvDataLen;
        /// <summary>
        /// 수신리턴 길이
        /// </summary>
        public int RecvDataLen
        {
            get { return this.m_nRecvDataLen; }
            set { this.m_nRecvDataLen = value; }
        }

        // 송수신 처리 실행 함수
        string m_sExecFunction;
        public string ExecFunction
        {
            get { return this.m_sExecFunction; }
            set { this.m_sExecFunction = value; }
        }

        // 송수신 처리 성공 여부
        bool m_bResultFlag;
        public bool ResultFlag
        {
            get { return this.m_bResultFlag; }
            set { this.m_bResultFlag = value; }
        }

        /// <summary>
        /// SOCKET
        /// </summary>
        private TcpSocketClient m_tcpClient = new TcpSocketClient();

        /// <summary>
        /// 생성자
        /// </summary>
        public frmTcpClientMsg()
        {
            InitializeComponent();

            base.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw, true);
            //this.UpdateStyles();
        }

        private void frmTcpClientMsg_Load(object sender, EventArgs e)
        {
            try
            {
                UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", "");

                CmMessage m_PosConfig = CmMessage.MakeMessageFromFile(BaseCom.NxIniPath + "PosConfig.INI");
                string sFont = m_PosConfig.GetMessage("GLOBAL").GetMessageValue("Font");
                FormManager.SetFormAllControlFont(this, sFont);
                long nScreenSizeUser = CmUtil.LongParse(m_PosConfig.GetMessage("GLOBAL").GetMessageValue("ScreenSizeUser"));
                FormManager.MovePopUpForm(this, false, nScreenSizeUser);

                picSearchMessage.Image = ImageManager.GetImage(BaseCom.NxImgPath, ImageManager.SCH_MESSAGE_BOX);
                if (m_sMessageStr != "") lblMessage.Text = m_sMessageStr;

                this.TopMost = true;

                tmrStart.Enabled = true;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.ERROR_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                    "Process Exception !!! " + ex.Message);
            }
        }

        private void frmTcpClientMsg_FormClosing(object sender, FormClosingEventArgs e)
        {
            UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", "");
        }

        private void tmrStart_Tick(object sender, EventArgs e)
        {
            try
            {
                m_bResultFlag = false;

                tmrStart.Enabled = false;

                m_bSecondDisp = true;
                m_nSecondCount = 0;

                Thread thrSecondDisp = new Thread(new ThreadStart(OnNetworkIRT));
                thrSecondDisp.Start();

                OnSecondDisplay();
            }
            catch(Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.ERROR_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                    "Process Exception !!! " + ex.Message);
            }
            finally
            {
                this.Close();
            }
        }

        private void OnSecondDisplay()
        {
            try
            {
                while(m_bSecondDisp == true)
                {
                    m_nSecondCount++;
                    if(m_nSecondCount % 10 == 0)
                    {
                        lblMessage.Text = m_sMessageStr + " (" + (int)(m_nSecondCount / 10) + ")";
                        lblMessage.Update();
                    }
                    Thread.Sleep(100);
                }
            }
            catch(Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.ERROR_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                    "Process Exception !!! " + ex.Message);
            }
        }

        /// <summary>
        /// TCP 클라이언트 실행
        /// </summary>
        private void OnNetworkIRT()
        {
            try
            {
                m_bSecondDisp = true;
                
                // 대상 함수 획득
                Type type = typeof(frmTcpClientMsg);
                MethodInfo method = type.GetMethod(m_sExecFunction);

                // 데이터 송수신 처리
                ResultFlag = (bool)method.Invoke(this, new object[] { });
            }
            catch(Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.ERROR_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", "Exception !!! " + ex.Message);
            }
            finally
            {
                m_bSecondDisp = false;
            }
        }

        /// <summary>
        /// 온라인쿠폰(중국) TCP 전문 송수신 처리
        /// </summary>
        /// <returns></returns>
        public bool ExecuteOnLineCoupon()
        {
            try
            {
                // 소캣 접속 처리
                if (m_tcpClient.Connect(m_sServerIp, m_nServerPort) != UserCom.OK)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.WARNING_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        string.Format("SOCKET Connect Fail : {0},{1}", m_sServerIp, m_nServerPort));
                    return false;
                }

                // 데이터 송신 처리
                if (m_tcpClient.SendData(m_bytSendByteData) != UserCom.OK)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.WARNING_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        string.Format("SOCKET Send Fail : {0},{1}", m_sServerIp, m_nServerPort));
                    return false;
                }

                // 데이터 수신 처리
                byte[] byteRecv = new byte[4096];
                int nRecvLen = m_tcpClient.RecvProcEndToETX(ref byteRecv, m_nTimeOut);
                if (nRecvLen <= 0)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.WARNING_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        string.Format("SOCKET Recv Fail : {0},{1}", m_sServerIp, m_nServerPort));
                    return false;
                }

                m_nRecvDataLen = nRecvLen;          // 수신데이터 길이
                m_bytRecvByteData = byteRecv;       // 수신데이터

                // ACK 데이터 송신
                byte[] byteAck = new byte[3];
                byteAck[0] = 0x02;      // STX
                byteAck[1] = 0x06;      // ACK
                byteAck[2] = 0x03;      // ETX
                if (m_tcpClient.SendData(byteAck) != UserCom.OK)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.WARNING_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        string.Format("SOCKET Ack Send Fail : {0},{1}", m_sServerIp, m_nServerPort));

                    m_bResultFlag = false;      // 실패
                }
                else
                {
                    m_bResultFlag = 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);
            }
            finally
            {
                m_tcpClient.Close();
            }
            return m_bResultFlag;
        }

        /// <summary>
        /// 직원할인(중국) TCP 전문 송수신 처리
        /// </summary>
        /// <returns></returns>
        public bool ExecuteEmployeeChina()
        {
            try
            {
                // 소캣 접속 처리
                if (m_tcpClient.Connect(m_sServerIp, m_nServerPort) != UserCom.OK)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.WARNING_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        string.Format("SOCKET Connect Fail : {0},{1}", m_sServerIp, m_nServerPort));
                    return false;
                }

                // 데이터 송신 처리
                if (m_tcpClient.SendData(m_bytSendByteData) != UserCom.OK)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.WARNING_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        string.Format("SOCKET Send Fail : {0},{1}", m_sServerIp, m_nServerPort));
                    return false;
                }

                // 데이터 수신 처리
                byte[] byteRecv = new byte[4096];
                int nRecvLen = m_tcpClient.RecvProcEndToETX(ref byteRecv, m_nTimeOut);
                if (nRecvLen <= 0)
                {
                    UserLog.WriteLogFile(UserCom.LOG_ERROR, UserCom.WARNING_LEVEL, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                        string.Format("SOCKET Recv Fail : {0},{1}", m_sServerIp, m_nServerPort));
                    return false;
                }

                m_nRecvDataLen = nRecvLen;          // 수신데이터 길이
                m_bytRecvByteData = byteRecv;       // 수신데이터
                m_bResultFlag = 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);
            }
            finally
            {
                m_tcpClient.Close();
            }
            return m_bResultFlag;
        }
    }
}
