using System;
using WinRT.BxlComponent.Plugin.BxlMpXamarinSDK.Abstractions;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Media.Imaging;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;

namespace WinRT.BxlComponent.Plugin.BxlMpXamarinSDK
{
    internal partial class MposConfigurationImplementation : MposConfig
    {
        public int DeviceID { get; private set; }
        public MPosDeviceType DeviceType { get; private set; }
        public MPosInterfaceType InterfaceType { get; private set; } = MPosInterfaceType.MPOS_INTERFACE_BLUETOOTH;
        public bool IsOpen { get; private set; } = false;
        public MPosCommandMode CommandMode { get; private set; } = MPosCommandMode.MPOS_COMMAND_MODE_BGATE;
        public IMPosConnection _MPosConnection { get; private set; } = null;
        public string _ConnectionString { get; private set; }
        public Dictionary<byte, byte[]> _CmdDictionary { get; private set; }  = new Dictionary<byte, byte[]>();
    }

    internal partial class MposConfigurationImplementation : MposConfig
    {
        public MposConfigurationImplementation(int deviceType, int deviceId)
        {
            MPosDebug.WriteLine("ConfigurationImplementation Constructor : START");
            DeviceID = deviceId;
            DeviceType = (MPosDeviceType)deviceType;
            MPosDebug.WriteLine("ConfigurationImplementation Constructor : DeviceID = " + DeviceID);
            MPosDebug.WriteLine("ConfigurationImplementation Constructor : DeviceType = " + DeviceType);
            MPosDebug.WriteLine("ConfigurationImplementation Constructor : END");
        }
        public async Task<int> openService(uint timeout = 5 /*second*/)
        {
            if (IsOpen)
            {
                MPosDebug.WriteLine("ConfigurationImplementation openService : MPOS_ALREADY_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation openService : END");
                return (int)MPosResult.MPOS_ALREADY_OPEN;
            }

            return await openService((uint)DeviceID, timeout);
        }
        public async Task<int> openService(uint deviceId = 0, uint timeout = 5 /*second*/)
        {

            int result = (int)MPosResult.MPOS_SUCCESS;
            MPosDebug.WriteLine("ConfigurationImplementation openService : START");
            MPosDebug.WriteLine("ConfigurationImplementation openService : deviceId = " + deviceId + ", timeout = " + timeout);
            MPosDebug.WriteLine("ConfigurationImplementation openService : InterfaceType = " + InterfaceType + ", _ConnectionString = " + _ConnectionString);
            MPosDebug.WriteLine("ConfigurationImplementation openService : CommandMode = " + CommandMode);

            if (IsOpen)
            {
                MPosDebug.WriteLine("ConfigurationImplementation openService : MPOS_ALREADY_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation openService : END");
                return (int)MPosResult.MPOS_ALREADY_OPEN;
            }

            _MPosConnection = MPosConnectionBuilderImplementation.Build(InterfaceType, _ConnectionString, (int)CommandMode);

            if (_MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation openService : MPosConnectionBuilder.Current.Build failed.");
                MPosDebug.WriteLine("ConfigurationImplementation openService : END");
                return (int)MPosResult.MPOS_FAIL_NOT_CONNECT;
            }

            // 이 클래스 경우, 객체 카운트를 올리지도 않고, 내리지도 않게 'closeAsync' 함수를 호출하지 않게 한다.
            // 사유 : open / close 반복 시, connection이 사용중이라는 에러로 인해, 예외적으로 카운트 하지 않음.
            //MPosConnectionBuilderImplementation.IncreaseCount();

            try
            {
                _MPosConnection.addDataReadEvent(onDataReadEvent);
                if (await _MPosConnection.openAsync(DeviceType, timeout)){
                    byte[] commandToWrite = new byte[] { 0x08, 0x7e, 0x50, 0x01 };
                    await _MPosConnection.writeAsync((int)BgateDeviceId.PNP_COMMAND, commandToWrite, false, false);
                    await _MPosConnection.getLowestDeviceId(1000, null);
                    IsOpen = true;
                }
            }catch (Exception ex){
                MPosDebug.WriteLine("ConfigurationImplementation openService : ex.Message = " + ex.Message);
                IsOpen = false;
            }

            if (!IsOpen){
                //await _MPosConnection.closeAsync();
                //_MPosConnection = null;
                result = (int)MPosResult.MPOS_FAIL_NOT_CONNECT;
                await closeService();
            }
            else{
                result = (int)MPosResult.MPOS_SUCCESS;
            }

            MPosDebug.WriteLine("ConfigurationImplementation openService : END");
            return result;

        }
        public async Task<int> closeService(uint closeTimeout = 0 /*second*/)
        {
            MPosDebug.WriteLine("ConfigurationImplementation closeService : START");

            _MPosConnection.removeDataReadEvent(onDataReadEvent);

            IsOpen = false;
            statusUpdateEvent = null;
            dataEvent = null;
            //if (_MPosConnection != null)
            //{
            //    await _MPosConnection.closeAsync(closeTimeout);
            //    _MPosConnection = null;
            //}

            MPosDebug.WriteLine("ConfigurationImplementation closeService : END");
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public bool isOpen()
        {
            return IsOpen;
        }
        public int selectCommandMode(int commandMode)
        {
            MPosDebug.WriteLine("ConfigurationImplementation selectCommandMode : START");
            MPosDebug.WriteLine("ConfigurationImplementation selectCommandMode : commandMode = " + commandMode);

            CommandMode = (MPosCommandMode)commandMode;

            MPosDebug.WriteLine("ConfigurationImplementation selectCommandMode : END");
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public int selectInterface(int interfaceType, string address)
        {
            MPosDebug.WriteLine("ConfigurationImplementation selectInterface : START");
            MPosDebug.WriteLine("ConfigurationImplementation selectInterface : interfaceType = " + interfaceType + " address = " + address);

            bool isMember = Enum.GetValues(typeof(MPosInterfaceType)).Cast<int>().Any(x => x == (int)interfaceType);

            if (isMember){
                InterfaceType = (MPosInterfaceType)interfaceType;
                _ConnectionString = address;
                MPosDebug.WriteLine("ConfigurationImplementation selectInterface : _ConnectionString = " + _ConnectionString);
                MPosDebug.WriteLine("ConfigurationImplementation selectInterface : END");
                return (int)MPosResult.MPOS_SUCCESS;
            }

            MPosDebug.WriteLine("ConfigurationImplementation selectInterface : MPOS_FAIL_INVALID_PARAMETER");
            MPosDebug.WriteLine("ConfigurationImplementation selectInterface : END");
            return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
        }
        public async Task<int> setTransaction(int transactionMode)
        {
            return (int)MPosResult.MPOS_FAIL_NOT_SUPPORT;
        }
        public async Task<int> directIO(byte[] data)
        {
            return (int)MPosResult.MPOS_FAIL_NOT_SUPPORT;
        }
        public async Task<int[]> searchDevices()
        {
            MPosDebug.WriteLine("ConfigurationImplementation searchDevices : START");
            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation searchDevices : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation searchDevices : END");
                return null;
            }

            var devIdList = _MPosConnection.getAllDeviceId();
            MPosDebug.WriteLine("ConfigurationImplementation searchDevices : devIdList.Length = " + devIdList.Length);

            MPosDebug.WriteLine("ConfigurationImplementation searchDevices : END");
            return devIdList;
        }

        //public async Task<int> searchDevices(Action<int[]> devIdListDelegate)
        //{
        //    MPosDebug.WriteLine("ConfigurationImplementation searchDevices : START");
        //    if (IsOpen == false || _MPosConnection == null)
        //    {
        //        MPosDebug.WriteLine("ConfigurationImplementation searchDevices : MPOS_FAIL_NO_OPEN");
        //        MPosDebug.WriteLine("ConfigurationImplementation searchDevices : END");
        //        return (int)MPosResult.MPOS_FAIL_NO_OPEN;
        //    }

        //    var devIdList = _MPosConnection.getAllDeviceId();
        //    MPosDebug.WriteLine("ConfigurationImplementation searchDevices : devIdList.Length = " + devIdList.Length);
        //    if (devIdList.Length != 0)
        //    {
        //        devIdListDelegate?.Invoke(devIdList);
        //        MPosDebug.WriteLine("ConfigurationImplementation searchDevices : END");
        //        return (int)MPosResult.MPOS_SUCCESS;
        //    }
        //    MPosDebug.WriteLine("ConfigurationImplementation searchDevices : END");
        //    return (int)MPosResult.MPOS_FAIL;
        //}
    }

    internal partial class MposConfigurationImplementation : MposConfig
    {
        public async Task<int> setSerialConfiguration(int devID, int baudRate, int dataBit, int stopBit, int parityBit, int flowControl)
        {
            MPosDebug.WriteLine("ConfigurationImplementation setSerialConfig : START");
            MPosDebug.WriteLine("ConfigurationImplementation setSerialConfig : devID = " + devID + " baudRate = " + baudRate + " dataBit = " + dataBit);
            MPosDebug.WriteLine("ConfigurationImplementation setSerialConfig : stopBit = " + stopBit + " parityBit = " + parityBit + " flowControl = " + flowControl);
            if (IsOpen == false || _MPosConnection == null){
                MPosDebug.WriteLine("ConfigurationImplementation setSerialConfig : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation setSerialConfig : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (baudRate < 0 || baudRate > 7
                || dataBit < 0 || dataBit > 1
                || stopBit < 0 || stopBit > 1
                || parityBit < 0 || parityBit > 2
                || flowControl < 0 || flowControl > 1)
            {
                MPosDebug.WriteLine("ConfigurationImplementation setSerialConfig : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            byte[] commandToWrite = null;
            commandToWrite = MPosBgateCmdBuilder.getTTYUSBSerialConfigWriteCmd(devID, baudRate, dataBit, stopBit, parityBit, flowControl);
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) > 0){
                MPosDebug.WriteLine("ConfigurationImplementation setSerialConfig : END");
                return (int)MPosResult.MPOS_SUCCESS;
            }
            MPosDebug.WriteLine("ConfigurationImplementation setSerialConfig : END");
            return (int)MPosResult.MPOS_FAIL;
        }
        public async Task<int[]> getSerialConfiguration(int devID)
        {
            MPosDebug.WriteLine("ConfigurationImplementation getSerialConfig : START");
            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation getSerialConfig : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation getSerialConfig : END");
                return null;
            }

            var devIdList = _MPosConnection.getAllDeviceId();
            if (devIdList.Any(x => x == devID) == false)
            {
                MPosDebug.WriteLine("\"ConfigurationImplementation getSerialConfig : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("ConfigurationImplementation getSerialConfig : END");
                return null;
            }

            byte[] commandToWrite = null;
            commandToWrite = MPosBgateCmdBuilder.getTTYUSBSerialConfigReadCmd(devID);
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) <= 0)
            {
                MPosDebug.WriteLine("\"ConfigurationImplementation getSerialConfig : MPOS_FAIL");
                MPosDebug.WriteLine("ConfigurationImplementation getSerialConfig : END");
                return null;
            }

            byte cmd = 0x0D;
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            while (!_CmdDictionary.ContainsKey(cmd))
            {
                await Task.Delay(10);
                if (stopwatch.ElapsedMilliseconds > 1500 /*1.5 Second*/)
                    break;
            }

            if (_CmdDictionary.ContainsKey(cmd))
            {
                int index = 0;
                // data array with id for target device
                int[] byteToIntArray = new int[_CmdDictionary[cmd].Skip(1).ToArray().Length];
                foreach (var d in _CmdDictionary[cmd].Skip(1).ToArray())
                    byteToIntArray[index++] = d;
                //serialConfig?.Invoke(byteToIntArray);
                _CmdDictionary.Remove(cmd);
                MPosDebug.WriteLine("ConfigurationImplementation getSerialConfig : END");
                //return (int)MPosResult.MPOS_SUCCESS;
                return byteToIntArray;
            }

            MPosDebug.WriteLine("ConfigurationImplementation getSerialConfig : END");
            return null;
        }
        public async Task<string> getBgateSerialNumber()
        {
            MPosDebug.WriteLine("ConfigurationImplementation getBgateSerialNumber : START");
            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation getBgateSerialNumber : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation getBgateSerialNumber : END");
                return null;
            }

            byte[] commandToWrite = null;
            commandToWrite = MPosBgateCmdBuilder.getBgateSerialNumberReadCmd();
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) <= 0)
            {
                MPosDebug.WriteLine("ConfigurationImplementation getBgateSerialNumber : MPOS_FAIL");
                MPosDebug.WriteLine("ConfigurationImplementation getBgateSerialNumber : END");
                return null;
            }

            byte cmd = 0x18;
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            while (!_CmdDictionary.ContainsKey(cmd))
            {
                await Task.Delay(10);
                if (stopwatch.ElapsedMilliseconds > 1500 /*1.5 Second*/)
                    break;
            }

            if (_CmdDictionary.ContainsKey(cmd))
            {
                string sn = Encoding.ASCII.GetString(_CmdDictionary[cmd].ToArray());
                MPosDebug.WriteLine("ConfigurationImplementation getBgateSerialNumber : sn = " + sn);
                //serialNumberDelegate?.Invoke(sn);
                _CmdDictionary.Remove(cmd);
                MPosDebug.WriteLine("ConfigurationImplementation getBgateSerialNumber : END");
                return sn;
            }

            MPosDebug.WriteLine("ConfigurationImplementation getBgateSerialNumber : END");
            return null;
        }
        public async Task<string> getUSBDevice(int deviceId)
        {
            MPosDebug.WriteLine("ConfigurationImplementation getUSBDevice : START");
            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation getUSBDevice : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation getUSBDevice : END");
                return null;
            }

            byte[] commandToWrite = null;
            commandToWrite = MPosBgateCmdBuilder.getUSBDeviceReadCmd(deviceId);
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) <= 0)
            {
                MPosDebug.WriteLine("ConfigurationImplementation getUSBDevice : MPOS_FAIL");
                MPosDebug.WriteLine("ConfigurationImplementation getUSBDevice : END");
                return null;
            }

            byte cmd = 0x45;
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            while (!_CmdDictionary.ContainsKey(cmd))
            {
                await Task.Delay(10);
                if (stopwatch.ElapsedMilliseconds > 1500 /*1.5 Second*/)
                    break;
            }

            if (_CmdDictionary.ContainsKey(cmd))
            {
                string usbInfo = "";
                byte[] readData = _CmdDictionary[cmd].ToArray();
                if (readData.Length == 5)
                    usbInfo = string.Format("VID_{0:X2}{1:X2}&PID_{2:X2}{3:X2}", readData[1], readData[2], readData[3], readData[4]);

                MPosDebug.WriteLine("ConfigurationImplementation getUSBDevice : sn = " + usbInfo);
                _CmdDictionary.Remove(cmd);
                MPosDebug.WriteLine("ConfigurationImplementation getUSBDevice : END");
                return usbInfo;
            }

            MPosDebug.WriteLine("ConfigurationImplementation getUSBDevice : END");
            return null;
        }
        public async Task<string> getCustomDevices(int deviceType)
        {
            MPosDebug.WriteLine("ConfigurationImplementation getCustomDevices : START");
            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation getCustomDevices : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation getCustomDevices : END");
                return "";
            }

            byte[] commandToWrite = null;
            commandToWrite = MPosBgateCmdBuilder.getCustomDevicesReadCmd(deviceType);
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) <= 0)
            {
                MPosDebug.WriteLine("ConfigurationImplementation getCustomDevices : MPOS_FAIL");
                MPosDebug.WriteLine("ConfigurationImplementation getCustomDevices : END");
                return "";
            }

            byte cmd = 0x40;
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            while (!_CmdDictionary.ContainsKey(cmd))
            {
                await Task.Delay(10);
                if (stopwatch.ElapsedMilliseconds > 1500 /*1.5 Second*/)
                    break;
            }

            if (_CmdDictionary.ContainsKey(cmd))
            {
                string usbInfo = "";
                byte[] readData = _CmdDictionary[cmd].ToArray();
                if ((readData.Length - 1) % 4 == 0)
                {
                    for (int i = 1; i < readData.Length; i += 4)
                    {
                        if (usbInfo.Length != 0)
                            usbInfo += "|";
                        usbInfo += string.Format("{0:X2}{1:X2}&{2:X2}{3:X2}", readData[i], readData[i + 1], readData[i + 2], readData[i + 3]);
                    }
                }

                MPosDebug.WriteLine("ConfigurationImplementation getCustomDevices : sn = " + usbInfo);
                _CmdDictionary.Remove(cmd);
                MPosDebug.WriteLine("ConfigurationImplementation getCustomDevices : END");
                return usbInfo;
            }

            MPosDebug.WriteLine("ConfigurationImplementation getCustomDevices : END");
            return "";
        }

        public async Task<int> addCustomDevice(int deviceType, string vid, string pid)
        {
            MPosDebug.WriteLine("ConfigurationImplementation addCustomDevices : START");
            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation addCustomDevices : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation addCustomDevices : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            byte[] commandToWrite = null;
            commandToWrite = MPosBgateCmdBuilder.getAddCustomDeviceWriteCmd(deviceType, vid, pid);
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) > 0)
            {
                MPosDebug.WriteLine("ConfigurationImplementation addCustomDevices : END");
                return (int)MPosResult.MPOS_SUCCESS;
            }

            MPosDebug.WriteLine("ConfigurationImplementation addCustomDevices : END");
            return (int)MPosResult.MPOS_FAIL;
        }
        public async Task<int> deleteCustomDevice(int deviceType, string vid, string pid)
        {
            MPosDebug.WriteLine("ConfigurationImplementation deleteCustomDevices : START");
            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation deleteCustomDevices : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation deleteCustomDevices : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            byte[] commandToWrite = null;
            commandToWrite = MPosBgateCmdBuilder.getDeleteCustomDeviceWriteCmd(deviceType, vid, pid);
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) > 0)
            {
                MPosDebug.WriteLine("ConfigurationImplementation deleteCustomDevices : END");
                return (int)MPosResult.MPOS_SUCCESS;
            }

            MPosDebug.WriteLine("ConfigurationImplementation deleteCustomDevices : END");
            return (int)MPosResult.MPOS_FAIL;
        }
        public async Task<int> reInitCustomDeviceType(int deviceType)
        {
            MPosDebug.WriteLine("ConfigurationImplementation reInitCustomDevicesType : START");
            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("ConfigurationImplementation reInitCustomDevicesType : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("ConfigurationImplementation reInitCustomDevicesType : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            byte[] commandToWrite = null;
            commandToWrite = MPosBgateCmdBuilder.getReInitCustomDevicesTypeWriteCmd(deviceType);
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) > 0)
            {
                MPosDebug.WriteLine("ConfigurationImplementation reInitCustomDevicesType : END");
                return (int)MPosResult.MPOS_SUCCESS;
            }

            MPosDebug.WriteLine("ConfigurationImplementation reInitCustomDevicesType : END");
            return (int)MPosResult.MPOS_FAIL;
        }
        public async Task<string> getSerialNumber(int deviceId)
        {
            return "";
            //MPosDebug.WriteLine("ConfigurationImplementation getSerialNumber : START");
            //if (IsOpen == false || _MPosConnection == null)
            //{
            //    MPosDebug.WriteLine("ConfigurationImplementation getSerialNumber : MPOS_FAIL_NO_OPEN");
            //    MPosDebug.WriteLine("ConfigurationImplementation getSerialNumber : END");
            //    return null;
            //}

            //byte[] commandToWrite = null;
            //commandToWrite = MPosBgateCmdBuilder.getBgateSerialNumberReadCmd();
            //if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) <= 0)
            //{
            //    MPosDebug.WriteLine("ConfigurationImplementation getSerialNumber : MPOS_FAIL");
            //    MPosDebug.WriteLine("ConfigurationImplementation getSerialNumber : END");
            //    return null;
            //}

            //var stopwatch = new Stopwatch();
            //stopwatch.Start();
            //while (!_CmdDictionary.ContainsKey(0x18))
            //{
            //    await Task.Delay(10);
            //    if (stopwatch.ElapsedMilliseconds > 1500 /*1.5 Second*/)
            //        break;
            //}

            //if (_CmdDictionary.ContainsKey(0x18))
            //{
            //    string sn = Encoding.ASCII.GetString(_CmdDictionary[0x18].ToArray());
            //    MPosDebug.WriteLine("ConfigurationImplementation getSerialNumber : sn = " + sn);
            //    //serialNumberDelegate?.Invoke(sn);
            //    _CmdDictionary.Remove(0x18);
            //    MPosDebug.WriteLine("ConfigurationImplementation getSerialNumber : END");
            //    return sn;
            //}

            //MPosDebug.WriteLine("ConfigurationImplementation getSerialNumber : END");
            //return null;
        }
    }
    internal partial class MposConfigurationImplementation : MposConfig
    {
        public event Action<byte[]> dataEvent;
        public event Action<uint> statusUpdateEvent;
        private void onDataReadEvent(int deviceId, byte[] data)
        {
            MPosDebug.WriteLine("ConfigurationImplementation onDataReadEvent : deviceId = " + deviceId);
            if (data == null || CommandMode != MPosCommandMode.MPOS_COMMAND_MODE_BGATE)
                return;
            if (deviceId != 0 /* B-gate Command ID*/)
                return;
            foreach (var d in data)
                MPosDebug.WriteLine("ConfigurationImplementation onDataReadEvent : 0x" + d.ToString("X2"));
            MPosDebug.WriteLine("ConfigurationImplementation onDataReadEvent : KEY = 0x" + data[0].ToString("X2") + " , Length = " + data.Length);
            if (_CmdDictionary.ContainsKey(data[0]/*KEY: B-gate command*/))
                _CmdDictionary.Remove(data[0]/*KEY: B-gate command*/);
            // add data without b-gate command
            _CmdDictionary.Add(data[0]/*KEY: B-gate command*/, data.Skip(1).Take(data.Length-1).ToArray());
        }
    }
}