using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using GcDevicePc.IniParam;

namespace GcDevicePc.Common
{
    class GCModbusSlave
    {
        [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 = "fnLibModbusSlaveInit", CharSet = CharSet.Unicode)]
        public static extern uint fnLibModbusSlaveInit();

        [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 GCModbusSlave()
        {
            this.hModbusHandle = fnLibModbusSlaveInit();
        }

        ~GCModbusSlave()
        {
            try
            {
                fnLibModbusSlaveClose(hModbusHandle);
            }catch
            {

            }
        }

        public uint CModbusSlaveClose()
        {
            uint ret = 0;
            try
            {
                ret = fnLibModbusSlaveClose(hModbusHandle);
            }
            catch
            {

            }
            
            return ret; 
        }


        public void CModbusSlaveInit(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)
           {
              // lock(CKVocAnalyzer.GlobalCKV.valueparamlist){

                   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{

                     }
                //}
           }

           if( address >=4 && address <20 )
           {
               switch(address)
               {
                   case 3:
                   {
                       value = SharedSpace.Data.change == true ? (ushort)1 : (ushort)0;
                   }
                       break;
                   case 4:
                   {
                       value = globaldata.m_hmibuffer.gcinfo.HMIMac[0];
                   }
                       break;
                   case 5:
                       {
                           value = globaldata.m_hmibuffer.gcinfo.HMIMac[1];
                       }
                       break;
                   case 6:
                       {
                           value = globaldata.m_hmibuffer.gcinfo.HMIMac[2];
                       }
                       break;
                   case 7:  //设备联机状态
                       {
                           value = (ushort)(globaldata.m_hmibuffer.gcinfo.hmioffline ? 1 : 0);
                       }
                       break;
                   case 8:  //HMI状态
                       {
                           value =  globaldata.m_hmibuffer.gcinfo.methodstatus;
                       }
                       break;
                   case 9:  //前进样口
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16InjPortFront == 1)
                           {
                               value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.FPActualTemp * 10);
                           }
                           else
                           {
                               value = 0;
                           }
                       }              
                       break;
                   case 10: //后进样口
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16InjPortBehind == 1)
                           {
                               value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.BPActualTemp * 10);
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 11: // 柱箱
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16Col == 1)
                           {
                               value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.ColActualTemp * 10);
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 12: //前检测器
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16InjPortFront == 1)
                           {
                               if (CProfileDevice.m_DevParam.syspara.u16DetFrontType == 0)
                               {
                                   value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.fDetActualTemp*10);
                               }
                               else if (CProfileDevice.m_DevParam.syspara.u16DetFrontType == 1)
                               {
                                   value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.fDetActualTemp * 10);
                               }else
                               {
                                   value = 0;
                               }
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 13: //中检测器
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16DetInter == 1)
                           {
                               if (CProfileDevice.m_DevParam.syspara.u16DetInterType == 0)
                               {
                                   value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.iDetActualTemp * 10);
                               }
                               else if (CProfileDevice.m_DevParam.syspara.u16DetInterType == 1)
                               {
                                   value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.iDetActualTemp * 10);
                               }
                               else
                               {
                                   value = 0;
                               }
                           }
                           else if (CProfileDevice.m_DevParam.syspara.u16AuxHeater1 == 1)
                           {
                               value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.AuxActualTemp1*10);
                           }else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 14: //后检测器
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16DetBehind == 1)
                           {
                               if (CProfileDevice.m_DevParam.syspara.u16DetBehindType == 0)
                               {
                                   value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.bDetActualTemp * 10);
                               }
                               else if (CProfileDevice.m_DevParam.syspara.u16DetBehindType == 1)
                               {
                                   value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.bDetActualTemp * 10);
                               }
                               else if (CProfileDevice.m_DevParam.syspara.u16AuxHeater2 == 1)
                               {
                                   value = (ushort)(globaldata.m_dpbuffer.ShowList.showtemp.AuxActualTemp2*10);
                               }else
                               {
                                    value = 0;
                               }
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 15: //前点火信号
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16DetFrontType == 1)
                           {
                               value = globaldata.m_dpbuffer.ShowList.showDet.fDetStatue;
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 16: //后点火信号
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16DetInterType == 1)
                           {
                               value = globaldata.m_dpbuffer.ShowList.showDet.fDetStatue;
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 17: //前检测器值
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16DetFront == 1)
                           {
                               value = (ushort)(globaldata.m_dpbuffer.ShowList.showDet.fDetValue * 1000);
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 18: //中检测器值
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16DetInter == 1)
                           {
                               value = (ushort)(globaldata.m_dpbuffer.ShowList.showDet.iDetValue * 1000);
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
                   case 19: //后检测器值
                       {
                           if (CProfileDevice.m_DevParam.syspara.u16DetBehind == 1)
                           {
                               value = (ushort)(globaldata.m_dpbuffer.ShowList.showDet.bDetValue * 1000);
                           }
                           else
                           {
                               value = 0;
                           }
                       }
                       break;
               }

           }
            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;
            switch (address)
            {
                case 16:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[0];
                    break;
                case 17:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[1];
                    break;
                case 18:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[2];
                    break;
                case 19:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[3];
                    break;
                case 20:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[4];
                    break;
                case 21:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[5];
                    break;
                case 22:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[6];
                    break;
                case 23:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[7];
                    break;
                case 24:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[8];
                    break;
                case 25:
                    value = globaldata.m_hmibuffer.gcinfo.TenRelay[9];
                    break;
                default:
                    value = 0;
                    break;
            }
         //   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());
        }





    }
}
