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

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

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

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

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

            return ret;
        }

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

            return ret;
        }

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

            return ret;
        }

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

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

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

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

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

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

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

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

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

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

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

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

    public class MPosNFCLib
    {
        private const string MPOS_LIB_NAME = "MPosControllerNFC.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)]string data);
    }
}

