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

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

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

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

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

            return ret;
        }

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

            return ret;
        }

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

            return ret;
        }

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

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

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

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

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

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

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

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

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

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

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

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

        public String searchDevices()
        {
            IntPtr ptr = MPosConfigLib.searchDevices(nBgtId);
            return Marshal.PtrToStringAuto(ptr);
        }

        public String getBgateSerialNumber()
        {
            IntPtr ptr = MPosConfigLib.getBgateSerialNumber(nBgtId);
            return Marshal.PtrToStringAuto(ptr);
        }

        public String getUSBDevice(int deviceId)
        {
            IntPtr ptr = MPosConfigLib.getUSBDevice(nBgtId, deviceId);
            return Marshal.PtrToStringAuto(ptr);
        }

        public String getSerialConfiguration(int deviceId)
        {
            IntPtr ptr = MPosConfigLib.getSerialConfiguration(nBgtId, deviceId);
            return Marshal.PtrToStringAuto(ptr);
        }

        public Int32 setSerialConfiguration(int deviceId, int baudrate, int dataBit, int stopBit, int parityBit, int flowControl)
        {
            return MPosConfigLib.setSerialConfiguration(nBgtId, deviceId, baudrate, dataBit, stopBit, parityBit, flowControl);
        }

        public String getCustomDevices(int deviceType)
        {
            IntPtr ptr = MPosConfigLib.getCustomDevices(nBgtId, deviceType);
            return Marshal.PtrToStringAuto(ptr);
        }

        public Int32 addCustomDevice(int deviceType, string vid, string pid)
        {
            return MPosConfigLib.addCustomDevice(nBgtId, deviceType, vid, pid);
        }

        public Int32 deleteCustomDevice(int deviceType, string vid, string pid)
        {
            return MPosConfigLib.deleteCustomDevice(nBgtId, deviceType, vid, pid);
        }

        public Int32 reInitCustomDeviceType(int deviceType)
        {
            return MPosConfigLib.reInitCustomDeviceType(nBgtId, deviceType);
        }
    }
    
    public class MPosConfigLib
    {
        private const string MPOS_LIB_NAME = "MPosControllerConfig.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);

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

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

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

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

        [DllImport(MPOS_LIB_NAME, EntryPoint = "setSerialConfiguration")]
        public extern static Int32 setSerialConfiguration(int bgtId, int deviceId, int baudrate, int dataBit, int stopBit, int parityBit, int flowControl);

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

        [DllImport(MPOS_LIB_NAME, EntryPoint = "addCustomDevice")]
        public extern static Int32 addCustomDevice(int bgtId, int deviceType, [MarshalAs(UnmanagedType.LPWStr)] string vid, [MarshalAs(UnmanagedType.LPWStr)] string pid);

        [DllImport(MPOS_LIB_NAME, EntryPoint = "deleteCustomDevice")]
        public extern static Int32 deleteCustomDevice(int bgtId, int deviceType, [MarshalAs(UnmanagedType.LPWStr)] string vid, [MarshalAs(UnmanagedType.LPWStr)] string pid);

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