using System;
using System.Runtime.InteropServices;
using System.Text;

namespace BIXOLON
{
    public class MPosControllerPrinter
    {
        public int nBgtId;
        public int ndeviceId;

        public Int32 selectInterface(int interfaceType, string address)
        {
            nBgtId = MPosPrinterLib.selectInterface(interfaceType, address);
            return nBgtId;
        }

        public Int32 selectCommandMode(int commandMode)
        {
            return MPosPrinterLib.selectCommandMode(nBgtId, commandMode);
        }

        public Int32 openService()
        {
            Int32 ret = MPosPrinterLib.openService(nBgtId);
            if (ret == MPosConst.RES_SUCCESS || ret == MPosConst.RES_ALREADY_OPEN)
                ndeviceId = MPosPrinterLib.getDeviceId(nBgtId);

            return ret;
        }

        public Int32 openServiceById(int openDeviceId, int timeout)
        {
            Int32 ret = MPosPrinterLib.openServiceById(nBgtId, openDeviceId, timeout);
            if (ret == MPosConst.RES_SUCCESS || ret == MPosConst.RES_ALREADY_OPEN)
                ndeviceId = MPosPrinterLib.getDeviceId(nBgtId);

            return ret;
        }

        public Int32 openUSBSerial(int positionNumber)
        {
            Int32 ret = MPosPrinterLib.openUSBSerial(nBgtId, positionNumber);
            if (ret == MPosConst.RES_SUCCESS || ret == MPosConst.RES_ALREADY_OPEN)
                ndeviceId = MPosPrinterLib.getDeviceId(nBgtId);

            return ret;
        }

        public Int32 closeService(int closeTimeout)
        {
            return MPosPrinterLib.closeService(nBgtId, closeTimeout);
        }

        public Boolean isOpen()
        {
            return MPosPrinterLib.isOpen(nBgtId);
        }

        public Int32 getDeviceId()
        {
            return MPosPrinterLib.getDeviceId(nBgtId);
        }

        public Int32 directIO(byte[] data, int dataLength)
        {
            return MPosPrinterLib.directIO(nBgtId, data, dataLength);
        }

        public Int32 sendFile(string fileName)
        {
            return MPosPrinterLib.sendFile(fileName);
        }

        public Int32 setTransaction(int transactionMode)
        {
            return MPosPrinterLib.setTransaction(nBgtId, transactionMode);
        }

        public Int32 setReadMode(int readMode)
        {
            return MPosPrinterLib.setReadMode(nBgtId, readMode);
        }

        public Int32 setKeepNetworkConnection(int enable)
        {
            return MPosPrinterLib.setKeepNetworkConnection(enable);
        }

        public String getSDKVersion()
        {
            IntPtr ptr = MPosPrinterLib.getSDKVersion();
            return Marshal.PtrToStringAuto(ptr);
        }

        public Int32 setStatusUpdateEvent(MPosPrinterLib.fnStatusUpdateEventCallback StatusUpdateEventCallback)
        {
            return MPosPrinterLib.setStatusUpdateEvent(nBgtId, StatusUpdateEventCallback);
        }

        public Int32 setOutputCompletedEvent(MPosPrinterLib.fnOutputCompletedEventCallback OutputCompletedEventCallback)
        {
            return MPosPrinterLib.setOutputCompletedEvent(nBgtId, OutputCompletedEventCallback);
        }

        public Int32 setDataEvent(MPosPrinterLib.fnDataEventCallback DataEventCallback)
        {
            return MPosPrinterLib.setDataEvent(nBgtId, DataEventCallback);
        }

        public Int32 setCharacterset(int codepage)
        {
            return MPosPrinterLib.setCharacterset(nBgtId, codepage);
        }

        public Int32 setInternationalCharacterset(int intlCharset)
        {
            return MPosPrinterLib.setInternationalCharacterset(nBgtId, intlCharset);
        }

        public Int32 cutPaper(int cutType)
        {
            return MPosPrinterLib.cutPaper(nBgtId, cutType);
        }

        public Int32 setPagemode(int pagemode)
        {
            return MPosPrinterLib.setPagemode(nBgtId, pagemode);
        }

        public Int32 setPagemodePrintArea(int x, int y, int width, int height)
        {
            return MPosPrinterLib.setPagemodePrintArea(nBgtId, x, y, width, height);
        }

        public Int32 setPagemodeDirection(int direction)
        {
            return MPosPrinterLib.setPagemodeDirection(nBgtId, direction);
        }

        public Int32 setPagemodePosition(int x, int y)
        {
            return MPosPrinterLib.setPagemodePosition(nBgtId, x, y);
        }

        public Int32 printText(string data, int fontType, int fontWidth, int fontHeight, int bold, int underline, int reverse, int alignment)
        {
            return MPosPrinterLib.printText(nBgtId, data, fontType, fontWidth, fontHeight, bold, underline, reverse, alignment);
        }

        public Int32 printBitmap(byte[] imageData, int width, int alignment, int brightness, bool isDithering, bool isCompress)
        {
            return MPosPrinterLib.printBitmap(nBgtId, imageData, width, alignment, brightness, isDithering, isCompress);
        }

        public Int32 printBitmapFile(string filename, int width, int alignment, int brightness, bool isDithering, bool isCompress)
        {
            return MPosPrinterLib.printBitmapFile(nBgtId, filename, width, alignment, brightness, isDithering, isCompress);
        }

        public Int32 printImageFile(string filename, int width, int alignment, int threshold, int ditheringType, int compressType)
        {
            return MPosPrinterLib.printImageFile(nBgtId, filename, width, alignment, threshold, ditheringType, compressType);
        }

        public Int32 printImage(byte[] imageData, int width, int alignment, int threshold, int ditheringType, int compressType)
        {
            return MPosPrinterLib.printImage(nBgtId, imageData, imageData.Length, width, alignment, threshold, ditheringType, compressType);
        }

        public Int32 printBase64Image(string base64String, int width, int alignment, int threshold, int ditheringType, int compressType)
        {
            return MPosPrinterLib.printBase64Image(nBgtId, base64String, width, alignment, threshold, ditheringType, compressType);
        }

        public Int32 print1DBarcode(string data, int symbology, int barWidth, int height, int alignment, int textPosition)
        {
            return MPosPrinterLib.print1DBarcode(nBgtId, data, symbology, barWidth, height, alignment, textPosition);
        }

        public Int32 printQRCode(string data, int model, int alignment, int moduleSize, int eccLevel)
        {
            return MPosPrinterLib.printQRCode(nBgtId, data, model, alignment, moduleSize, eccLevel);
        }

        public Int32 printPDF417(string data, int symbol, int alignment, int columnNumber, int rowNumber, int moduleWidth, int moduleHeight, int eccLevel)
        {
            return MPosPrinterLib.printPDF417(nBgtId, data, symbol, alignment, columnNumber, rowNumber, moduleWidth, moduleHeight, eccLevel);
        }

        public Int32 printGS1Databar(string data, int symbol, int alignment, int moduleSize)
        {
            return MPosPrinterLib.printGS1Databar(nBgtId, data, symbol, alignment, moduleSize);
        }

        public Int32 printGS1DatabarMobile(string data, int symbol, int alignment, int moduleWidth, int moduleHeight, int segmentHeight, int separatorHeight)
        {
            return MPosPrinterLib.printGS1DatabarMobile(nBgtId, data, symbol, alignment, moduleWidth, moduleHeight, segmentHeight, separatorHeight);
        }

        public Int32 printCompositeSymbology([MarshalAs(UnmanagedType.LPWStr)] string data, [MarshalAs(UnmanagedType.LPWStr)] string cData, int symbol, int cSymbol, int alignment, int size)
        {
            return MPosPrinterLib.printCompositeSymbology(nBgtId, data, cData, symbol, cSymbol, alignment, size);
        }

        public Int32 printDataMatrix(string data, int alignment, int moduleSize)
        {
            return MPosPrinterLib.printDataMatrix(nBgtId, data, alignment, moduleSize);
        }

        public Int32 printMaxicode(string data, int mode, int alignment)
        {
            return MPosPrinterLib.printMaxicode(nBgtId, data, mode, alignment);
        }

        public Int32 printAztec(string data, int alignment, int moduleSize, int eccLevel, int mode)
        {
            return MPosPrinterLib.printAztec(nBgtId, data, alignment, moduleSize, eccLevel, mode);
        }

        public Int32 printLine(int x1, int y1, int x2, int y2, int thickness)
        {
            return MPosPrinterLib.printLine(nBgtId, x1, y1, x2, y2, thickness);
        }

        public Int32 printBox(int left, int top, int right, int bottom, int thickness)
        {
            return MPosPrinterLib.printBox(nBgtId, left, top, right, bottom, thickness);
        }

        public Int32 checkPrinterStatus()
        {
            return MPosPrinterLib.checkPrinterStatus(nBgtId);
        }

        public Int32 asbEnable(bool enable)
        {
            return MPosPrinterLib.asbEnable(nBgtId, enable);
        }

        public Int32 openDrawer(int pinNumber, int onTimePulse, int offTimePulse)
        {
            return MPosPrinterLib.openDrawer(nBgtId, pinNumber, onTimePulse, offTimePulse);
        }

        public String getModelName()
        {
            IntPtr ptr = MPosPrinterLib.getModelName(nBgtId);
            return Marshal.PtrToStringAuto(ptr);
        }

        public String getFirmwareVersion()
        {
            IntPtr ptr = MPosPrinterLib.getFirmwareVersion(nBgtId);
            return Marshal.PtrToStringAuto(ptr);
        }

        public String getStatisticsData(int info)
        {
            IntPtr ptr = MPosPrinterLib.getStatisticsData(nBgtId, info);
            return Marshal.PtrToStringAuto(ptr);
        }
    }

    public class MPosPrinterLib
    {
        protected const string MPOS_LIB_NAME = "MPosControllerPrinter.dll";

        [DllImport(MPOS_LIB_NAME, EntryPoint = "selectInterface")]
        public extern static Int32 selectInterface(int interfaceType, [MarshalAs(UnmanagedType.LPWStr)] string address);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "selectCommandMode")]
        public extern static Int32 selectCommandMode(int bgtId, int commandMode);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "openService")]
        public extern static Int32 openService(int bgtId);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "openServiceById")]
        public extern static Int32 openServiceById(int bgtId, int openDeviceId, int timeout);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "openUSBSerial")]
        public extern static Int32 openUSBSerial(int bgtId, int positionNumber);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "closeService")]
        public extern static Int32 closeService(int bgtId, int closeTimeout);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "isOpen")]
        public extern static Boolean isOpen(int bgtId);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "getDeviceId")]
        public extern static Int32 getDeviceId(int bgtId);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "directIO")]
        public extern static Int32 directIO(int bgtId, byte[] data, int dataLength);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "sendFile")]
        public extern static Int32 sendFile([MarshalAs(UnmanagedType.LPWStr)] string fileName);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setTransaction")]
        public extern static Int32 setTransaction(int bgtId, int transactionMode);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setReadMode")]
        public extern static Int32 setReadMode(int bgtId, int readMode);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setKeepNetworkConnection")]
        public extern static Int32 setKeepNetworkConnection(int enable);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "getSDKVersion")]
        public extern static IntPtr getSDKVersion();

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setStatusUpdateEvent")]
        public extern static Int32 setStatusUpdateEvent(int bgtId, fnStatusUpdateEventCallback StatusUpdateEventCallback);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setOutputCompletedEvent")]
        public extern static Int32 setOutputCompletedEvent(int bgtId, fnOutputCompletedEventCallback OutputCompletedEventCallback);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setDataEvent")]
        public extern static Int32 setDataEvent(int bgtId, fnDataEventCallback DataEventCallback);

        public delegate void fnStatusUpdateEventCallback(int status);
        public delegate void fnOutputCompletedEventCallback();
        //public delegate void fnDataEventCallback([MarshalAs(UnmanagedType.LPWStr)]StringBuilder data);
        public delegate void fnDataEventCallback([MarshalAs(UnmanagedType.LPWStr)]string data);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setCharacterset")]
        public extern static Int32 setCharacterset(int bgtId, int codepage);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setInternationalCharacterset")]
        public extern static Int32 setInternationalCharacterset(int bgtId, int intlCharset);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "cutPaper")]
        public extern static Int32 cutPaper(int bgtId, int cutType);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setPagemode")]
        public extern static Int32 setPagemode(int bgtId, int pagemode);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setPagemodePrintArea")]
        public extern static Int32 setPagemodePrintArea(int bgtId, int x, int y, int width, int height);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setPagemodeDirection")]
        public extern static Int32 setPagemodeDirection(int bgtId, int direction);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setPagemodePosition")]
        public extern static Int32 setPagemodePosition(int bgtId, int x, int y);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printText")]
        public extern static Int32 printText(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int fontType, int fontWidth, int fontHeight, int bold, int underline, int reverse, int alignment);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printBitmap")]
        public extern static Int32 printBitmap(int bgtId, byte[] imageData, int width, int alignment, int brightness, bool isDithering, bool isCompress);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printBitmapFile")]
        public extern static Int32 printBitmapFile(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string filename, int width, int alignment, int brightness, bool isDithering, bool isCompress);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printImageFile")]
        public extern static Int32 printImageFile(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string filename, int width, int alignment, int threshold, int ditheringType, int compressType);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printImage")]
        public extern static Int32 printImage(int bgtId, byte[] imageData, int imageLength, int width, int alignment, int threshold, int ditheringType, int compressType);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printBase64Image")]
        public extern static Int32 printBase64Image(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string base64String, int width, int alignment, int threshold, int ditheringType, int compressType);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "print1DBarcode")]
        public extern static Int32 print1DBarcode(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int symbology, int barWidth, int height, int alignment, int textPosition);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printQRCode")]
        public extern static Int32 printQRCode(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int model, int alignment, int moduleSize, int eccLevel);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printPDF417")]
        public extern static Int32 printPDF417(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int symbol, int alignment, int columnNumber, int rowNumber, int moduleWidth, int moduleHeight, int eccLevel);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printGS1Databar")]
        public extern static Int32 printGS1Databar(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int symbol, int alignment, int moduleSize);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printGS1DatabarMobile")]
        public extern static Int32 printGS1DatabarMobile(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int symbol, int alignment, int moduleWidth, int moduleHeight, int segmentHeight, int separatorHeight);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printCompositeSymbology")]
        public extern static Int32 printCompositeSymbology(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, [MarshalAs(UnmanagedType.LPWStr)] string cData, int symbol, int cSymbol, int alignment, int size);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printDataMatrix")]
        public extern static Int32 printDataMatrix(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int alignment, int moduleSize);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printMaxicode")]
        public extern static Int32 printMaxicode(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int mode, int alignment);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printAztec")]
        public extern static Int32 printAztec(int bgtId, [MarshalAs(UnmanagedType.LPWStr)] string data, int alignment, int moduleSize, int eccLevel, int mode);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printLine")]
        public extern static Int32 printLine(int bgtId, int x1, int y1, int x2, int y2, int thickness);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "printBox")]
        public extern static Int32 printBox(int bgtId, int left, int top, int right, int bottom, int thickness);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "checkPrinterStatus")]
        public extern static Int32 checkPrinterStatus(int bgtId);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "asbEnable")]
        public extern static Int32 asbEnable(int bgtId, bool enable);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "openDrawer")]
        public extern static Int32 openDrawer(int bgtId, int pinNumber, int onTimePulse, int offTimePulse);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "getModelName")]
        public extern static IntPtr getModelName(int bgtId);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "getFirmwareVersion")]
        public extern static IntPtr getFirmwareVersion(int bgtId);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "getStatisticsData")]
        public extern static IntPtr getStatisticsData(int bgtId, int info);
    }
}

