using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;


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

namespace Cosmos.Win
{
    public partial class frmICReaderUpdate : Form
    {
        #region 변수 선언
        private IICReaderUs m_cDeviceICReader = null;                                // IC 리더기
        private IICReaderUpdate m_ICReaderUpdate = null;                               // IC 리더기 업데이트
        private StateServer StateObject = (StateServer)StateServer.GetInstance();    //StateObject : StateServer Object(객체)
        private SManager sManager = new SManager();                                  // 이 객체를 통해 업무 Service 호출
        private PosStatus m_cPosStatus = new PosStatus();                            // 기본정보 참조
        private PosOLEDevice.CallbackRegFunc delegateCallback;

        /// <summary>
        /// Device 상태 정보 객체
        /// </summary>
        public DeviceStatus m_cDevStatus = null;

        private int nUpdateCnt = 0;

        private string sWorkBizMsg = "";

        private string sSetFirmUpdateFile = string.Empty;     // 펌웨어 업데이트 파일

        private string ICREADER_FIRMWARE_GROUP = PosConst.PGM_UPDATE_TYPE.POSDOWN_GROUP_70;
        private string ICREADER_FIRMWARE_PATH = BaseCom.NxDownPath + @"ICREADER\";

        private DataTable m_DataTable = new DataTable();
        /// <summary>
        /// 처리대상 정보
        /// </summary>
        public DataTable SetDataTable { set { this.m_DataTable = value; } get { return m_DataTable; } }            

        #endregion 변수 선언

        #region 생성자 & 소멸자
        public frmICReaderUpdate()
        {
            InitializeComponent();

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

            m_cPosStatus = (PosStatus)StateObject.POS;      // POS 기본정보
            m_cDeviceICReader = (IICReaderUs)sManager.InitServiceInstance(ServiceLists.AGENT_OLEDEVICE.DLL, ServiceLists.AGENT_OLEDEVICE.DEVICE_ICREADER);
            m_ICReaderUpdate = (IICReaderUpdate)sManager.InitServiceInstance(ServiceLists.BSV_BASIC.DLL, ServiceLists.BSV_BASIC.ICREADER_UPDATE);
            m_cDevStatus = (DeviceStatus)StateObject.DEVICE;
            delegateCallback = new PosOLEDevice.CallbackRegFunc(SetProgreeBar);
        }

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

        private void frmICReaderUpdate_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 + "()", lblTitle.Text);
        }
        #endregion 생성자 & 소멸자

        #region 폼 컨트롤 초기화
        /// <summary>
        /// 폼 컨트롤 초기화
        /// </summary>
        private void InitControl()
        {
            try
            {
                #region 변수 초기화
                nUpdateCnt = 0;
                sWorkBizMsg = "";
                lblCount.Text = "";
                pbWork.Minimum = 0;
                pbWork.Maximum = 100;

                pbWork.Visible = false;

                btnConfirm.Tag = "0";
                #endregion 변수 초기화

                FormManager.SetFormAllControlFont(this, m_cPosStatus.Base.FONT);
                FormManager.SetTextBoxGlobalInfo(this, m_cPosStatus.Global.m_stCultureMaster.nGroupingDigits, m_cPosStatus.Global.m_stCultureMaster.strGroupingSymbol
                    , m_cPosStatus.Global.m_stCultureMaster.nDecimalDigits, m_cPosStatus.Global.m_stCultureMaster.strDecimalSymbol);
                FormManager.MovePopUpForm(this, false, m_cPosStatus.Sale.ScreenSizeUser);

                picBack.Image = ImageManager.GetImage(Cosmos.BaseFrame.BaseCom.NxImgPath, ImageManager.POP_SIZE_S);

                lblMessage.Text = MessageManager.GetErrorMessage(POS_MESSAGE.ERROR.MSG_0702);      

                btnYes.Text = MessageManager.GetLabelMessage(POS_MESSAGE.LABEL.MSG_0025);
                btnNo.Text = MessageManager.GetLabelMessage(POS_MESSAGE.LABEL.MSG_0026);
                btnConfirm.Text = MessageManager.GetLabelMessage(POS_MESSAGE.LABEL.MSG_0009);

                btnYes.Visible = true;
                btnNo.Visible = true;
                btnConfirm.Visible = false;

                this.TopMost = true;

                nUpdateCnt = m_ICReaderUpdate.ICReaderUpdateCnt(ICREADER_FIRMWARE_PATH, ref sSetFirmUpdateFile);
                   
                if (nUpdateCnt == 0)
                {
                    WinManager.ErrorMessage(MessageManager.GetErrorMessage(POS_MESSAGE.ERROR.MSG_0703));   
                    this.Close();
                    return;
                }

            }
            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 + "()", "Process Exception !!! " + ex.Message);
            }
        }
        #endregion 폼 컨트롤 초기화

        #region Control Event
        private void btnYes_Click(object sender, EventArgs e)
        {
            int iRet = -99;   
            string sFilePath = ICREADER_FIRMWARE_PATH + sSetFirmUpdateFile;
            string sErrorMsg = string.Empty;
     
            try
            {
                pbWork.Visible = true;
                btnYes.Visible = false;
                btnNo.Visible = false;

                // 펌웨어
                if (File.Exists(sFilePath) == true)
                {
                    lblMessage.Text = MessageManager.GetErrorMessage(POS_MESSAGE.ERROR.MSG_0672);
                    sWorkBizMsg = MessageManager.GetErrorMessage(POS_MESSAGE.ERROR.MSG_0672) + "...{0} %";

                    this.Update();

                    string sPort = m_cPosStatus.Base.OlePosICReaderSerialPortNumber.Replace("COM", "");

                    GCHandle gch = GCHandle.Alloc(delegateCallback);
                    IntPtr intptr_delegate = Marshal.GetFunctionPointerForDelegate(delegateCallback);

                    iRet = m_cDeviceICReader.SetDE_FWDOWN(Convert.ToInt16(sPort), Convert.ToInt32(m_cPosStatus.Base.OlePosICReaderSerialBaudRate), Encoding.UTF8.GetBytes(sFilePath), intptr_delegate);

                    gch.Free();

                    if (iRet == 0)
                    {
                        // 성공
                        UpdateResult(iRet, true);

                        // 1초 후 자동 닫히기
                        System.Threading.Thread.Sleep(1000);

                        btnConfirm_Click(btnYes, null);
                    }
                    else
                    {
                        // 실패
                        UpdateResult(iRet, false);
                    }
                }
                else
                {
                    UpdateResult(-6, false); // -6 : 전송 할 파일 없음
                }
            }
            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);
                this.Close();
            }
        }

        private void btnNo_Click(object sender, EventArgs e)
        {
            UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name
                                 , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                                 , "ICREADER FW => 업데이트 취소");
            
            // 처리 상태 저장
            SetDataState(ICREADER_FIRMWARE_GROUP, false);

            // 펌웨어 파일 삭제
            DeleteFile();

            btnConfirm_Click(btnNo, null);
        }

        private void btnConfirm_Click(object sender, EventArgs e)
        {
            if ((string)btnConfirm.Tag != "1")
            {
                this.DialogResult = DialogResult.Cancel;
            }
            else
            {
                this.DialogResult = DialogResult.OK;
            }

            this.Close();
        }
        #endregion Control Event

        #region User Method
        /// <summary>
        /// 상태 진행바
        /// </summary>
        /// <param name="iValue"></param>
        /// <param name="iMaxValue"></param>
        private void SetProgreeBar(int iValue, int iMaxValue)
        {
            try
            {
                double nPercent = CmUtil.DoubleMultiplication(CmUtil.DoubleDivision(iValue, iMaxValue), 100);

                pbWork.Visible = true;
                pbWork.Minimum = 0;
                pbWork.Maximum = 100;
                pbWork.Value = (int)Math.Round(nPercent, 0, MidpointRounding.AwayFromZero);
                pbWork.Update();

                lblCount.Visible = true;
                lblCount.Text = string.Format(sWorkBizMsg, Math.Round(nPercent, 0, MidpointRounding.AwayFromZero).ToString());
                lblCount.Update();

                if (iValue == iMaxValue)
                {
                    System.Threading.Thread.Sleep(300);
                }

                Application.DoEvents();
            }
            catch (Exception ex)
            {
                WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
        }

        private void UpdateResult(int iRet, bool bRetFlag)
        {
            string sErrorMsg = string.Empty;

            try
            {
                // 메세지 표시 및 컨트롤 visible 처리
                if (bRetFlag)
                {
                    lblMessage.Text = MessageManager.GetErrorMessage(POS_MESSAGE.ERROR.MSG_0704);

                    btnConfirm.Tag = "1";
                }
                else
                {
                    sErrorMsg = m_ICReaderUpdate.ICReaderResultCode(iRet);
                    lblMessage.Text = MessageManager.GetErrorMessage(sErrorMsg);

                    lblCount.Visible = false;
                    pbWork.Visible = false;
                    btnConfirm.Visible = true;
                }

                this.Update();

                // 처리 상태 저장
                SetDataState(ICREADER_FIRMWARE_GROUP, bRetFlag);

                DeleteFile();
            }
            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);
            }
        }

        private void DeleteFile()
        {
            try
            {
                //DirectoryInfo dir = new DirectoryInfo(ICREADER_FIRMWARE_PATH);
                //dir.Delete(true);
                CmUtil.DeleteDirectoryInFile(ICREADER_FIRMWARE_PATH, 2);

                return;

            }
            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);
            }
        }
        #endregion User Method

        #region 처리 상태 저장
        private void SetDataState(string sGroup, bool bState)
        {
            try
            {
                foreach (DataRow dr in m_DataTable.Rows)
                {
                    string sGroupCheck = CmUtil.MidH(dr["KIND"].ToString(), 0, 2).Trim();
                    if (sGroupCheck == sGroup)  
                    {
                        dr["APP_TYPE"] = (bState == true) ? ItemConst.PGM_DOWN_STATE.Update_OK : ItemConst.PGM_DOWN_STATE.Update_Fail;
                        break;
                    }
                }

            }
            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);
            }
        }
        #endregion 처리 상태 저장
    }
}
