using System;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
//using Microsoft.PointOfService;
using System.ComponentModel;

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

/*-----------------------------------------------------------------------------------------------*/
// 설      명 : Hand Scanner 제어
// 작  성  자 : 
// 변경  이력 : 
/*-----------------------------------------------------------------------------------------------*/
namespace Cosmos.OLEDevice
{
    public class DeviceScanner : IScannerUs
    {
        /// <summary>
        /// StateServer Object (StateServer 객체)
        /// </summary>
        public StateServer StateObject = (StateServer)StateServer.GetInstance();
        /// <summary>
        /// Device 상태 정보 객체
        /// </summary>
        public DeviceStatus devStatus = new DeviceStatus();

        ///// <summary>
        ///// Pos for .Net Scanner 객체
        ///// </summary>
        //private Scanner scanner = null;
        ///// <summary>
        ///// Pos for .Net의 Device 정보를 가져오기 위한 객체
        ///// </summary>
        //private PosExplorer posExplorer = null;

        private string m_sScanData = string.Empty;
        private string m_sScanDataLabel = string.Empty;
        private string m_sScanDataType = string.Empty;

        private BackgroundWorker bw = null;

        private int m_nErrorCount = 0;
        /// <summary>
        /// 생성자
        /// </summary>
        public DeviceScanner()
        {
            try
            {
                //posExplorer = new PosExplorer();
                devStatus = (DeviceStatus)StateObject.DEVICE;
                DeviceStatusInit();
                bw = new BackgroundWorker();

                m_nErrorCount = 0;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "DevicePosPrinter.Devicescanner()", ex.Message);
            }
        }

        /// <summary>
        /// 디바이스 Open시 처리함수
        /// </summary>
        /// <param name="sDeviceType">장비종류(ex- "Msr","PosPrinter","Scanner"...)</param>
        /// <param name="sLogicalName">레지스트리 항목(ex- "DefaultMsr","DefaultPosPrinter","DefaultScanner"...)</param>
        /// <returns></returns>
        public bool OpenDevice(string sDeviceType, string sLogicalName)
        {
            bool bRet = false;

            try
            {
                //DeviceInfo devinfo = null;

                //if (sDeviceType == DeviceType.Scanner && sLogicalName == PosConst.OPOS_LDN.SCANNER)
                //    devinfo = posExplorer.GetDevice(DeviceType.Scanner, PosConst.OPOS_LDN.SCANNER);
                //else
                //{
                //    devStatus.Scanner.Open = false;
                //    devStatus.Scanner.Status = "DEVICE INFO ERROR";
                //    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                //                        "DeviceScanner.OpenDevice()", devStatus.Scanner.Status);
                //    return bRet;
                //}

                //if (devinfo == null)
                //{
                //    devStatus.Scanner.Open = false;
                //    devStatus.Scanner.Status = "DEVICE INFO ERROR";
                //    UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                //                        "DeviceScanner.OpenDevice()", devStatus.Scanner.Status);
                //    return bRet;
                //}

                //scanner = (Scanner)posExplorer.CreateInstance(devinfo);

                //if (scanner != null)
                //{
                //    scanner.DataEvent += new DataEventHandler(Scanner_DataEvent);
                //    scanner.ErrorEvent += new DeviceErrorEventHandler(Scanner_ErrorEvent);

                //    try
                //    {
                //        scanner.Open();
                //    }
                //    catch (Exception ex)
                //    {
                //        devStatus.Scanner.Status = "OPEN FAIL";
                //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                //                            "DeviceScanner.OpenDevice()", devStatus.Scanner.Status + " " + ex.Message);
                //        //UserLog.WriteAMSLog("DEV", "ERR", "0103", "GunScanner " + devStatus.Scanner.Status);

                //        return bRet;
                //    }


                //    try
                //    {
                //        scanner.Claim(1000);
                //    }
                //    catch (Exception ex)
                //    {
                //        devStatus.Scanner.Status = "CLAIM FAIL";
                //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                //                            "Devicescanner.OpenDevice()", devStatus.Scanner.Status + " " + ex.Message);
                //        //UserLog.WriteAMSLog("DEV", "ERR", "0203", "GunScanner " + devStatus.Scanner.Status);
                //        //장비관련 AMS 로그 삭제 요청(2015.07.23) 

                //        return bRet;
                //    }

                //    try
                //    {
                //        scanner.DeviceEnabled = true;
                //    }
                //    catch (Exception ex)
                //    {
                //        devStatus.Scanner.Status = "DEVICE ENABLED FAIL";
                //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                //                            "DeviceScanner.OpenDevice()", devStatus.Scanner.Status + " " + ex.Message);
                //        return bRet;
                //    }

                //    try
                //    {
                //        scanner.DataEventEnabled = true;
                //    }
                //    catch (Exception ex)
                //    {
                //        devStatus.Scanner.Status = "DATAEVENT ENABLED FAIL";
                //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                //                            "DeviceScanner.OpenDevice()", devStatus.Scanner.Status + " " + ex.Message);
                //        return bRet;
                //    }
                //    scanner.DecodeData = true;
                //    devStatus.Scanner.Open = true;
                //    devStatus.Scanner.Status = "Success";

                //    bw.DoWork += OlePosHandler;
                //    bRet = true;
                //}
                //m_nErrorCount = 0;
            }
            catch (Exception ex)
            {
                devStatus.Scanner.Open = false;
                devStatus.Scanner.Status = "DEVICE OPEN EXCEPTION";

                UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "DeviceScanner.OpenDevice()", devStatus.Scanner.Status + " " + ex.Message);
                return bRet;
            }
            return bRet;
        }

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="sender"></param>
        ///// <param name="e"></param>
        //private void Scanner_DataEvent(object sender, DataEventArgs e)
        //{
        //    try
        //    {
        //        if(!bw.IsBusy)
        //        {
        //            ASCIIEncoding encoder = new ASCIIEncoding();

        //            m_sScanData = encoder.GetString(scanner.ScanData);
        //            m_sScanDataLabel = encoder.GetString(scanner.ScanDataLabel);
        //            m_sScanDataType = scanner.ScanDataType.ToString();

        //            devStatus.Scanner.Data = m_sScanData;
        //            devStatus.Scanner.DataLabel = "";
        //            //for (int i = 0; i < m_sScanDataLabel.Length; i++)
        //            //{
        //            //    if (CmUtil.IsNumber(m_sScanDataLabel.Substring(i, 1)) == true)
        //            //        devStatus.Scanner.DataLabel += m_sScanDataLabel.Substring(i, 1);
        //            //}
        //            string sChgDataLabel = "";
        //            for (int i = 0; i < scanner.ScanDataLabel.Length; i++)
        //            {
        //                if (scanner.ScanDataLabel[i] == (byte)29)
        //                    sChgDataLabel += "|";
        //                else
        //                    sChgDataLabel += Convert.ToChar(scanner.ScanDataLabel[i]).ToString();
        //            }
        //            for (int i = 0; i < sChgDataLabel.Length; i++)
        //            {
        //                if (CmUtil.IsNumber(sChgDataLabel.Substring(i, 1)) == true)
        //                {
        //                    devStatus.Scanner.DataLabel = sChgDataLabel.Substring(i, sChgDataLabel.Length - i);
        //                    break;
        //                }
        //                //if (sChgDataLabel.Substring(i, 1) != string.Format("{0}", (char)10) && sChgDataLabel.Substring(i, 1) != string.Format("{0}", (char)13))
        //                //{
        //                //    devStatus.Scanner.DataLabel = devStatus.Scanner.DataLabel + sChgDataLabel.Substring(i, 1);
        //                //}
        //            }
        //            devStatus.Scanner.DataType = m_sScanDataType;

        //            UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
        //                                "DeviceScanner.Scanner_DataEvent()",
        //                                "Data=" + m_sScanData + ", DataLabel=" + m_sScanDataLabel + "=>" + devStatus.Scanner.DataLabel + ", DataType=" + m_sScanDataType);
        //            bw.RunWorkerAsync();
        //        }
        //        else
        //        {
        //            UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
        //                            "DeviceScanner.Scanner_DataEvent()", "스캐너 이벤트 처리 전 이벤트 발생 불가");
        //            //Cosmos.CommonManager.WinManager.ErrorMessage("해당 화면에서 스캐너를 입력 할 수 없습니다.", "스캐너 입력 오류", true);
        //            //MessageStartTimer(100);
        //        }
               
        //        //if (PosOLEDevice.m_delegateOlePos != null)
        //        //    PosOLEDevice.m_delegateOlePos(PosConst.OPOS_DEVICE.SCANNER, m_sScanData, devStatus.Scanner.DataLabel, m_sScanDataType);
        //        //else
        //        //{
        //        //    UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
        //        //                    "DeviceScanner.Scanner_DataEvent()", "이벤트 전송 대상 없음.");
        //        //    Cosmos.CommonManager.WinManager.ErrorMessage("해당 화면에서 스캐너를 입력 할 수 없습니다.", "스캐너 입력 오류", true);
        //        //}

        //    }
        //    catch (Exception ex)
        //    {
        //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
        //                            "DeviceScanner.Scanner_DataEvent()", ex.Message);
        //        devStatus.Scanner.Status = "DATAEVENT ERROR";
        //    }
        //    finally
        //    {
        //        scanner.ClearInput();
        //        scanner.DataEventEnabled = true;
        //    }
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OlePosHandler(object sender, DoWorkEventArgs e)
        {
            try
            {
                if (PosOLEDevice.m_delegateOlePos != null)
                    PosOLEDevice.m_delegateOlePos(PosConst.OPOS_DEVICE.SCANNER, string.Empty, devStatus.Scanner.DataLabel, string.Empty);
                else
                {
                    UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "DeviceScanner.OlePosHandler()", "이벤트 전송 대상 없음.");
                    //Cosmos.CommonManager.WinManager.ErrorMessage("해당 화면에서 스캐너를 입력 할 수 없습니다.", "스캐너 입력 오류", true);
                    //MessageStartTimer(100);
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                "DeviceScanner.OlePosHandler()", ex.Message);
            }
        }

        //private void MessageStartTimer(int dueTime)
        //{
        //    try
        //    {
        //        Thread thrBeep = new Thread(new ThreadStart(OnBeepSound));
        //        thrBeep.Start();
        //    }
        //    catch (Exception ex)
        //    {
        //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
        //                            "DeviceScanner.MessageStartTimer()", ex.Message);
        //    }
        //}

        //private void OnBeepSound()
        //{
        //    try
        //    {
        //        CmMessage m_PosConfig = CmMessage.MakeMessageFromFile(BaseCom.NxIniPath + "PosConfig.INI");
        //        string sPosUseType = m_PosConfig.GetMessage("olepos").GetMessageValue("PosUseType");
        //        string sKeyboard = m_PosConfig.GetMessage("control").GetMessageValue("Keyboard");
                
        //        for (int i = 0; i < 5; i++)
        //        {
        //            WinManager.BuzzSoundOn(sPosUseType, sKeyboard);
        //            Thread.Sleep(200);
        //        }

        //        //CmMessage m_PosConfig = CmMessage.MakeMessageFromFile(BaseCom.NxIniPath + "PosConfig.INI");

        //        //string sPosUseType = m_PosConfig.GetMessage("olepos").GetMessageValue("PosUseType");
        //        //string sKeyboard = m_PosConfig.GetMessage("control").GetMessageValue("Keyboard");

        //        //for (int i = 0; i < 5; i++)
        //        //{
        //        //    if (sPosUseType == "2" || sPosUseType == "9" || sPosUseType == "4" || sKeyboard == "2")
        //        //        // POS모델   ==> 2:7K, 9.B20(Toshiba) 4.3000XC(분스)
        //        //        // POS키보드 ==> (0:104, 1:40, 2:32)
        //        //        Console.Beep();
        //        //    else
        //        //        BuzzOn(0, 0);
        //        //    Thread.Sleep(200);
        //        //}
        //    }
        //    catch (Exception ex)
        //    {
        //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
        //                            "DeviceScanner.OnBeepSound()", ex.Message);
        //    }
        //}

        //private void MessageStartTimer(int dueTime)
        //{
        //    if (m_nErrorCount < 2)
        //    {
        //        Timer t = new Timer(new TimerCallback(MessageTimerProc));
        //        t.Change(dueTime, 0);
        //    }
        //}

        //private void MessageTimerProc(object state)
        //{
        //    m_nErrorCount++;
        //    // The state object is the Timer object.
        //    Timer t = (Timer)state;
        //    t.Dispose();

        //    Cosmos.CommonManager.WinManager.ErrorMessage("해당 화면에서 스캐너를 입력 할 수 없습니다.", "스캐너 입력 오류", true);
        //    m_nErrorCount--;
        //}

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="sender"></param>
        ///// <param name="e"></param>
        //private void Scanner_ErrorEvent(object sender, DeviceErrorEventArgs e)
        //{
        //    try
        //    {
        //        ASCIIEncoding encoder = new ASCIIEncoding();

        //        m_sScanData = encoder.GetString(scanner.ScanData);
        //        m_sScanDataLabel = encoder.GetString(scanner.ScanDataLabel);
        //        m_sScanDataType = scanner.ScanDataType.ToString();

        //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
        //                            "DeviceScanner.Scanner_ErrorEvent()",
        //                            "ErrorEvent 발생 ScanData=[" + m_sScanData + "] ScanDataLabel=[" + m_sScanDataLabel + "] ScanDataType=[" + m_sScanDataType + "]");

        //        devStatus.Scanner.Data = string.Empty;
        //        devStatus.Scanner.DataLabel = string.Empty;

        //        scanner.ClearInput();
        //        scanner.DataEventEnabled = true;

        //        devStatus.Scanner.Status = "ERROR EVENT";
        //    }
        //    catch (Exception ex)
        //    {
        //        UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
        //                            "DeviceScanner.Scanner_ErrorEvent()", ex.Message);

        //        devStatus.Scanner.Status = "ErrorEvent Error 발생";
        //    }
        //}

        /// <summary>
        /// Scanner StateServer 정보 초기화
        /// </summary>
        private void DeviceStatusInit()
        {
            devStatus.Scanner.Data = "";
            devStatus.Scanner.DataLabel = "";
            devStatus.Scanner.DataType = "";
            devStatus.Scanner.DeviceName = "";
            devStatus.Scanner.Status = "";
            devStatus.Scanner.Open = false;
        }

        /// <summary>
        /// 디바이스 Close시 처리함수</para>
        /// </summary>
        /// <returns></returns>
        public bool CloseDevice()
        {
            bool bRet = false;

            try
            {
                //if (scanner == null)
                //    return bRet;

                //scanner.DataEventEnabled = false;
                //scanner.DeviceEnabled = false;
                //scanner.Release();
                //scanner.Close();
                //scanner = null;
                bRet = true;
                devStatus.Scanner.Status = "CLOSE";
                devStatus.Scanner.Open = false;
                bw.DoWork -= OlePosHandler;
            }
            catch (Exception ex)
            {
                bw.DoWork -= OlePosHandler;
                UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                    "DeviceScanner.CloseDevice()", ex.Message);

                devStatus.Scanner.Status = "CLOSE EXCEPTION";
            }
            return bRet;
        }

        /// <summary>
        /// 장비의 Event 발생 Enable 상태 설정
        /// <para>True:사용가능, False:사용불가능</para>
        /// </summary>
        public bool DeviceEnabled
        {
            get
            {
                try
                {
                    //if (scanner.DeviceEnabled && scanner.DataEventEnabled)
                    //    return true;
                    //else
                        return false;
                }
                catch (Exception ex)
                {
                    UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "DeviceScanner.DeviceEnabled()", ex.Message);
                    return false;
                }
            }
            set
            {
                try
                {
                    bool bRet = SetDeviceEnabled(value);
                }
                catch (Exception ex)
                {
                    UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                        "DeviceScanner.DeviceEnabled()", ex.Message);
                }
            }
        }

        /// <summary>
        /// 장비의 Event 발생 Enable 상태 설정
        /// <para>True:사용가능, False:사용불가능</para>
        /// </summary>
        /// <param name="bEnable"></param>
        /// <returns></returns>
        private bool SetDeviceEnabled(bool bEnable)
        {
            bool bRet = false;

            try
            {
                //scanner.DataEventEnabled = bEnable;
                //scanner.DeviceEnabled = bEnable;
                devStatus.Scanner.Status = "DEVICE ENABLED " + bEnable.ToString();
                bRet = true;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_IOS, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                    "DeviceScanner.SetDeviceEnabled()", ex.Message);
                devStatus.Scanner.Status = "DEVICE ENABLED FAIL";
            }
            return bRet;
        }
    }
}
