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;

namespace WinRT.BxlComponent.Plugin.BxlMpXamarinSDK
{
    internal partial class MPosDeviceLabelPrinterImplementation : MPosControllerLabelPrinter
    {
        public MPosLabelCodePage CodePage { get; set; } = MPosLabelCodePage.MPOS_CODEPAGE_WPC1252;
        public MPosICS ICS { get; set; } = MPosICS.MPOS_ICS_USA;
        public string _ModelName { get; private set; }
        public string _FirmwareVersion { get; private set; }
        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 bool TransactionModeInOut { get; private set; }
        public MPosCommandMode CommandMode { get; private set; }
        public string _ConnectionString { get; private set; }
        public IMPosConnection _MPosConnection { get; private set; } = null;
        private MPosDeviceDataProcessor _DeviceDataProcessor = new MPosDeviceDataProcessor();
        private string _DebugId;

        public MPosDeviceLabelPrinterImplementation(int deviceType, int deviceId)
        {
            DeviceID = deviceId;
            DeviceType = (MPosDeviceType)deviceType;
            _DebugId = DebugHelper.GetId(this);
        }

        // IMPosDeviceControllerDevice Methods
        public async Task<int> openService(uint deviceId = 0, uint timeout = 5 /*second*/)
        {
            int result = (int)MPosResult.MPOS_SUCCESS;
            MPosDebug.WriteLine("LabelPrinterImplementation openService : START");
            MPosDebug.WriteLine("LabelPrinterImplementation openService : ConnectionString = " + _ConnectionString);
            MPosDebug.WriteLine("LabelPrinterImplementation openService : CommandMode = " + CommandMode.ToString());

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

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

            try
            {
                _DeviceDataProcessor.initDataStream();
                _MPosConnection.addDataReadEvent(onDataReadEvent);
                _MPosConnection.addDisconnectedEvent(onDisconnectedEvent);
                _MPosConnection.addConnectedEvent(onConnectedEvent);

                if (await _MPosConnection.openAsync(DeviceType, timeout))
                {
                    IsOpen = true;
                    DeviceID = (int)deviceId;

                    onConnectedEvent();

                    //if (CommandMode != MPosCommandMode.MPOS_COMMAND_MODE_DIRECT)
                    //{
                    //    if (deviceId <= 0 || deviceId >= 255)
                    //        deviceId = (uint)await _MPosConnection.getLowestDeviceId(1500, this);
                    //    if (!await _MPosConnection.isAvailableDeviceId(this, deviceId))
                    //        IsOpen = false;
                    //    else
                    //        DeviceID = (int)deviceId;
                    //}

                    if (IsOpen)
                    {
                        _ModelName = "";
                        if (await getModelName(null) == (int)MPosResult.MPOS_SUCCESS){
                            MPosDebug.WriteLine("LabelPrinterImplementation openService : _ModelName = " + _ModelName);
                            if (_ModelName.Contains("SLP") || _ModelName.Contains("SRP") || _ModelName.Contains("SPP")
                                || _ModelName.Contains("XL5-") || _ModelName.Contains("XT5-") || _ModelName.Contains("XD3-")
                                || _ModelName.Contains("XD5-") || _ModelName.Contains("XQ-") || _ModelName.Contains("XM7-")
                                || _ModelName.Contains("XT3-"))
                            {
                                IsOpen = true;
                            }else{
                                IsOpen = false;
                            }
                        }
                    }
                }
            }
            catch (Exception ex){
                MPosDebug.WriteLine("LabelPrinterImplementation openService : ex.Message = " + ex.Message);
                IsOpen = false;
            }

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

            if (CommandMode == MPosCommandMode.MPOS_COMMAND_MODE_BGATE && result == (int)MPosResult.MPOS_SUCCESS){
                //MPosConnectionBuilderImplementation.IncreaseCount();
                MPosConnectionBuilderImplementation.AddDevice(DeviceID);
            }

            MPosDebug.WriteLine("LabelPrinterImplementation openService : END");
            return result;
        }
        public async Task<int> openService(uint timeout = 5 /*second*/)
        {
            if (IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation openService : MPOS_ALREADY_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation openService : END");
                return (int)MPosResult.MPOS_ALREADY_OPEN;
            }

            return await openService((uint)DeviceID, timeout);
        }
        public async Task<int> closeService(uint closeTimeout = 0 /*second*/)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation closeService : START");

            if (CommandMode == MPosCommandMode.MPOS_COMMAND_MODE_BGATE){
                MPosConnectionBuilderImplementation.RemoveDevice(DeviceID);
            }

            IsOpen = false;
            statusUpdateEvent = null;
            dataEvent = null;

            _DeviceDataProcessor.clearDataStream();

            if (_MPosConnection != null)
            {
                _MPosConnection.removeDataReadEvent(this.onDataReadEvent);
                _MPosConnection.removeDisconnectedEvent(this.onDisconnectedEvent);
                _MPosConnection.removeConnectedEvent(this.onConnectedEvent);
                await _MPosConnection.closeAsync(closeTimeout);
                _MPosConnection = null;
            }

            MPosDebug.WriteLine("LabelPrinterImplementation closeService : END");
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public int selectCommandMode(int commandMode)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation selectCommandMode : START");
            MPosDebug.WriteLine("LabelPrinterImplementation selectCommandMode : commandMode = " + commandMode.ToString());

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

            if (isMember)
            {
                CommandMode = (MPosCommandMode)commandMode;
                MPosDebug.WriteLine("LabelPrinterImplementation selectCommandMode : END");
                return (int)MPosResult.MPOS_SUCCESS;
            }

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

            if (IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation selectInterface : MPOS_FAIL_OPENED");
                MPosDebug.WriteLine("LabelPrinterImplementation selectInterface : END");
                return (int)MPosResult.MPOS_FAIL_OPENED;
            }

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

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

            MPosDebug.WriteLine("LabelPrinterImplementation selectInterface : MPOS_FAIL_INVALID_PARAMETER");
            MPosDebug.WriteLine("LabelPrinterImplementation selectInterface : END");
            return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
        }

        public bool isOpen()
        {
            return IsOpen;
        }
        public async Task<int> directIO(byte[] data)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation directIO : START");

            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation directIO : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation directIO : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            int writtenBytes = 0;

            if (data != null)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation directIO : data.Length = " + data.Length.ToString());
                writtenBytes = await _MPosConnection.writeAsync(DeviceID, data);
                MPosDebug.WriteLine("LabelPrinterImplementation directIO : written bytes = " + writtenBytes.ToString());

                var expectedDataLength = MPosByteArrayHelper.searchBytePattern(Encoding.ASCII.GetBytes("^cp"), data).Count;
                expectedDataLength += MPosByteArrayHelper.searchBytePattern(Encoding.ASCII.GetBytes("^cu"), data).Count;
                expectedDataLength += MPosByteArrayHelper.searchBytePattern(Encoding.ASCII.GetBytes("^PI"), data).Count;
                if (expectedDataLength > 0)
                {
                    // in case '^cp' or '^cu' pattern found, call this method without 'await' keyword.
                    var getDataTask = await _DeviceDataProcessor.getDataFromMemoryStream(0, (dataArray) => { dataEvent?.Invoke(dataArray); });
                }
            }

            MPosDebug.WriteLine("LabelPrinterImplementation directIO : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> printRawData(byte[] data)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation printRawData : START");
            var ret = await directIO(data);
            MPosDebug.WriteLine("LabelPrinterImplementation printRawData : END");
            return ret;
        }
    }
    internal partial class MPosDeviceLabelPrinterImplementation : MPosControllerLabelPrinter
    {
        public event Action<byte[]> dataEvent;
        public event Action<uint> statusUpdateEvent;

        // MAUI에서 추가
        //public event Action<byte[]> _dataEvent
        //{
        //    add { if (!isDataEventHandlerRegistered(value)) dataEvent += value; }
        //    remove { if (statusUpdateEvent != null) dataEvent -= value; }
        //}
        //public event Action<uint> _statusUpdateEvent
        //{
        //    add { if (!isStatusEventHandlerRegistered(value)) statusUpdateEvent += value; }
        //    remove { if (statusUpdateEvent != null) statusUpdateEvent -= value; }
        //}
        //private bool isDataEventHandlerRegistered(Delegate prospectiveHandler)
        //{
        //    if (this.dataEvent != null)
        //    {
        //        foreach (Delegate existingHandler in this.dataEvent.GetInvocationList())
        //            if (existingHandler == prospectiveHandler)
        //                return true;
        //    }
        //    return false;
        //}
        //private bool isStatusEventHandlerRegistered(Delegate prospectiveHandler)
        //{
        //    if (this.statusUpdateEvent != null)
        //    {
        //        foreach (Delegate existingHandler in this.statusUpdateEvent.GetInvocationList())
        //            if (existingHandler == prospectiveHandler)
        //                return true;
        //    }
        //    return false;
        //}

        private async void onConnectedEvent()
        {
            MPosDebug.WriteLine("LabelPrinterImplementation onConnectedEvent");
            byte[] commandToWrite = null;
            if (CommandMode == MPosCommandMode.MPOS_COMMAND_MODE_BGATE)
                commandToWrite = MPosBgateCmdBuilder.getReadModeCmd((uint)DeviceID, BgateDeviceReadMode.AUTO_ENABLE);
            else if (DeviceID < 0xff) //주변기기로 연결된 경우에는 ReadMode Enable 커맨드를 전송한다.
                commandToWrite = new byte[] { 0x08, 0x7e, 0x52, (byte)DeviceID, 0x01 };
            await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false);
        }
        private void onDisconnectedEvent()
        {
            MPosDebug.WriteLine("LabelPrinterImplementation onDisconnectedEvent");
        }
        private void onDataReadEvent(int deviceId, byte[] data)
        {
            if (data == null)
                return;
            if (CommandMode == MPosCommandMode.MPOS_COMMAND_MODE_BGATE){
                if (deviceId != DeviceID)
                    return;
            }
            _DeviceDataProcessor.writeData(data);
        }
    }
    internal partial class MPosDeviceLabelPrinterImplementation : MPosControllerLabelPrinter
    {
        public async Task<int> printBuffer(int numberOfCopies)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation printBuffer : START");
            MPosDebug.WriteLine("LabelPrinterImplementation printBuffer : numberOfCopies = " + numberOfCopies.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation printBuffer : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation printBuffer : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (numberOfCopies < 1) numberOfCopies = 1;
            if (numberOfCopies > 65535) numberOfCopies = 65535;

            string printCommand = "P" + numberOfCopies.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation printBuffer : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation printBuffer : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<uint> checkPrinterStatus()
        {
            MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : START");

            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var commandToWrite = Encoding.ASCII.GetBytes("^cp\r\n");
            if (CommandMode == MPosCommandMode.MPOS_COMMAND_MODE_BGATE)
            {
                var data1 = MPosBgateCmdBuilder.getReadModeCmd((uint)DeviceID, BgateDeviceReadMode.AUTO_ENABLE);
                var data2 = MPosBgateCmdBuilder.addMPosHeaderData((uint)DeviceID, commandToWrite);
                commandToWrite = MPosByteArrayHelper.concat(data1, data2);
            }

            int writtenBytes = await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false);
            byte[] readData = await _DeviceDataProcessor.getDataFromMemoryStream(2);
            if (readData == null)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : NO DATA READ");
                MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : END");
                return (int)MPosResult.MPOS_FAIL;
            }

            if (readData.Length < 2)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : NOT EXPECTED DATA");
                MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : END");
                return (int)MPosResult.MPOS_FAIL;
            }

            MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : readData[" + (readData.Length - 2) + "] = " + readData[readData.Length - 2]);
            MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : readData[" + (readData.Length - 1) + "] = " + readData[readData.Length - 1]);

            uint status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_IDLE;

            // first byte
            if ((readData[readData.Length-2] & 0x04) != 0)   status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_RIBBON_END;      // 리본 없음
            if ((readData[readData.Length-2] & 0x08) != 0)   status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_GAP_ERROR;       // 갭 인식 불량(오토센싱 실패)
            if ((readData[readData.Length-2] & 0x10) != 0)   status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_TPH_OVERHEAT;    // TPH 과열
            if ((readData[readData.Length-2] & 0x20) != 0)   status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_CUTTER_JAMMED;   // 커터 잼
            if ((readData[readData.Length-2] & 0x40) != 0)   status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_COVEROPEN;       // 커버 열림
            if ((readData[readData.Length-2] & 0x80) != 0)   status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_PAPEREMPTY;      // 용지 없음
            // second byte
            if ((readData[readData.Length-1] & 0x80) != 0)  status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_ON_BUILDING_LABEL_TO_BE_PRINTED; // 이미지 버퍼에 라벨 구성 중
            if ((readData[readData.Length-1] & 0x40) != 0)  status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_ON_PRINTING_LABEL;               // 이미지 버퍼에 있는 라벨 인쇄 중
            if ((readData[readData.Length-1] & 0x20) != 0)  status = (int)MPosLabelPrinterStatus.MPOS_LABEL_STATUS_PRINTER_ISSUED_LABEL_ISPAUSED;           // 인쇄된 라벨이 필러에 붙어있음

            statusUpdateEvent?.Invoke(status);
            MPosDebug.WriteLine("LabelPrinterImplementation checkPrinterStatus : END");
            return status;
        }
        private string getCharSetSelectCommand(int internationalCharSet, int codepage)
        {
            string charSetCmd = "CS" + (internationalCharSet).ToString() + ",";
            switch ((MPosLabelCodePage)codepage)
            {
                case MPosLabelCodePage.MPOS_CODEPAGE_CP437: charSetCmd += "0"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP850: charSetCmd += "1"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP852: charSetCmd += "2"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP860: charSetCmd += "3"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP863: charSetCmd += "4"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP865: charSetCmd += "5"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1252: charSetCmd += "6"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP857: charSetCmd += "8"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP737: charSetCmd += "9"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1250: charSetCmd += "10"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1253: charSetCmd += "11"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1254: charSetCmd += "12"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP855: charSetCmd += "13"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP862: charSetCmd += "14"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP866: charSetCmd += "15"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1251: charSetCmd += "16"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1255: charSetCmd += "17"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP928: charSetCmd += "18"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP864: charSetCmd += "19"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP775: charSetCmd += "20"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1257: charSetCmd += "21"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP858: charSetCmd += "22"; break;
                default:
                    return "";
            }
            charSetCmd += "\r\n";
            return charSetCmd;
        }
        private byte[] getEncodedTextData(string data, int codepage = -1)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation getEncodedTextData : START");

            byte[] encodedData = null;
            if (data.Length <= 0)
                return null;

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            if (codepage < 0){
                codepage = (int)CodePage;
            }

            switch ((MPosLabelCodePage)codepage)
            {
                //C# Encoding 클래스가 928을 지원하지 않아서, 가장 유사한 1253으로 처리하도록 수정
                case MPosLabelCodePage.MPOS_CODEPAGE_CP928:
                    encodedData = Encoding.GetEncoding(1253).GetBytes(data);
                    break;
                //case MPosLabelCodePage.MPOS_CODEPAGE_CP864:
                //    encodedData = Encoding.GetEncoding(437).GetBytes("NOT SUPPORTED CODEPAGE");
                //    break;
                default:
                    encodedData = Encoding.GetEncoding(codepage).GetBytes(data);
                    break;
            }

            if (encodedData != null){
                MPosDebug.WriteLine("LabelPrinterImplementation getEncodedTextData : encodedData.Length = " + encodedData.Length);
            }
            MPosDebug.WriteLine("LabelPrinterImplementation getEncodedTextData : END");
            return encodedData;
        }
        public async Task<int> getModelName(Action<string> modelDelegate)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation getModelName : START");

            if (IsOpen == false || _MPosConnection == null){
                MPosDebug.WriteLine("LabelPrinterImplementation getModelName : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation getModelName : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (string.IsNullOrWhiteSpace(_ModelName) == false){
                MPosDebug.WriteLine("LabelPrinterImplementation getModelName : not Null Or Empty, _ModelName = " + _ModelName);
                MPosDebug.WriteLine("LabelPrinterImplementation getModelName : _ModelName = " + _ModelName);
                MPosDebug.WriteLine("LabelPrinterImplementation getModelName : END");
                modelDelegate?.Invoke(_ModelName);
                return (int)MPosResult.MPOS_SUCCESS;
            }

            var commandToWrite = System.Text.Encoding.ASCII.GetBytes("CB@^PI0\r\n^PI02\r\n");

            // RN SDK
            //if (CommandMode == MPosCommandMode.MPOS_COMMAND_MODE_BGATE){
            //    var data1 = MPosBgateCmdBuilder.getReadModeCmd((uint)DeviceID, BgateDeviceReadMode.AUTO_ENABLE);
            //    var data2 = MPosBgateCmdBuilder.addMPosHeaderData((uint)DeviceID, commandToWrite);
            //    commandToWrite = MPosByteArrayHelper.concat(data1, data2);
            //}

            //if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) == commandToWrite.Length){
            //    var readDataArray = await _DeviceDataProcessor.getDataFromMemoryStream(new byte[] { 0x0d, 0x0a }, 2000);
            //    if (readDataArray != null) {
            //        _ModelName = Encoding.ASCII.GetString(readDataArray);
            //        //_ModelName = Encoding.ASCII.GetString(readDataArray.Take(Array.FindIndex(readDataArray, d => d == 0x00)).ToArray());
            //    }
            //}

            // MAUI SDK
            //if (CommandMode == MPosCommandMode.MPOS_COMMAND_MODE_BGATE){
            //    var data1 = MPosBgateCmdBuilder.getReadModeCmd((uint)DeviceID, BgateDeviceReadMode.AUTO_ENABLE);
            //    var data2 = MPosBgateCmdBuilder.addMPosHeaderData((uint)DeviceID, commandToWrite);
            //    commandToWrite = MPosByteArrayHelper.concat(data1, data2);
            //}

            //if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) == commandToWrite.Length){
            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite) != 0)
            {
                var readDataArray = await _DeviceDataProcessor.getDataFromMemoryStream(new byte[] { 0x0d, 0x0a }, 2000);
                if (readDataArray != null)
                    _ModelName = Encoding.ASCII.GetString(readDataArray);
            }

            MPosDebug.WriteLine("LabelPrinterImplementation getModelName : _ModelName = " + _ModelName);
            MPosDebug.WriteLine("LabelPrinterImplementation getModelName : END");
            if (string.IsNullOrEmpty(_ModelName))
                return (int)MPosResult.MPOS_FAIL;
            modelDelegate?.Invoke(_ModelName);
            return (int)MPosResult.MPOS_SUCCESS;

        }

        // MAUI
        //public async Task<int> getPrinterInformation(int item, Action<string> infoDelegate)
        //{
        //    // MAUI 내용 추가 생략
        //}

        public async Task<int> getFirmwareVersion(Action<string> versionDelegate)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation getFirmwareVersion : START");
            if (IsOpen == false || _MPosConnection == null){
                MPosDebug.WriteLine("LabelPrinterImplementation getFirmwareVersion : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation getFirmwareVersion : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (string.IsNullOrWhiteSpace(_FirmwareVersion) == false){
                versionDelegate?.Invoke(_FirmwareVersion);
                MPosDebug.WriteLine("LabelPrinterImplementation getFirmwareVersion : _FirmwareVersion = " + _FirmwareVersion);
                MPosDebug.WriteLine("LabelPrinterImplementation getFirmwareVersion : END");
                return (int)MPosResult.MPOS_SUCCESS;
            }

            var commandToWrite = System.Text.Encoding.ASCII.GetBytes("CB@^PI2\r\n^PI0\r\n");
            if (CommandMode == MPosCommandMode.MPOS_COMMAND_MODE_BGATE){
                var data1 = MPosBgateCmdBuilder.getReadModeCmd((uint)DeviceID, BgateDeviceReadMode.AUTO_ENABLE);
                var data2 = MPosBgateCmdBuilder.addMPosHeaderData((uint)DeviceID, commandToWrite);
                commandToWrite = MPosByteArrayHelper.concat(data1, data2);
            }

            if (await _MPosConnection.writeAsync(DeviceID, commandToWrite, false, false) == commandToWrite.Length)
            {
                var readDataArray = await _DeviceDataProcessor.getDataFromMemoryStream(new byte[] { 0x0d, 0x0a });
                if (readDataArray != null) {
                    _FirmwareVersion = Encoding.ASCII.GetString(readDataArray);
                    //_FirmwareVersion = Encoding.ASCII.GetString(readDataArray.Take(Array.FindIndex(readDataArray, d => d == 0x00)).ToArray());
                }
            }

            MPosDebug.WriteLine("LabelPrinterImplementation getFirmwareVersion : _FirmwareVersion = " + _FirmwareVersion);
            MPosDebug.WriteLine("LabelPrinterImplementation getFirmwareVersion : END");
            if (string.IsNullOrEmpty(_FirmwareVersion))
                return (int)MPosResult.MPOS_FAIL;
            versionDelegate?.Invoke(_FirmwareVersion);
            return (int)MPosResult.MPOS_SUCCESS;

        }
    }
    internal partial class MPosDeviceLabelPrinterImplementation : MPosControllerLabelPrinter
    {
        public async Task<int> setTransaction(int transactionMode)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setTransaction : START");

            if (IsOpen == false || _MPosConnection == null)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setTransaction : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setTransaction : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            MPosDebug.WriteLine("PrinterImplementation setTransaction : transactionMode = " + transactionMode.ToString());

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

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setTransaction : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation setTransaction : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            // Already page mode entered.
            bool mode = Convert.ToBoolean(transactionMode);

            // Already transaction mode in
            if (mode && _MPosConnection._TransactionModeInOut)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation transactionMode : MPOS_TRANSACTION_ALREADY_IN");
                MPosDebug.WriteLine("LabelPrinterImplementation transactionMode : END");
                //return (int)MPosResult.MPOS_TRANSACTION_ALREADY_IN;
                throw new Exception("TRANSACTION MODE ALREADY IN");
            }

            TransactionModeInOut = mode;
            _MPosConnection._TransactionModeInOut = mode;

            if (_MPosConnection._TransactionModeInOut)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setTransaction : END");
                return (int)MPosResult.MPOS_SUCCESS;
            }

            var result = await _MPosConnection.clearBufferStored(DeviceID);
            MPosDebug.WriteLine("LabelPrinterImplementation setTransaction : END");

            return result;
        }
        public int setTextEncoding(int textEncoding)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setTextEncoding : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setTextEncoding : textEncoding = " + textEncoding.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setTextEncoding : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setTextEncoding : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

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

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            CodePage = (MPosLabelCodePage)textEncoding;
            MPosDebug.WriteLine("LabelPrinterImplementation setTextEncoding : END");

            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setCharacterset(int charset, int internationalCharset)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : charset = " + charset.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : internationalCharset = " + internationalCharset.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true, true };
            isMember[0] = Enum.GetValues(typeof(MPosICS)).Cast<int>().Any(x => x == (int)internationalCharset);
            isMember[1] = Enum.GetValues(typeof(MPosLabelCodePage)).Cast<int>().Any(x => x == (int)charset);

            foreach (var member in isMember)
            {
                if (member == false)
                {
                    MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : MPOS_FAIL_INVALID_PARAMETER");
                    MPosDebug.WriteLine("LabelPrinterImplementation setCharacterset : END");
                    return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
                }
            }

            if (charset != (int)MPosLabelCodePage.MPOS_CODEPAGE_CHINA_GB2312 &&
                charset != (int)MPosLabelCodePage.MPOS_CODEPAGE_CHINA_BIG5 &&
                charset != (int)MPosLabelCodePage.MPOS_CODEPAGE_KOREA_KS5601 &&
                charset != (int)MPosLabelCodePage.MPOS_CODEPAGE_JAPAN_SHIFTJIS)
            {
                CodePage = (MPosLabelCodePage)charset;
            }

            ICS = (MPosICS)internationalCharset;

            // MAUI
            //ICS = (MPosLabelICS)internationalCharset;

            string printCommand = "CS";
            printCommand += ((int)internationalCharset).ToString() + ",";

            switch ((MPosLabelCodePage)charset)
            {
                case MPosLabelCodePage.MPOS_CODEPAGE_CP437: printCommand += "0"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP850: printCommand += "1"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP852: printCommand += "2"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP860: printCommand += "3"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP863: printCommand += "4"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP865: printCommand += "5"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1252: printCommand += "6"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP857: printCommand += "8"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP737: printCommand += "9"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1250: printCommand += "10"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1253: printCommand += "11"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1254: printCommand += "12"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP855: printCommand += "13"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP862: printCommand += "14"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP866: printCommand += "15"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1251: printCommand += "16"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1255: printCommand += "17"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP928: printCommand += "18"; break;
                //case MPosLabelCodePage.MPOS_CODEPAGE_CP864: printCommand += "19"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP775: printCommand += "20"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_WPC1257: printCommand += "21"; break;
                case MPosLabelCodePage.MPOS_CODEPAGE_CP858: printCommand += "22"; break;
                default:
                    // East Asia Codepage
                    printCommand += "6";
                    break;
            }

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setCharacterset : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setCharacterset : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setPrintingType(char printingType)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setPrintingType : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setPrintingType : printingType = " + printingType.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setPrintingType : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setPrintingType : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

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

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setPrintingType : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation setPrintingType : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            string printCommand = "ST" + printingType.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setPrintingType : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setPrintingType : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setMargin(int horizontalMargin, int verticalMargin)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setMargin : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setMargin : horizontalMargin = " + horizontalMargin.ToString() + ", verticalMargin = " + verticalMargin.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setMargin : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setMargin : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (horizontalMargin < 0) horizontalMargin = 0;
            if (verticalMargin < 0) verticalMargin = 0;

            string printCommand = "SM";
            printCommand += horizontalMargin.ToString() + ",";
            printCommand += verticalMargin.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setMargin : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setMargin : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setBackFeedOption(bool bEnable, int stepQuantity = 0)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setBackFeedOption : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setBackFeedOption : bEnable = " + bEnable.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation setBackFeedOption : stepQuantity = " + stepQuantity.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setBackFeedOption : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setBackFeedOption : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            string printCommand = "SF";

            if (bEnable)
            {
                printCommand += "1,";
                printCommand += stepQuantity.ToString();
            }
            else
            {
                printCommand += "0";
            }

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setBackFeedOption : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setBackFeedOption : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        private int getMaxLength(string modelName)
        {
            int maxLenth = 32000;
            switch (modelName.Trim())
            {
                // GAZA
                case "SLP-TX220": maxLenth = 23640; break;
                case "SLP-TX223": maxLenth = 23640; break;
                case "SLP-TX420": maxLenth = 23640; break;
                case "SLP-TX423": maxLenth = 23640; break;
                case "SLP-DX420": maxLenth = 11820; break;
                case "SLP-DX423": maxLenth = 11820; break;
                case "SLP-DX220": maxLenth = 23640; break;
                case "SLP-DX223": maxLenth = 23640; break;
                case "SLP-DL410": maxLenth = 23640; break;
                case "SLP-DL413": maxLenth = 23640; break;
                case "SLP-TX400": maxLenth = 11820; break;
                case "SLP-TX403": maxLenth = 11820; break;
                case "SRP-770III": maxLenth = 8000; break;
                case "SRP-E770III": maxLenth = 8000; break;
                // GAZA (Bluetooth)
                case "SLP-TX220B": maxLenth = 23640; break;
                case "SLP-TX223B": maxLenth = 23640; break;
                case "SLP-TX420B": maxLenth = 23640; break;
                case "SLP-TX423B": maxLenth = 23640; break;
                case "SLP-DX420B": maxLenth = 11820; break;
                case "SLP-DX423B": maxLenth = 11820; break;
                case "SLP-DX220B": maxLenth = 23640; break;
                case "SLP-DX223B": maxLenth = 23640; break;
                case "SLP-DL410B": maxLenth = 23640; break;
                case "SLP-DL413B": maxLenth = 23640; break;
                // GAZA
                case "XD3-40d": maxLenth = 8000; break;
                case "XD3-40t": maxLenth = 8000; break;
                case "XD5-40d": maxLenth = 11820; break;
                case "XD5-43d": maxLenth = 11820; break;
                case "XD5-40t": maxLenth = 11820; break;
                case "XD5-43t": maxLenth = 11820; break;
                case "XL5-40": maxLenth = 11820; break;
                case "XL5-43": maxLenth = 11820; break;
                // + RFID
                case "XD5-40tR": maxLenth = 11820; break;
                case "XD5-43tR": maxLenth = 11820; break;
                // GAZA (Industrial Printer)
                case "XT3-40": maxLenth = 32000; break;
                case "XT3-43": maxLenth = 24000; break;
                case "XT5-40": maxLenth = 32000; break;
                case "XT5-43": maxLenth = 32000; break;
                case "XT5-46": maxLenth = 24000; break;
                // GAZA (Industrial Printer) + RFID
                case "XT5-40NR": maxLenth = 32000; break;
                case "XT5-43NR": maxLenth = 32000; break;
                case "XT5-46NR": maxLenth = 24000; break;
                // GAZA (POS<->Label)
                case "SRP-S3000_LABEL": maxLenth = 8000; break;
                // Mobile Label
                case "SPP-L3000": maxLenth = 8000; break;
                case "SPP-L4000": maxLenth = 8000; break;
                case "SPP-L310": maxLenth = 8000; break;
                case "SPP-C200": maxLenth = 8000; break;
                case "SPP-C300": maxLenth = 8000; break;
                case "SPP-L410": maxLenth = 8000; break;
                case "SPP-L410II": maxLenth = 8000; break;
                case "XM7-40": maxLenth = 8000; break;
                case "XM7-30": maxLenth = 8000; break;
                case "XM7-20": maxLenth = 8000; break;
                // NEC
                case "SRP-770": maxLenth = 2600; break;
                case "SRP-770II": maxLenth = 2600; break;
                case "SLP-T400": maxLenth = 8000; break;
                case "SLP-D400": maxLenth = 8000; break;
                case "SLP-T403": maxLenth = 5200; break;
                case "SLP-D403": maxLenth = 5200; break;
                case "SLP-D420": maxLenth = 8000; break;
                case "SLP-D423": maxLenth = 5200; break;
                case "SLP-D220": maxLenth = 8000; break;
                case "SLP-D223": maxLenth = 5200; break;
                default:
                    maxLenth = 32000;
                    break;
            }
            return maxLenth;
        }
        public async Task<int> setLength(int labelLength, int gapLength, char mediaType, int offsetLength)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setLength : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setLength : labelLength = " + labelLength + ", gapLength = " + gapLength);
            MPosDebug.WriteLine("LabelPrinterImplementation setLength : mediaType = " + mediaType + ", offsetLength = " + offsetLength);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setLength : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setLength : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            bool isMember = Enum.GetValues(typeof(MPosLabelMediaType)).Cast<int>().Any(x => x == (int)mediaType);
            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setLength : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation setLength : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            int maxLength = getMaxLength(_ModelName);
            if (labelLength > maxLength)
                labelLength = maxLength;
            if (mediaType != 'C')
            {
                switch (_ModelName.Trim())
                {
                    case "SPP-L3000": labelLength = labelLength > 3200 ? 3200 : labelLength; break;
                    case "SPP-L310": labelLength = labelLength > 3200 ? 3200 : labelLength; break;
                    case "SPP-L4000": labelLength = labelLength > 4000 ? 4000 : labelLength; break;
                    case "SPP-L410": labelLength = labelLength > 4000 ? 4000 : labelLength; break;
                    case "SPP-L410II": labelLength = labelLength > 4000 ? 4000 : labelLength; break;
                    case "XM7-40": labelLength = labelLength > 4000 ? 4000 : labelLength; break;
                    case "XM7-30": labelLength = labelLength > 3200 ? 3200 : labelLength; break;
                    case "XM7-20": labelLength = labelLength > 3200 ? 3200 : labelLength; break;
                    case "XM7-40R": labelLength = labelLength > 4000 ? 4000 : labelLength; break;
                    default:
                        if (labelLength > 3200) labelLength = 3200;
                        break;
                }
            }

            if (labelLength < 0) labelLength = 0;
            if (gapLength < 0) gapLength = 0;
            if (offsetLength < 0) offsetLength = 0;

            string printCommand = "SL";
            printCommand += labelLength.ToString() + ",";
            printCommand += gapLength.ToString() + ",";
            printCommand += mediaType.ToString() + ",";
            printCommand += offsetLength.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setLength : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation setLength : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setWidth(int labelWidth)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setWidth : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setWidth : labelWidth = " + labelWidth.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setWidth : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setWidth : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (labelWidth < 0)
                labelWidth = 0;

            string printCommand = "SW";
            printCommand += labelWidth.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setWidth : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setWidth : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setBufferMode(bool doubleBufferEnable)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setBufferMode : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setBufferMode : doubleBufferEnable = " + doubleBufferEnable.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setBufferMode : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setBufferMode : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            string printCommand = "SB";

            if (doubleBufferEnable)
                printCommand += "1";
            else
                printCommand += "0";

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setBufferMode : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setBufferMode : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setSpeed(int speed)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setSpeed : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setSpeed : speed = " + speed.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setSpeed : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setSpeed : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (speed < 0)
                speed = 0;

            string printCommand = "SS";
            printCommand += speed.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setSpeed : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setSpeed : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setDensity(int density)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setDensity : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setDensity : density = " + density.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setDensity : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setDensity : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (density < 0) density = 0;
            if (density > 20) density = 20;

            string printCommand = "SD";
            printCommand += density.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setDensity : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setDensity : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setOrientation(char orientation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setOrientation : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setOrientation : orientation = " + orientation.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setOrientation : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setOrientation : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

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

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setOrientation : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation setOrientation : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            string printCommand = "SO" + orientation.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setOrientation : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setOrientation : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setOffset(int offset)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setOffset : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setOffset : offset = " + offset.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setOffset : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setOffset : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (offset < -100) offset = -100;
            if (offset > 100) offset = 100;

            string printCommand = "SA";

            if (offset >= 0)
            {
                printCommand += offset.ToString();
            }
            else
            {
                offset = (offset * (-1));
                printCommand += ("-" + offset.ToString());
            }

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setOffset : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setOffset : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setCuttingPosition(int cuttingPosition)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setCuttingPosition : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setCuttingPosition : cuttingPosition = " + cuttingPosition.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setCuttingPosition : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setCuttingPosition : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (cuttingPosition < -100) cuttingPosition = -100;
            if (cuttingPosition > 100) cuttingPosition = 100;

            string printCommand = "TA";

            if (cuttingPosition >= 0)
            {
                printCommand += cuttingPosition.ToString();
            }
            else
            {
                cuttingPosition = (cuttingPosition * (-1));
                printCommand += ("-" + cuttingPosition.ToString());
            }

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setCuttingPosition : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setCuttingPosition : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> setAutoCutter(bool enable, int period = 1 /*every page*/)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setAutoCutter : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setAutoCutter : enable = " + enable + ", period = " + period);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setAutoCutter : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setAutoCutter : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            if (period <= 0)
                period = 1;

            string printCommand = "CUT";

            if (enable)
            {
                printCommand += "y," + period.ToString();
            }
            else
            {
                printCommand += "n";
            }

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation setAutoCutter : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation setAutoCutter : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
    }
    internal partial class MPosDeviceLabelPrinterImplementation : MPosControllerLabelPrinter
    {
        public async Task<int> drawCircle(int startPosX, int startPosY, int sizeSelection, int multiplier)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawCircle : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawCircle : startPosX = " + startPosX + ", startPosY = " + startPosY + ", sizeSelection = " + sizeSelection + ", multiplier = " + multiplier);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawCircle : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawCircle : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = Enum.GetValues(typeof(MPosLabelCircle)).Cast<int>().Any(x => x == (int)sizeSelection);

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawCircle : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawCircle : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (startPosX < 0) startPosX = 0;
            if (startPosY < 0) startPosY = 0;
            if (multiplier < 1) multiplier = 1;
            if (multiplier > 4) multiplier = 4;

            string printCommand = "CD";
            printCommand += startPosX.ToString() + ",";
            printCommand += startPosY.ToString() + ",";
            printCommand += sizeSelection.ToString() + ",";
            printCommand += multiplier.ToString();

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation drawCircle : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawCircle : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawImage(object bitmapSrc, int startPosX, int startPosY, int width, int brightness = 50, bool isDithering = true, bool isCompress = true)
        {
            int result = (int)MPosResult.MPOS_FAIL;
            MPosDebug.WriteLine("LabelPrinterImplementation drawImage : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawImage : brightness = " + brightness + ", startPosX = " + startPosX + ", startPosY = " + startPosY);

            if (!IsOpen){
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var writeableBmp = bitmapSrc as WriteableBitmap;

            if (writeableBmp == null)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (width == 0)
            {
                // Image width cannot be Zero (0)
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            try
            {
                uint[] imgSize = new uint[] { 0, 0 };
                byte[] imgData = null;
                byte[] pixelImgData = null;

                Guid encoderId = BitmapEncoder.BmpEncoderId;
                Guid decoderId = BitmapDecoder.BmpDecoderId;
                StorageFile file = null;

                for (int i = 0; i < 6; i++)
                {
                    switch (i)
                    {
                        case 0: encoderId = BitmapEncoder.BmpEncoderId; decoderId = BitmapDecoder.BmpDecoderId; break;
                        case 1: encoderId = BitmapEncoder.PngEncoderId; decoderId = BitmapDecoder.PngDecoderId; break;
                        case 2: encoderId = BitmapEncoder.JpegEncoderId; decoderId = BitmapDecoder.JpegDecoderId; break;
                        case 3: encoderId = BitmapEncoder.GifEncoderId; decoderId = BitmapDecoder.GifDecoderId; break;
                        case 4: encoderId = BitmapEncoder.TiffEncoderId; decoderId = BitmapDecoder.TiffDecoderId; break;
                        case 5: encoderId = BitmapEncoder.JpegXREncoderId; decoderId = BitmapDecoder.JpegXRDecoderId; break;
                    }

                    file = await MPosImagePrintCommand.writeableBitmapToStorageFile(writeableBmp, encoderId);

                    if (file != null)
                    {
                        pixelImgData = await MPosImagePrintCommand.getResizedPixelData(file, decoderId, width, imgSize);
                        file = null;
                        await MPosImagePrintCommand.deleteTempImageFile();
                    }

                    if (pixelImgData != null)
                        break;
                }

                if (pixelImgData != null)
                {
                    if (isCompress)
                        imgData = MPosImagePrintCommand.getLabelRleCmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], (uint)(brightness > 0 ? brightness : 50), isDithering);
                    else
                        imgData = MPosImagePrintCommand.getLabelLDCmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], (uint)(brightness > 0 ? brightness : 50), isDithering);

                    if (imgData != null)
                    {
                        var dataToSend = MPosByteArrayHelper.concat(imgData, Encoding.ASCII.GetBytes("\r\n"));
                        var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
                        MPosDebug.WriteLine("PrinterImplementation drawImage : written bytes = " + writtenBytes.ToString());
                        MPosDebug.WriteLine("PrinterImplementation drawImage : END");

                        if (writtenBytes <= 0)
                            result = (int)MPosResult.MPOS_FAIL;
                        result = (int)MPosResult.MPOS_SUCCESS;
                    }

                    pixelImgData = null;
                }
            }
            catch (Exception ex)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : Exception Code = 0x" + ex.HResult.ToString("X2"));
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : Exception = " + ex.ToString());
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
                if ((uint)ex.HResult == 0x80070005) // UnauthorizedAccessException
                    throw ex;
                if ((uint)ex.HResult == 0x80070002) // FileNotFoundException
                    throw ex;
            }

            MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
            return result;
        }

        public async Task<int> drawImage(object bitmapSrc, int startPosX, int startPosY, int width, int threshold = 128, int ditheringType = 1, int compressType = 1)
        {
            int result = (int)MPosResult.MPOS_FAIL;
            MPosDebug.WriteLine("LabelPrinterImplementation drawImage : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawImage : threshold = " + threshold + ", startPosX = " + startPosX + ", startPosY = " + startPosY);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var writeableBmp = bitmapSrc as WriteableBitmap;

            if (writeableBmp == null)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (width == 0)
            {
                // Image width cannot be Zero (0)
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            try
            {
                uint[] imgSize = new uint[] { 0, 0 };
                byte[] imgData = null;
                byte[] pixelImgData = null;

                Guid encoderId = BitmapEncoder.BmpEncoderId;
                Guid decoderId = BitmapDecoder.BmpDecoderId;
                StorageFile file = null;

                for (int i = 0; i < 6; i++)
                {
                    switch (i)
                    {
                        case 0: encoderId = BitmapEncoder.BmpEncoderId; decoderId = BitmapDecoder.BmpDecoderId; break;
                        case 1: encoderId = BitmapEncoder.PngEncoderId; decoderId = BitmapDecoder.PngDecoderId; break;
                        case 2: encoderId = BitmapEncoder.JpegEncoderId; decoderId = BitmapDecoder.JpegDecoderId; break;
                        case 3: encoderId = BitmapEncoder.GifEncoderId; decoderId = BitmapDecoder.GifDecoderId; break;
                        case 4: encoderId = BitmapEncoder.TiffEncoderId; decoderId = BitmapDecoder.TiffDecoderId; break;
                        case 5: encoderId = BitmapEncoder.JpegXREncoderId; decoderId = BitmapDecoder.JpegXRDecoderId; break;
                    }

                    file = await MPosImagePrintCommand.writeableBitmapToStorageFile(writeableBmp, encoderId);

                    if (file != null)
                    {
                        pixelImgData = await MPosImagePrintCommand.getResizedPixelData(file, decoderId, width, imgSize);
                        file = null;
                        await MPosImagePrintCommand.deleteTempImageFile();
                    }

                    if (pixelImgData != null)
                        break;
                }

                if (pixelImgData != null)
                {
                    bool isDithering = true;
                    if (ditheringType == 0) isDithering = false;
                    if ((MPosLabelCompressType)compressType == MPosLabelCompressType.MPOS_LABEL_IMAGE_COMPRESS_RLE)
                        imgData = MPosImagePrintCommand.getLabelRleCmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], 50, isDithering, threshold);
                    else if ((MPosLabelCompressType)compressType == MPosLabelCompressType.MPOS_LABEL_IMAGE_COMPRESS_LZMA)
                        imgData = MPosImagePrintCommand.getLabelLZMACmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], 50, isDithering, threshold);
                    else
                        imgData = MPosImagePrintCommand.getLabelLDCmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], 50, isDithering, threshold);

                    if (imgData != null)
                    {
                        var dataToSend = MPosByteArrayHelper.concat(imgData, Encoding.ASCII.GetBytes("\r\n"));
                        var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
                        MPosDebug.WriteLine("PrinterImplementation drawImage : written bytes = " + writtenBytes.ToString());
                        MPosDebug.WriteLine("PrinterImplementation drawImage : END");

                        if (writtenBytes <= 0)
                            result = (int)MPosResult.MPOS_FAIL;
                        result = (int)MPosResult.MPOS_SUCCESS;
                    }

                    pixelImgData = null;
                }
            }
            catch (Exception ex)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : Exception Code = 0x" + ex.HResult.ToString("X2"));
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : Exception = " + ex.ToString());
                MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
                if ((uint)ex.HResult == 0x80070005) // UnauthorizedAccessException
                    throw ex;
                if ((uint)ex.HResult == 0x80070002) // FileNotFoundException
                    throw ex;
            }

            MPosDebug.WriteLine("LabelPrinterImplementation drawImage : END");
            return result;
        }
        public async Task<int> drawImageFile(string filePath, int startPosX, int startPosY, int width, int brightness = 50, bool isDithering = true, bool isCompress = true)
        {
            int result = (int)MPosResult.MPOS_FAIL;
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : filePath = " + filePath + ", brightness = " + brightness + ", startPosX = " + startPosX + ", startPosY = " + startPosY);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            Guid decoderId;
            var upperfilePath = filePath.ToUpper();
            if (upperfilePath.Contains(".JPG")) decoderId = BitmapDecoder.JpegDecoderId;
            else if (upperfilePath.Contains(".JPEG")) decoderId = BitmapDecoder.JpegDecoderId;
            else if (upperfilePath.Contains(".GIF")) decoderId = BitmapDecoder.GifDecoderId;
            else if (upperfilePath.Contains(".PNG")) decoderId = BitmapDecoder.PngDecoderId;
            else if (upperfilePath.Contains(".BMP")) decoderId = BitmapDecoder.BmpDecoderId;
            else
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : MPOS_FAIL_NOT_SUPPORTED_IMAGE_TYPE");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
                throw new Exception("NOT SUPPORTED IMAGE TYPE");
                //return (int)MPosResult.MPOS_FAIL_NOT_SUPPORTED_IMAGE_TYPE;
            }

            if (width == 0)
            {
                // Image width cannot be Zero (0)
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            try
            {
                StorageFile file = null;
                uint[] imgSize = new uint[] { 0, 0 };
                byte[] imgData = null;
                byte[] pixelImgData = null;

                if (filePath.Contains("ms-appx:///") || filePath.Contains("ms-appdata:///") || filePath.Contains("ms-appx-web:///"))
                    file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(filePath));
                else
                    file = await StorageFile.GetFileFromPathAsync(filePath);

                pixelImgData = await MPosImagePrintCommand.getResizedPixelData(file, decoderId, width, imgSize);

                if (isCompress)
                    imgData = MPosImagePrintCommand.getLabelRleCmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], (uint)(brightness > 0 ? brightness : 50), isDithering);
                else
                    imgData = MPosImagePrintCommand.getLabelLDCmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], (uint)(brightness > 0 ? brightness : 50), isDithering);

                if (imgData != null)
                {
                    var dataToSend = MPosByteArrayHelper.concat(imgData, Encoding.ASCII.GetBytes("\r\n"));
                    var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : written bytes = " + writtenBytes.ToString());
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");

                    if (writtenBytes <= 0)
                        result = (int)MPosResult.MPOS_FAIL;
                    result = (int)MPosResult.MPOS_SUCCESS;
                }
            }
            catch (Exception ex)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : Exception Code = 0x" + ex.HResult.ToString("X2"));
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : Exception = " + ex.ToString());
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
                if ((uint)ex.HResult == 0x80070005) // UnauthorizedAccessException
                    throw ex;
                if ((uint)ex.HResult == 0x80070002) // FileNotFoundException
                    throw ex;
            }

            MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
            return result;
        }
        public async Task<int> drawImageFile(string filePath, int startPosX, int startPosY, int width, int threshold = 128, int ditheringType = 1, int compressType = 1)
        {
            //return await drawImageFile(filePath, startPosX, startPosY, width, brightness, ditheringType == 1, compressType == 1);
            int result = (int)MPosResult.MPOS_FAIL;
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : filePath = " + filePath + ", threshold = " + threshold + ", startPosX = " + startPosX + ", startPosY = " + startPosY);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            Guid decoderId;
            var upperfilePath = filePath.ToUpper();
            if (upperfilePath.Contains(".JPG")) decoderId = BitmapDecoder.JpegDecoderId;
            else if (upperfilePath.Contains(".JPEG")) decoderId = BitmapDecoder.JpegDecoderId;
            else if (upperfilePath.Contains(".GIF")) decoderId = BitmapDecoder.GifDecoderId;
            else if (upperfilePath.Contains(".PNG")) decoderId = BitmapDecoder.PngDecoderId;
            else if (upperfilePath.Contains(".BMP")) decoderId = BitmapDecoder.BmpDecoderId;
            else
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : MPOS_FAIL_NOT_SUPPORTED_IMAGE_TYPE");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
                throw new Exception("NOT SUPPORTED IMAGE TYPE");
                //return (int)MPosResult.MPOS_FAIL_NOT_SUPPORTED_IMAGE_TYPE;
            }

            if (width == 0)
            {
                // Image width cannot be Zero (0)
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            try
            {
                StorageFile file = null;
                uint[] imgSize = new uint[] { 0, 0 };
                byte[] imgData = null;
                byte[] pixelImgData = null;

                if (filePath.Contains("ms-appx:///") || filePath.Contains("ms-appdata:///") || filePath.Contains("ms-appx-web:///"))
                    file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(filePath));
                else
                    file = await StorageFile.GetFileFromPathAsync(filePath);

                pixelImgData = await MPosImagePrintCommand.getResizedPixelData(file, decoderId, width, imgSize);
                bool isDithering = true;
                if (ditheringType == 0) isDithering = false;
                if ((MPosLabelCompressType)compressType == MPosLabelCompressType.MPOS_LABEL_IMAGE_COMPRESS_RLE)
                    imgData = MPosImagePrintCommand.getLabelRleCmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], 50, isDithering, threshold);
                else if ((MPosLabelCompressType)compressType == MPosLabelCompressType.MPOS_LABEL_IMAGE_COMPRESS_LZMA)
                    imgData = MPosImagePrintCommand.getLabelLZMACmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], 50, isDithering, threshold);
                else
                    imgData = MPosImagePrintCommand.getLabelLDCmd(pixelImgData, (uint)startPosX, (uint)startPosY, imgSize[0], imgSize[1], 50, isDithering, threshold);

                if (imgData != null)
                {
                    var dataToSend = MPosByteArrayHelper.concat(imgData, Encoding.ASCII.GetBytes("\r\n"));
                    var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : written bytes = " + writtenBytes.ToString());
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");

                    if (writtenBytes <= 0)
                        result = (int)MPosResult.MPOS_FAIL;
                    result = (int)MPosResult.MPOS_SUCCESS;
                }
            }
            catch (Exception ex)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : Exception Code = 0x" + ex.HResult.ToString("X2"));
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : Exception = " + ex.ToString());
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
                if ((uint)ex.HResult == 0x80070005) // UnauthorizedAccessException
                    throw ex;
                if ((uint)ex.HResult == 0x80070002) // FileNotFoundException
                    throw ex;
            }

            MPosDebug.WriteLine("LabelPrinterImplementation drawImageFile : END");
            return result;
        }
        public async Task<int> drawImageWithBase64(string base64String, int xPos, int yPos, int width, int brightness = 50, bool isDithering = true, bool isCompress = true)
        {
            int result = (int)MPosResult.MPOS_FAIL;
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : brightness = " + brightness + ", xPos = " + xPos + ", yPos = " + yPos + ", width = " + width);
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : isCompress = " + isCompress + ", base64String.Length = " + base64String.Length + ", isDithering = " + isDithering);

            if (!IsOpen){
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            try
            {
                var randomAccessStream = new InMemoryRandomAccessStream();

                using (var dataWriter = new DataWriter(randomAccessStream))
                {
                    // read stream
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : FromBase64String");
                    dataWriter.WriteBytes(Convert.FromBase64String(base64String));
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : StoreAsync");
                    await dataWriter.StoreAsync();
                    // decode image
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : CreateAsync");
                    var decoder = await BitmapDecoder.CreateAsync(randomAccessStream);
                    randomAccessStream.Seek(0);

                    // Get the SoftwareBitmap representation of the file
                    SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : PixelHeight = " + softwareBitmap.PixelHeight + ", PixelWidth = " + softwareBitmap.PixelWidth);

                    byte[] imgData = null;
                    UInt32 resizeWidth = 0;
                    UInt32 resizeHeight = 0;

                    if (width == (int)MPosImageWidth.MPOS_IMAGE_WIDTH_ASIS || width < 0){
                        resizeWidth = decoder.PixelWidth;
                        resizeHeight = decoder.PixelHeight;
                    }
                    else{
                        resizeWidth = (UInt32)width;
                        resizeHeight = (UInt32)((decoder.PixelHeight * resizeWidth) / decoder.PixelWidth);
                    }

                    BitmapTransform resizeForm = new BitmapTransform()
                    {
                        ScaledWidth = resizeWidth,
                        ScaledHeight = resizeHeight
                    };

                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : PixelWidth = " + decoder.PixelWidth + ", PixelHeight = " + decoder.PixelHeight);
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : resizeWidth = " + resizeWidth + ", resizeHeight = " + resizeHeight);

                    PixelDataProvider pixelDataProvider = await decoder.GetPixelDataAsync(
                                          BitmapPixelFormat.Bgra8,    // WriteableBitmap uses BGRA format
                                          BitmapAlphaMode.Straight,
                                          resizeForm,
                                          ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
                                          ColorManagementMode.DoNotColorManage);

                    if(pixelDataProvider != null)
                    {
                        if (isCompress)
                        {
                            imgData = MPosImagePrintCommand.getLabelRleCmd(pixelDataProvider.DetachPixelData(),
                                                                            (uint)xPos,
                                                                            (uint)yPos,
                                                                            resizeForm.ScaledWidth,
                                                                            resizeForm.ScaledHeight,
                                                                            (uint)(brightness > 0 ? brightness : 50),
                                                                            isDithering);
                        }
                        else
                        {
                            imgData = MPosImagePrintCommand.getLabelLDCmd(pixelDataProvider.DetachPixelData(),
                                                                            (uint)xPos,
                                                                            (uint)yPos,
                                                                            resizeForm.ScaledWidth,
                                                                            resizeForm.ScaledHeight,
                                                                            (uint)(brightness > 0 ? brightness : 50),
                                                                            isDithering);
                        }

                        if (imgData != null)
                        {
                            var dataToSend = MPosByteArrayHelper.concat(imgData, Encoding.ASCII.GetBytes("\r\n"));
                            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
                            MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : written bytes = " + writtenBytes + ", dataToSend = " + dataToSend.Length);
                            if (writtenBytes == dataToSend.Length)
                                result = (int)MPosResult.MPOS_SUCCESS;
                        }
                    }
                }

            }
            catch (Exception ex){
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : ex = " + ex.Message);
            }

            return result;
        }
        public async Task<int> drawImageWithBase64(string base64String, int xPos, int yPos, int width, int threshold = 128, int ditheringType = 1, int compressType = 1)
        {
            int result = (int)MPosResult.MPOS_FAIL;
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : threshold = " + threshold + ", xPos = " + xPos + ", yPos = " + yPos + ", width = " + width);
            MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : compressType = " + compressType + ", base64String.Length = " + base64String.Length + ", ditheringType = " + ditheringType);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            try
            {
                var randomAccessStream = new InMemoryRandomAccessStream();

                using (var dataWriter = new DataWriter(randomAccessStream))
                {
                    // read stream
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : FromBase64String");
                    dataWriter.WriteBytes(Convert.FromBase64String(base64String));
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : StoreAsync");
                    await dataWriter.StoreAsync();
                    // decode image
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : CreateAsync");
                    var decoder = await BitmapDecoder.CreateAsync(randomAccessStream);
                    randomAccessStream.Seek(0);

                    // Get the SoftwareBitmap representation of the file
                    SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : PixelHeight = " + softwareBitmap.PixelHeight + ", PixelWidth = " + softwareBitmap.PixelWidth);

                    byte[] imgData = null;
                    UInt32 resizeWidth = 0;
                    UInt32 resizeHeight = 0;

                    if (width == (int)MPosImageWidth.MPOS_IMAGE_WIDTH_ASIS || width < 0)
                    {
                        resizeWidth = decoder.PixelWidth;
                        resizeHeight = decoder.PixelHeight;
                    }
                    else
                    {
                        resizeWidth = (UInt32)width;
                        resizeHeight = (UInt32)((decoder.PixelHeight * resizeWidth) / decoder.PixelWidth);
                    }

                    BitmapTransform resizeForm = new BitmapTransform()
                    {
                        ScaledWidth = resizeWidth,
                        ScaledHeight = resizeHeight
                    };

                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : PixelWidth = " + decoder.PixelWidth + ", PixelHeight = " + decoder.PixelHeight);
                    MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : resizeWidth = " + resizeWidth + ", resizeHeight = " + resizeHeight);

                    PixelDataProvider pixelDataProvider = await decoder.GetPixelDataAsync(
                                          BitmapPixelFormat.Bgra8,    // WriteableBitmap uses BGRA format
                                          BitmapAlphaMode.Straight,
                                          resizeForm,
                                          ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
                                          ColorManagementMode.DoNotColorManage);

                    if (pixelDataProvider != null)
                    {
                        bool isDithering = true;
                        if (ditheringType == 0) isDithering = false;

                        if ((MPosLabelCompressType)compressType == MPosLabelCompressType.MPOS_LABEL_IMAGE_COMPRESS_RLE)
                        {
                            imgData = MPosImagePrintCommand.getLabelRleCmd(pixelDataProvider.DetachPixelData(),
                                                                            (uint)xPos,
                                                                            (uint)yPos,
                                                                            resizeForm.ScaledWidth,
                                                                            resizeForm.ScaledHeight,
                                                                            50,
                                                                            isDithering,
                                                                            threshold);
                        }
                        else if ((MPosLabelCompressType)compressType == MPosLabelCompressType.MPOS_LABEL_IMAGE_COMPRESS_LZMA)
                        {
                            imgData = MPosImagePrintCommand.getLabelLZMACmd(pixelDataProvider.DetachPixelData(),
                                                                            (uint)xPos,
                                                                            (uint)yPos,
                                                                            resizeForm.ScaledWidth,
                                                                            resizeForm.ScaledHeight,
                                                                            50,
                                                                            isDithering,
                                                                            threshold);
                        }
                        else
                        {
                            imgData = MPosImagePrintCommand.getLabelLDCmd(pixelDataProvider.DetachPixelData(),
                                                                            (uint)xPos,
                                                                            (uint)yPos,
                                                                            resizeForm.ScaledWidth,
                                                                            resizeForm.ScaledHeight,
                                                                            50,
                                                                            isDithering,
                                                                            threshold);
                        }

                        if (imgData != null)
                        {
                            var dataToSend = MPosByteArrayHelper.concat(imgData, Encoding.ASCII.GetBytes("\r\n"));
                            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
                            MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : written bytes = " + writtenBytes + ", dataToSend = " + dataToSend.Length);
                            if (writtenBytes == dataToSend.Length)
                                result = (int)MPosResult.MPOS_SUCCESS;
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawImageWithBase64 : ex = " + ex.Message);
            }

            return result;
        }
        public async Task<int> drawBlock(int startPosX, int startPosY, int endPosX, int endPosY, char option = 'B', int thickness = 2)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBlock : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBlock : startPosX = " + startPosX + ", startPosY = " + startPosY);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBlock : endPosX = " + endPosX + ", endPosY = " + endPosY + ", option = " + option + ", thickness = " + thickness);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBlock : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBlock : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = Enum.GetValues(typeof(MPosLabelBlock)).Cast<int>().Any(x => x == (int)option);

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBlock : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBlock : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (startPosX < 0) startPosX = 0;
            if (startPosY < 0) startPosY = 0;
            if (endPosX < 0) endPosX = 0;
            if (endPosY < 0) endPosY = 0;
            if (thickness < 1) thickness = 1;

            string printCommand = "BD";
            printCommand += startPosX.ToString() + ",";
            printCommand += startPosY.ToString() + ",";
            printCommand += endPosX.ToString() + ",";
            printCommand += endPosY.ToString() + ",";

            switch ((MPosLabelBlock)option)
            {
                case MPosLabelBlock.MPOS_LABEL_DRAW_BLOCK_OPTION_LINE_OVERWRITING:
                case MPosLabelBlock.MPOS_LABEL_DRAW_BLOCK_OPTION_LINE_EXCLUSIVE_OR:
                case MPosLabelBlock.MPOS_LABEL_DRAW_BLOCK_OPTION_LINE_DELETE:
                    printCommand += option.ToString();
                    break;
                case MPosLabelBlock.MPOS_LABEL_DRAW_BLOCK_OPTION_SLOPE:
                case MPosLabelBlock.MPOS_LABEL_DRAW_BLOCK_OPTION_BOX:
                    printCommand += option.ToString() + ",";
                    printCommand += thickness.ToString();
                    break;
            }

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation drawBlock : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBlock : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcode1D(string data, int xPos, int yPos, int barcodeType, int widthNarrow, int widthWide, int height, int hri, int quietZoneWidth, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : data = " + data + ", xPos = " + xPos + ", yPos = " + yPos);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : barcodeType = " + barcodeType + ", widthNarrow = " + widthNarrow + ", widthWide = " + widthWide);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : height = " + height + ", hri = " + hri + ", quietZoneWidth = " + quietZoneWidth + ", rotation = " + rotation);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelHRI)).Cast<int>().Any(x => x == (int)hri);
            isMember[1] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);
            isMember[2] = Enum.GetValues(typeof(MPosLabel1dCodeType)).Cast<int>().Any(x => x == (int)barcodeType);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (quietZoneWidth < 0) quietZoneWidth = 0;
            if (quietZoneWidth > 20) quietZoneWidth = 20;

            string printCommand = "B1";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += barcodeType.ToString() + ",";
            printCommand += widthNarrow.ToString() + ",";
            printCommand += widthWide.ToString() + ",";
            printCommand += height.ToString() + ",";
            printCommand += rotation.ToString() + ",";
            printCommand += hri.ToString() + ",";
            printCommand += quietZoneWidth.ToString() + ",";

            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcode1D : printCommand = " + printCommand);
            printCommand += "'" + data + "'";

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand + "\r\n"));
            MPosDebug.WriteLine("PrinterImplementation drawBarcode1D : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcode1D : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeMaxiCode(string data, int xPos, int yPos, int mode)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMaxiCode : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMaxiCode : data = " + data + ", xPos = " + xPos + ", yPos = " + yPos);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMaxiCode : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMaxiCode : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

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

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMaxiCode : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMaxiCode : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;

            string printCommand = "B2";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "M" + ",";   // MAXICODE
            printCommand += mode.ToString() + ",";

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMaxiCode : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeMaxiCode : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeMaxiCode : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }

        public async Task<int> drawBarcodePDF417(string data, int xPos, int yPos, int maximumRowCount, int maximumColumnCount, int errorCorrectionLevel,
                                int dataCompressionMethod, bool hri, int barcodeOriginPoint, int moduleWidth, int barHeight, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : data = " + data + ", xPos = " + xPos + ", yPos = " + yPos);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : errorCorrectionLevel = " + errorCorrectionLevel + ", dataCompressionMethod = " + dataCompressionMethod);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : printBarcodeText = " + hri + ", barcodeOriginPoint = " + barcodeOriginPoint);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : moduleWidth = " + moduleWidth + ", barHeight = " + barHeight + ", rotation = " + rotation);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true, true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelPDF417ECL)).Cast<int>().Any(x => x == (int)errorCorrectionLevel);
            isMember[1] = Enum.GetValues(typeof(MPosLabelPDF41Compress)).Cast<int>().Any(x => x == (int)dataCompressionMethod);
            isMember[2] = Enum.GetValues(typeof(MPosLabelPDF41StartPosition)).Cast<int>().Any(x => x == (int)barcodeOriginPoint);
            isMember[3] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (maximumRowCount < 3) maximumRowCount = 3;
            if (maximumRowCount > 90) maximumRowCount = 90;
            if (maximumColumnCount < 1) maximumColumnCount = 1;
            if (maximumColumnCount > 30) maximumColumnCount = 30;
            if (moduleWidth < 2) moduleWidth = 2;
            if (moduleWidth > 9) moduleWidth = 9;
            if (barHeight < 4) barHeight = 4;
            if (barHeight > 99) barHeight = 99;

            string printCommand = "B2";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "P" + ",";  // PDF417
            printCommand += maximumRowCount.ToString() + ",";
            printCommand += maximumColumnCount.ToString() + ",";
            printCommand += errorCorrectionLevel.ToString() + ",";
            printCommand += dataCompressionMethod.ToString() + ",";
            if (hri) printCommand += "1" + ",";
            else printCommand += "0" + ",";
            printCommand += barcodeOriginPoint.ToString() + ",";
            printCommand += moduleWidth.ToString() + ",";
            printCommand += barHeight.ToString() + ",";
            printCommand += rotation.ToString() + ",";
            printCommand += "'" + data + "'\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePDF417 : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodePDF417 : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodePDF417 : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeQRCode(string data, int xPos, int yPos, int size, int model, int errorCorrectionLevel, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeQRCode : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeQRCode : data = " + data + ", xPos = " + xPos + ", yPos = " + yPos + ", model = " + model);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeQRCode : errorCorrectionLevel = " + errorCorrectionLevel + ", size = " + size + ", rotation = " + rotation);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeQRCode : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeQRCode : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelQRCodeModel)).Cast<int>().Any(x => x == (int)model);
            isMember[1] = Enum.GetValues(typeof(MPosLabelQRCodeECL)).Cast<int>().Any(x => x == (int)errorCorrectionLevel);
            isMember[2] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeQRCode : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeQRCode : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (size < 1) size = 1;
            if (size > 9) size = 9;

            string printCommand = "B2";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "Q" + ",";  // QR Code
            printCommand += model.ToString() + ",";
            printCommand += ((char)errorCorrectionLevel).ToString() + ",";
            printCommand += size.ToString() + ",";
            printCommand += rotation.ToString() + ",";
            printCommand += "'" + data + "'\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeQRCode : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeQRCode : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeQRCode : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeDataMatrix(string data, int xPos, int yPos, int size, bool reverse, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : data = " + data + ", xPos = " + xPos.ToString() + ", yPos = " + yPos.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : size = " + size.ToString() + ", reverse = " + reverse.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : rotation = " + rotation.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);

            if (!isMember){
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (size < 1) size = 1;
            if (size > 4) size = 4;

            string printCommand = "B2";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "D" + ",";  // DATA MATRIX
            printCommand += size.ToString() + ",";

            if (reverse)
                printCommand += "R" + ",";
            else
                printCommand += "N" + ",";

            printCommand += rotation.ToString() + ",";

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeDataMatrix : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeDataMatrix : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeDataMatrix : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeAztec(string data, int xPos, int yPos, int size, bool extendedChannel,
                                    int errorCorrectionLevel, bool menuSymbol, int numberOfSymbols, string optionalID, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : data = " + data + ", xPos = " + xPos + ", yPos = " + yPos + ", size = " + size);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : extendedChannel = " + extendedChannel + ",  errorCorrectionLevel = "+ errorCorrectionLevel);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : menuSymbol = " + menuSymbol + ",  numberOfSymbols = " + numberOfSymbols);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : optionalID = " + optionalID + ", rotation = " + rotation);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (size < 1) size = 1;
            if (size > 10) size = 10;
            if (errorCorrectionLevel < 0) errorCorrectionLevel = 0;
            if (errorCorrectionLevel > 300) errorCorrectionLevel = 300;
            if (numberOfSymbols < 1) numberOfSymbols = 1;
            if (numberOfSymbols > 26) numberOfSymbols = 26;

            string printCommand = "B2";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "A" + ",";  // AZTEC
            printCommand += size.ToString() + ",";

            if (extendedChannel)
                printCommand += "1" + ",";
            else
                printCommand += "0" + ",";

            printCommand += errorCorrectionLevel.ToString() + ",";

            if (menuSymbol)
                printCommand += "1" + ",";
            else
                printCommand += "0" + ",";

            printCommand += numberOfSymbols.ToString() + ",";
            printCommand += optionalID + ",";
            printCommand += rotation.ToString() + ",";

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeAztec : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeAztec : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeAztec : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeCode49(string data, int xPos, int yPos, int widthNarrow, int widthWide, int height, int hri, int startingMode, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : data = " + data + ", xPos = " + xPos.ToString() + ", yPos = " + yPos.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : widthNarrow = " + widthNarrow.ToString() + ", widthWide = " + widthWide.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : height = " + height.ToString() + ", hri = " + hri.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : rotation = " + rotation.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelCode49Mode)).Cast<int>().Any(x => x == (int)startingMode);
            isMember[1] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);
            isMember[2] = Enum.GetValues(typeof(MPosLabelHRI)).Cast<int>().Any(x => x == (int)hri);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (widthNarrow < 1) widthNarrow = 1;
            if (widthWide < 1) widthWide = 1;
            if (height < 1) height = 1;

            string printCommand = "B2";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "F" + ",";  // CODe49

            printCommand += widthNarrow.ToString() + ",";
            printCommand += widthWide.ToString() + ",";
            printCommand += height.ToString() + ",";

            switch ((MPosLabelHRI)hri)
            {
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE2:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE3:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE4:
                    printCommand += "1" + ",";
                    break;
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE2:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE3:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE4:
                    printCommand += "2" + ",";
                    break;
                default:
                    printCommand += "0" + ",";
                    break;
            }

            printCommand += startingMode.ToString() + ",";
            printCommand += rotation.ToString() + ",";

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCode49 : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeCode49 : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeCode49 : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeCodaBlock(string data, int xPos, int yPos, int widthNarrow, int widthWide, int height, bool securityLevel,
                                                    int numberOfCharactersPerRow, char mode, int numberOfRowToEncode)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : data = " + data + ", xPos = " + xPos + ", yPos = " + yPos);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : widthNarrow = " + widthNarrow + ", widthWide = " + widthWide + "height = " + height + ", securityLevel = " + securityLevel);
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : numberOfCharactersPerRow = " + numberOfCharactersPerRow + ", mode = " + mode + ", numberOfRowToEncode = " + numberOfRowToEncode);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelCodaBlockMode)).Cast<int>().Any(x => x == (int)mode);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (widthNarrow < 1) widthNarrow = 1;
            if (widthWide < 1) widthWide = 1;
            if (height < 1) height = 1;
            if (numberOfCharactersPerRow < 2) numberOfCharactersPerRow = 2;
            if (numberOfCharactersPerRow > 62) numberOfCharactersPerRow = 62;

            switch ((MPosLabelCodaBlockMode)mode)
            {
                case MPosLabelCodaBlockMode.MPOS_LABEL_CODABLOCK_MODE_A:
                    if (numberOfRowToEncode < 1) numberOfRowToEncode = 1;
                    if (numberOfRowToEncode > 18) numberOfRowToEncode = 18;
                    break;
                default:
                    if (numberOfRowToEncode < 2) numberOfRowToEncode = 2;
                    if (numberOfRowToEncode > 4) numberOfRowToEncode = 4;
                    break;
            }

            string printCommand = "B2";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "C" + ",";  // CODA BLOCK

            printCommand += widthNarrow.ToString() + ",";
            printCommand += widthWide.ToString() + ",";
            printCommand += height.ToString() + ",";

            if (securityLevel)
                printCommand += "1" + ",";
            else
                printCommand += "0" + ",";

            printCommand += numberOfCharactersPerRow.ToString() + ",";
            printCommand += mode.ToString() + ",";
            printCommand += numberOfRowToEncode.ToString() + ",";
            printCommand += "0" + ",";  // No Rotation

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeCodaBlock : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeCodaBlock : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeCodaBlock : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeMicroPDF(string data, int xPos, int yPos, int moduleWidth, int moduleHeight, int mode, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : data = " + data + ", xPos = " + xPos.ToString() + ", yPos = " + yPos.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : moduleWidth = " + moduleWidth.ToString() + ", moduleHeight = " + moduleHeight.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : mode = " + mode.ToString() + ", rotation = " + rotation.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (moduleWidth < 2) moduleWidth = 2;
            if (moduleWidth > 8) moduleWidth = 8;
            if (moduleHeight < 1) moduleHeight = 1;
            if (moduleHeight > 99) moduleHeight = 99;
            if (mode < 0) mode = 0;
            if (mode > 33) mode = 33;

            string printCommand = "B2";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "B" + ",";  // Micro PDF417

            printCommand += moduleWidth.ToString() + ",";
            printCommand += moduleHeight.ToString() + ",";
            printCommand += mode.ToString() + ",";
            printCommand += rotation.ToString() + ",";

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMicroPDF : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeMicroPDF : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeMicroPDF : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeIMB(string data, int xPos, int yPos, bool hri, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeIMB : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeIMB : data = " + data + ", xPos = " + xPos.ToString() + ", yPos = " + yPos.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeIMB : hri = " + hri.ToString() + ", rotation = " + rotation.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeIMB : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeIMB : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeIMB : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeIMB : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;

            string printCommand = "B3";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "I" + ",";  // IMB(Intelligent Mail Barcode) 
            printCommand += rotation.ToString() + ",";

            if (hri)
                printCommand += "1" + ",";
            else
                printCommand += "0" + ",";

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeIMB : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeIMB : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeIMB : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeMSI(string data, int xPos, int yPos, int narrowWidth, int wideWidth, int height, int checkDigitSelection, bool printCheckDigit, int hri, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : data = " + data + ", xPos = " + xPos.ToString() + ", yPos = " + yPos.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : narrowWidth = " + narrowWidth.ToString() + ", wideWidth = " + wideWidth.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : height = " + height.ToString() + ", checkDigitSelection = " + checkDigitSelection.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : hri = " + hri.ToString() + ", rotation = " + rotation.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : printCheckDigit = " + printCheckDigit.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelMSICheckDigit)).Cast<int>().Any(x => x == (int)checkDigitSelection);
            isMember[1] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);
            isMember[2] = Enum.GetValues(typeof(MPosLabelHRI)).Cast<int>().Any(x => x == (int)hri);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (narrowWidth < 1) narrowWidth = 1;
            if (wideWidth < 1) wideWidth = 1;
            if (height < 1) height = 1;

            string printCommand = "B3";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "M" + ",";  // MSI

            printCommand += narrowWidth.ToString() + ",";
            printCommand += wideWidth.ToString() + ",";
            printCommand += height.ToString() + ",";
            printCommand += checkDigitSelection.ToString() + ",";

            if (printCheckDigit)
                printCommand += "1" + ",";
            else
                printCommand += "0" + ",";

            printCommand += rotation.ToString() + ",";

            switch ((MPosLabelHRI)hri)
            {
                case MPosLabelHRI.MPOS_BARCODE_TEXTNONE:
                    printCommand += "0" + ",";
                    break;
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE2:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE3:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE4:
                    printCommand += "1" + ",";
                    break;
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE2:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE3:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE4:
                    printCommand += "2" + ",";
                    break;
            }

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeMSI : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeMSI : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeMSI : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodePlessey(string data, int xPos, int yPos, int narrowWidth, int wideWidth, int height, bool printCheckDigit, int hri, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : data = " + data + ", xPos = " + xPos.ToString() + ", yPos = " + yPos.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : narrowWidth = " + narrowWidth.ToString() + ", wideWidth = " + wideWidth.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : height = " + height.ToString() + ", printCheckDigit = " + printCheckDigit.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : hri = " + hri.ToString() + ", rotation = " + rotation.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);
            isMember[1] = Enum.GetValues(typeof(MPosLabelHRI)).Cast<int>().Any(x => x == (int)hri);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (narrowWidth < 1) narrowWidth = 1;
            if (wideWidth < 1) wideWidth = 1;
            if (height < 1) height = 1;

            string printCommand = "B3";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "P" + ",";  // Plessey
            printCommand += narrowWidth.ToString() + ",";
            printCommand += wideWidth.ToString() + ",";
            printCommand += height.ToString() + ",";

            if (printCheckDigit)
                printCommand += "1" + ",";
            else
                printCommand += "0" + ",";

            printCommand += rotation.ToString() + ",";

            switch ((MPosLabelHRI)hri)
            {
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE2:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE3:
                case MPosLabelHRI.MPOS_BARCODE_TEXTBELOW_FONTSIZE4:
                    printCommand += "1" + ",";
                    break;
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE2:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE3:
                case MPosLabelHRI.MPOS_BARCODE_TEXTABOVE_FONTSIZE4:
                    printCommand += "2" + ",";
                    break;
                default:
                    printCommand += "0" + ",";
                    break;
            }

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodePlessey : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodePlessey : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodePlessey : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeTLC39(string data, int xPos, int yPos, int narrowWidth, int wideWidth, int height, int rowHeightOfMicroPDF417, int narrowWidthOfMicroPDF417, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : data = " + data + ", xPos = " + xPos.ToString() + ", yPos = " + yPos.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : narrowWidth = " + narrowWidth.ToString() + ", wideWidth = " + wideWidth.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : height = " + height.ToString() + ", narrowWidthOfMicroPDF417 = " + narrowWidthOfMicroPDF417.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : rowHeightOfMicroPDF417 = " + rowHeightOfMicroPDF417.ToString() + ", rotation = " + rotation.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (narrowWidth < 1) narrowWidth = 1;
            if (wideWidth < 1) wideWidth = 1;
            if (height < 1) height = 1;
            if (rowHeightOfMicroPDF417 < 1) rowHeightOfMicroPDF417 = 1;
            if (rowHeightOfMicroPDF417 > 255) rowHeightOfMicroPDF417 = 255;
            if (narrowWidthOfMicroPDF417 < 1) narrowWidthOfMicroPDF417 = 1;
            if (narrowWidthOfMicroPDF417 > 10) narrowWidthOfMicroPDF417 = 10;

            string printCommand = "B3";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "T" + ",";  // TLC39
            printCommand += narrowWidth.ToString() + ",";
            printCommand += wideWidth.ToString() + ",";
            printCommand += height.ToString() + ",";
            printCommand += rowHeightOfMicroPDF417.ToString() + ",";
            printCommand += narrowWidthOfMicroPDF417.ToString() + ",";
            printCommand += rotation.ToString() + ",";

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeTLC39 : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeTLC39 : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeTLC39 : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawBarcodeRSS(string data, int xPos, int yPos, int barcodeType, int magnification, int separatorHeight, int barcodeHeight, int segmentWidth, int rotation)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : data = " + data + ", xPos = " + xPos.ToString() + ", yPos = " + yPos.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : magnification = " + magnification.ToString() + ", separatorHeight = " + separatorHeight.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : barcodeHeight = " + barcodeHeight.ToString() + ", segmentWidth = " + segmentWidth.ToString());
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : rotation = " + rotation.ToString());

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelRSSType)).Cast<int>().Any(x => x == (int)barcodeType);
            isMember[1] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == (int)rotation);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0) xPos = 0;
            if (yPos < 0) yPos = 0;
            if (barcodeHeight < 0) barcodeHeight = 0;
            if (segmentWidth < 1) segmentWidth = 1;
            if (segmentWidth > 22) segmentWidth = 22;
            if (separatorHeight < 1) separatorHeight = 1;
            if (separatorHeight > 2) separatorHeight = 2;
            if (magnification < 1) magnification = 1;
            if (magnification > 10) magnification = 10;

            string printCommand = "B3";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += "R" + ",";  // RSS
            printCommand += barcodeType.ToString() + ",";
            printCommand += magnification.ToString() + ",";
            printCommand += separatorHeight.ToString() + ",";
            printCommand += barcodeHeight.ToString() + ",";
            printCommand += segmentWidth.ToString() + ",";
            printCommand += rotation.ToString() + ",";

            printCommand += "'" + data + "'\r\n";
            MPosDebug.WriteLine("LabelPrinterImplementation drawBarcodeRSS : printCommand = " + printCommand);
            var dataToSend = Encoding.UTF8.GetBytes(printCommand);
            //var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), Encoding.UTF8.GetBytes(data), Encoding.ASCII.GetBytes("'\r\n"));

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeRSS : written bytes = " + writtenBytes.ToString());
            MPosDebug.WriteLine("PrinterImplementation drawBarcodeRSS : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
        public async Task<int> drawTextVectorFont(string data, int xPos, int yPos, char fontSelection, int fontWidth, int fontHeight, int rightSpace, int rotation,
                                    bool reverse, bool bold, bool italic, bool rightToLeft, int alignment)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : data = " + data + ", xPos = " + xPos + ", yPos = " + yPos);
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : fontSelection = " + fontSelection + ", fontWidth = " + fontWidth + ", fontHeight = " + fontHeight);
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : rightSpace = " + rightSpace + ", rotation = " + rotation + ", reverse = " + reverse);
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : bold = " + bold + ", italic = " + italic + ", rightToLeft = " + rightToLeft + ", alignment = " + alignment);

            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : test-start");
            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : test-0");
            var isMember = new bool[] { true, true, true };
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : test-1");
            isMember[0] = Enum.GetValues(typeof(MPosLabelVectorFont)).Cast<int>().Any(x => x == fontSelection);
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : test-2");
            isMember[1] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == rotation);
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : test-3");
            isMember[2] = Enum.GetValues(typeof(MPosLabelAlignment)).Cast<int>().Any(x => x == alignment);
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : test-4");

            if (isMember.All(x => x == true) == false){
                MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0)           xPos = 0;
            if (yPos < 0)           yPos = 0;
            if (fontWidth <= 0)     fontWidth = 1;
            if (fontHeight <= 0)    fontHeight = 1;

            string printCommand = getCharSetSelectCommand((int)ICS, (int)CodePage) + "V";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += fontSelection.ToString() + ",";
            printCommand += fontWidth.ToString() + ",";
            printCommand += fontHeight.ToString() + ",";

            if (rightSpace >= 0)
            {
                printCommand += ("+" + rightSpace.ToString() + ",");
            }
            else
            {
                rightSpace = (rightSpace * -1);
                printCommand += ("-" + rightSpace.ToString() + ",");
            }

            if (bold)
                printCommand += "B" + ",";
            else
                printCommand += "N" + ",";

            if (reverse)
                printCommand += "R" + ",";
            else
                printCommand += "N" + ",";

            if (italic)
                printCommand += "I" + ",";
            else
                printCommand += "N" + ",";

            printCommand += rotation.ToString() + ",";

            if (rightToLeft == false)
            {
                switch ((MPosLabelAlignment)alignment)
                {
                    case MPosLabelAlignment.MPOS_LABEL_ALIGNMENT_LEFT:      printCommand += "L" + ","; break;
                    case MPosLabelAlignment.MPOS_LABEL_ALIGNMENT_RIGHT:     printCommand += "R" + ","; break;
                    case MPosLabelAlignment.MPOS_LABEL_ALIGNMENT_CENTER:    printCommand += "C" + ","; break;
                }
            }

            if (rightToLeft)
                printCommand += "1" + ",";
            else
                printCommand += "0" + ",";

            printCommand += "'";

            byte[] encodedTextData = null;

            switch ((MPosLabelVectorFont)fontSelection)
            {
                case MPosLabelVectorFont.MPOS_LABEL_VECTOR_FONT_ASCII:
                    encodedTextData = getEncodedTextData(data);
                    break;
                case MPosLabelVectorFont.MPOS_LABEL_VECTOR_FONT_KS5601:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : MPOS_CODEPAGE_KOREA_KS5601");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_KOREA_KS5601);
                    break;
                case MPosLabelVectorFont.MPOS_LABEL_VECTOR_FONT_BIG5:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : MPOS_CODEPAGE_CHINA_BIG5");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_CHINA_BIG5);
                    break;
                case MPosLabelVectorFont.MPOS_LABEL_VECTOR_FONT_GB2312:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : MPOS_CODEPAGE_CHINA_GB2312");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_CHINA_GB2312);
                    break;
                case MPosLabelVectorFont.MPOS_LABEL_VECTOR_FONT_SHIFT_JIS:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : MPOS_CODEPAGE_JAPAN_SHIFTJIS");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_JAPAN_SHIFTJIS);
                    break;
                case MPosLabelVectorFont.MPOS_LABEL_VECTOR_FONT_OCR_A:
                case MPosLabelVectorFont.MPOS_LABEL_VECTOR_FONT_OCR_B:
                    // Latin Characters only supported.
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextVectorFont : MPOS_LABEL_VECTOR_FONT_OCR");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_WPC1252);
                    break;
            }

            var result = (int)MPosResult.MPOS_SUCCESS;
            if (encodedTextData != null){
                var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), encodedTextData, Encoding.ASCII.GetBytes("'\r\n"));
                var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
                MPosDebug.WriteLine("PrinterImplementation drawTextVectorFont : written bytes = " + writtenBytes.ToString());
                if (writtenBytes <= 0)
                    result = (int)MPosResult.MPOS_FAIL;
            }
            MPosDebug.WriteLine("PrinterImplementation drawTextVectorFont : END");
            return result;
            
        }
        public async Task<int> drawTextDeviceFont(string data, int xPos, int yPos, char fontSelection, int fontWidth, int fontHeight,
                                                    int rightSpace, int rotation, bool reverse, bool bold, bool rightToLeft, int alignment)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : START");
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : data = " + data + ", xPos = " + xPos + ", yPos = " + yPos + ", fontSelection = " + fontSelection);
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : fontWidth = " + fontWidth + ", fontWidth = " + fontWidth + ", fontHeight = " + fontHeight + ", rightSpace = " + rightSpace);
            MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : rotation = " + rotation + ", reverse = " + reverse + ", bold = " + bold + ", rightToLeft = " + rightToLeft + ", alignment = " + alignment);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            var isMember = new bool[] { true, true, true };
            isMember[0] = Enum.GetValues(typeof(MPosLabelBitmapFont)).Cast<int>().Any(x => x == fontSelection);
            isMember[1] = Enum.GetValues(typeof(MPosLabelRotation)).Cast<int>().Any(x => x == rotation);
            isMember[2] = Enum.GetValues(typeof(MPosLabelAlignment)).Cast<int>().Any(x => x == alignment);

            if (isMember.All(x => x == true) == false)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            if (xPos < 0)           xPos = 0;
            if (yPos < 0)           yPos = 0;
            if (fontWidth <= 0)     fontWidth = 1;
            if (fontWidth > 4)      fontWidth = 4;
            if (fontHeight <= 0)    fontHeight = 1;
            if (fontHeight > 4)     fontHeight = 4;

            string printCommand = getCharSetSelectCommand((int)ICS, (int)CodePage) + "T";
            printCommand += xPos.ToString() + "," + yPos.ToString() + ",";
            printCommand += fontSelection.ToString() + ",";
            printCommand += fontWidth.ToString() + ",";
            printCommand += fontHeight.ToString() + ",";

            if (rightSpace >= 0)
            {
                printCommand += ("+" + rightSpace.ToString() + ",");
            }
            else
            {
                rightSpace = (rightSpace * -1);
                printCommand += ("-" + rightSpace.ToString() + ",");
            }

            printCommand += rotation.ToString() + ",";

            if (reverse)
                printCommand += "R" + ",";
            else
                printCommand += "N" + ",";

            if (bold)
                printCommand += "B" + ",";
            else
                printCommand += "N" + ",";

            if (rightToLeft)
            {
                printCommand += "R" + ",";
            }
            else
            {
                switch ((MPosLabelAlignment)alignment)
                {
                    case MPosLabelAlignment.MPOS_LABEL_ALIGNMENT_LEFT:
                        printCommand += "F" + ","; break;
                    case MPosLabelAlignment.MPOS_LABEL_ALIGNMENT_RIGHT:
                        printCommand += "L" + ","; break;
                    default:
                        printCommand += "F" + ","; break;
                }
            }

            printCommand += "'";

            byte[] encodedTextData = null;

            switch ((MPosLabelBitmapFont)fontSelection)
            {
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_KOREAN1:
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_KOREAN2:
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_KOREAN3:
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_KOREAN4:
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_KOREAN5:
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_KOREAN6:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : MPOS_CODEPAGE_KOREA_KS5601");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_KOREA_KS5601);
                    break;
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_GB2312:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : MPOS_CODEPAGE_CHINA_GB2312");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_CHINA_GB2312);
                    break;
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_BIG5:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : MPOS_CODEPAGE_CHINA_BIG5");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_CHINA_BIG5);
                    break;
                case MPosLabelBitmapFont.MPOS_LABEL_DEVICE_FONT_SHIFT_JIS:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : MPOS_CODEPAGE_JAPAN_SHIFTJIS");
                    encodedTextData = getEncodedTextData(data, (int)MPosLabelCodePage.MPOS_CODEPAGE_JAPAN_SHIFTJIS);
                    break;
                default:
                    MPosDebug.WriteLine("LabelPrinterImplementation drawTextDeviceFont : NO MATCH");
                    encodedTextData = getEncodedTextData(data);
                    break;
            }

            var result = (int)MPosResult.MPOS_SUCCESS;
            if (encodedTextData != null)
            {
                var dataToSend = MPosByteArrayHelper.concat(Encoding.ASCII.GetBytes(printCommand), encodedTextData, Encoding.ASCII.GetBytes("'\r\n"));
                var writtenBytes = await _MPosConnection.writeAsync(DeviceID, dataToSend);
                MPosDebug.WriteLine("PrinterImplementation drawTextDeviceFont : written bytes = " + writtenBytes);
                if (writtenBytes <= 0)
                    result = (int)MPosResult.MPOS_FAIL;
            }
            MPosDebug.WriteLine("PrinterImplementation drawTextDeviceFont : END");
            return result;
        }
        public async Task<int> setupRFID(int rfidType, int numberOfRetries, int numberOfLabel, int radioPower)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setupRFID : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setupRFID : rfidType = " + rfidType + ", numberOfRetries = " + numberOfRetries +
                ", numberOfLabel = " + numberOfLabel + ", radioPower = " + radioPower);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setupRFID : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setupRFID : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }
            
            var isMember = Enum.GetValues(typeof(MPosLabelRfidTransponderType)).Cast<int>().Any(x => x == (int)rfidType);

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setupRFID : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation setupRFID : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }
            
            if (numberOfRetries < 1) numberOfRetries = 1;
            else if (numberOfRetries > 10) numberOfRetries = 10;
            if (numberOfLabel < 1) numberOfLabel = 1;
            else if (numberOfLabel > 5) numberOfLabel = 5;
            if (radioPower < 0) radioPower = 0;
            else if (radioPower > 30) radioPower = 30;

            string printCommand = ">RFS,";
            printCommand += rfidType.ToString() + "," + numberOfRetries.ToString() + ",";
            printCommand += numberOfLabel.ToString() + "," + radioPower.ToString() + "\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation setupRFID : printCommand = " + printCommand);

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand));
            MPosDebug.WriteLine("PrinterImplementation setupRFID : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation setupRFID : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }

        public async Task<int> setRFIDPosition(int transPosition)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPosition : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPosition : transPosition = " + transPosition);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPosition : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPosition : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            string printCommand = ">RFTP,";

            if (transPosition >= 0)
            {
                printCommand += transPosition.ToString();
            }
            else
            {
                transPosition = (transPosition * (-1));
                printCommand += ("-" + transPosition.ToString());
            }
            printCommand += "\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPosition : printCommand = " + printCommand);

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand));
            MPosDebug.WriteLine("PrinterImplementation setRFIDPosition : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation setRFIDPosition : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }

        public async Task<int> calibrateRFID()
        {
            MPosDebug.WriteLine("LabelPrinterImplementation calibrateRFID : START");

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation calibrateRFID : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation calibrateRFID : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            string printCommand = ">RFCP,";
            printCommand += "\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation calibrateRFID : printCommand = " + printCommand);

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand));
            MPosDebug.WriteLine("PrinterImplementation calibrateRFID : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation calibrateRFID : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }

        public async Task<int> writeRFID(int dataType, int startingBlockNumber, int dataLength, string data)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : START");
            MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : dataType = " + dataType + ", startingBlockNumber = " + startingBlockNumber +
                ", dataLength = " + dataLength + ", data = " + data);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }
            
            var isMember = Enum.GetValues(typeof(MPosLabelRfidDataType)).Cast<int>().Any(x => x == (int)dataType);

            if (!isMember)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }
            /*
            if (data.Length != dataLength)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }
            */
            switch ((MPosLabelRfidDataType)dataType)
            {
                case MPosLabelRfidDataType.MPOS_LABEL_RFID_DATA_TYPE_ASCII:
                    dataLength = data.Length;
                    break;
                case MPosLabelRfidDataType.MPOS_LABEL_RFID_DATA_TYPE_HEX:
                case MPosLabelRfidDataType.MPOS_LABEL_RFID_DATA_TYPE_USER_HEX:
                    dataLength = data.Length / 2;
                    break;
            }

            if (startingBlockNumber < 4) startingBlockNumber = 4;
            else if (startingBlockNumber > 10) startingBlockNumber = 10;


            string printCommand = ">RFW,";
            printCommand += ((char)dataType).ToString() + ",";
            if ((MPosLabelRfidDataType)dataType != MPosLabelRfidDataType.MPOS_LABEL_RFID_DATA_TYPE_EPC)
            {
                printCommand += startingBlockNumber.ToString() + "," + dataLength.ToString() + ",";
            }
            printCommand += "'" + data + "'\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation writeRFID : printCommand = " + printCommand);

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand));
            MPosDebug.WriteLine("PrinterImplementation writeRFID : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation writeRFID : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }

        public async Task<int> setRFIDPassword(string oldAccessPwd, string oldKillPwd, string newAccessPwd, string newKillPwd)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPassword : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPassword : oldAccessPwd = " + oldAccessPwd + ", oldKillPwd = " + oldKillPwd +
                ", newAccessPwd = " + newAccessPwd + ", newKillPwd = " + newKillPwd);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPassword : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPassword : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            string printCommand = ">RFZ,";
            printCommand += "'" + oldAccessPwd + ",";
            printCommand += oldKillPwd + ",";
            printCommand += newAccessPwd + ",";
            printCommand += newKillPwd + "'\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation setRFIDPassword : printCommand = " + printCommand);

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand));
            MPosDebug.WriteLine("PrinterImplementation setRFIDPassword : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation setRFIDPassword : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }

        public async Task<int> lockRFID()
        {
            MPosDebug.WriteLine("LabelPrinterImplementation lockRFID : START");

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation lockRFID : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation lockRFID : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }

            string printCommand = ">RFLK,";
            printCommand += "\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation lockRFID : printCommand = " + printCommand);

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand));
            MPosDebug.WriteLine("PrinterImplementation lockRFID : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation lockRFID : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }

        public async Task<int> setEPCDataStructure(int totalSize, string fieldSizes)
        {
            MPosDebug.WriteLine("LabelPrinterImplementation setEPCDataStructure : START");
            MPosDebug.WriteLine("LabelPrinterImplementation setEPCDataStructure : dataType = " + totalSize + ", fieldSizes = " + fieldSizes);

            if (!IsOpen)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setEPCDataStructure : MPOS_FAIL_NO_OPEN");
                MPosDebug.WriteLine("LabelPrinterImplementation setEPCDataStructure : END");
                return (int)MPosResult.MPOS_FAIL_NO_OPEN;
            }
            string[] fields = fieldSizes.Split(new char[] { ',' });
            int fieldCount = 0;
            foreach (var field in fields)
            {
                fieldCount += int.Parse(field);
            }
            if (totalSize != fieldCount)
            {
                MPosDebug.WriteLine("LabelPrinterImplementation setEPCDataStructure : fieldCount = " + fieldCount);
                MPosDebug.WriteLine("LabelPrinterImplementation setEPCDataStructure : MPOS_FAIL_INVALID_PARAMETER");
                MPosDebug.WriteLine("LabelPrinterImplementation setEPCDataStructure : END");
                return (int)MPosResult.MPOS_FAIL_INVALID_PARAMETER;
            }

            string printCommand = ">RFES,";
            printCommand += totalSize.ToString() + ",";
            printCommand += "'" + fieldSizes + "'\r\n";

            MPosDebug.WriteLine("LabelPrinterImplementation setEPCDataStructure : printCommand = " + printCommand);

            var writtenBytes = await _MPosConnection.writeAsync(DeviceID, Encoding.ASCII.GetBytes(printCommand));
            MPosDebug.WriteLine("PrinterImplementation setEPCDataStructure : written bytes = " + writtenBytes);
            MPosDebug.WriteLine("PrinterImplementation setEPCDataStructure : END");

            if (writtenBytes <= 0)
                return (int)MPosResult.MPOS_FAIL;
            return (int)MPosResult.MPOS_SUCCESS;
        }
    }
}
