using System;
using System.Runtime.InteropServices;

namespace GcDevicePc.Common
{
    class GCModbusSlave485
    {
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public unsafe delegate ushort SlaveReadHoldingRegister(ushort address);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public unsafe delegate void SlaveWriteHoldingRegister(ushort address, ushort value);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public unsafe delegate ushort SlaveReadCoilsRegister(ushort address);
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public unsafe delegate void SlaveWriteCoilsRegister(ushort address, ushort value);

        [DllImport(@"LibModbus.dll", EntryPoint = "fnLibModbusSlave485Init", CharSet = CharSet.Unicode)]
        public static extern uint fnLibModbusSlave485Init(System.Byte port, System.Int32 BaudRate);

        [DllImport(@"LibModbus.dll", EntryPoint = "fnLibModbusSlaveHoldingRegister", CallingConvention = CallingConvention.Cdecl)]
        public static extern void fnLibModbusSlaveHoldingRegister(System.UInt32 handle, SlaveReadHoldingRegister callslavereadholdingreg, SlaveWriteHoldingRegister callslavewirteholdingreg, ushort startAddr, ushort NReg);

        [DllImport(@"LibModbus.dll", EntryPoint = "fnLibModbusSlaveCoilsRegister", CallingConvention = CallingConvention.Cdecl)]
        public static extern void fnLibModbusSlaveCoilsRegister(System.UInt32 handle, SlaveReadCoilsRegister callslavereadcoilsreg, SlaveWriteCoilsRegister callslavewirtecoilsreg, ushort startAddr, ushort NReg);

        [DllImport(@"LibModbus.dll", EntryPoint = "fnLibModbusSlaveClose")]
        public static extern uint fnLibModbusSlaveClose(uint handle);

        private uint hModbusHandle;

        public GCModbusSlave485(Byte port, int baudrate )
        {
            try
            {
                this.hModbusHandle = fnLibModbusSlave485Init(port, baudrate);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        ~GCModbusSlave485()
        {
            try
            {
                fnLibModbusSlaveClose(hModbusHandle);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public uint CModbusSlave485Close()
        {
            uint ret = 0;
            try
            {
                ret = fnLibModbusSlaveClose(hModbusHandle);
            }
            catch
            {
                Console.WriteLine("Slave 退出出现Bug");
            }

            return ret;
        }


        public void CModbusSlave485Init(ushort hstartaddr, ushort hnreg, ushort cstartaddr, ushort cnreg)
        {
            setHoldingRegisterFunc(hstartaddr, hnreg);
            setCoilsRegisterFunc(cstartaddr, cnreg);
        }

        SlaveReadHoldingRegister MySlaveReadHoldingRegister;
        SlaveWriteHoldingRegister MySlaveWriteHoldingRegister;
        public void setHoldingRegisterFunc(ushort startaddr, ushort nreg)
        {
            MySlaveReadHoldingRegister = new SlaveReadHoldingRegister(slavereadhreg);
            MySlaveWriteHoldingRegister = new SlaveWriteHoldingRegister(slavewirtehreg);
            fnLibModbusSlaveHoldingRegister(hModbusHandle, MySlaveReadHoldingRegister, MySlaveWriteHoldingRegister, startaddr, nreg);
        }

        static ushort slavereadhreg(ushort address)
        {
            ushort value = 0;
            ushort baseaddress = 20;
            address = (ushort)(address - 1);
            int listnum = SharedSpace.Data.listValue.Count;
            int readnum = (address - baseaddress) / 2;

            if (readnum <= listnum - 1 && listnum > 0 && address >= 20)
            {
                try
                {
                    ushort[] s = new ushort[2];
                    float[] f = new float[2];
                    {
                        f[0] = float.Parse(SharedSpace.Data.listValue[readnum].vale.ToString());
                        Buffer.BlockCopy(f, 2, s, 0, 2);
                        Buffer.BlockCopy(f, 0, s, 2, 2);
                    }
                    value = s[(address - baseaddress) % 2];
                }
                catch
                {

                }
            }
            return value;
        }

        static void slavewirtehreg(ushort address, ushort value)
        {
             Console.WriteLine("MoudbusSlave Wirte adder:" + address.ToString() + " value:" + value.ToString());
        }

        SlaveReadCoilsRegister MySlaveReadCoilsRegister;
        SlaveWriteCoilsRegister MySlaveWriteCoilsRegister;
        public void setCoilsRegisterFunc(ushort startaddr, ushort nreg)
        {

            MySlaveReadCoilsRegister = new SlaveReadCoilsRegister(slavereadcreg);
            MySlaveWriteCoilsRegister = new SlaveWriteCoilsRegister(slavewirtecreg);
            fnLibModbusSlaveCoilsRegister(hModbusHandle, MySlaveReadCoilsRegister, MySlaveWriteCoilsRegister, startaddr, nreg);
        }

        public static ushort slavereadcreg(ushort address)
        {
            ushort value = 0;
        //   Console.WriteLine("MoudbusSlave Read Holding adder is " + CKVocAnalyzer.GlobalCKV.valueparamlist.ToString());
            return value;
        }


        public static void slavewirtecreg(ushort address, ushort value)
        {
            //Console.WriteLine("MoudbusSlave Wirte adder:" + address.ToString() + " value:" + value.ToString());
        }

    }
}
