using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic;
using CommonClassLib;
using DBFactory;
namespace SimensProdave6
{
    public static class CSimensProdave6_S7
    {
        public static DBOperator dbo = new DBOperator();
        static int res;
        static bool _IfInit = false;
        static int _InitCount = 0;

        public static int InitCount
        {
            get { return CSimensProdave6_S7._InitCount; }
            set { CSimensProdave6_S7._InitCount = value; }
        }
        static uint BufLen = 1024;
        static string Errors;
        /// <summary>
        /// 与mpi网络通讯的故障信息
        /// </summary>
        public static string ErrorsText
        {
            get { return Errors; }
            set { Errors = value; }

        }
        public  struct CON_ADR_TYPE
        {
            //' MPI Stationsadresse   (2  |0  |0  |0  |0  |0  )
            //' IP Adresse            (192|168|0  |1  |0  |0  )
            //' MAC Adresse           (08 |00 |06 |01 |AA |BB )
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public  byte[] PlcAddress;
            //char[] 
            //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
            //public string name;
        }
        public  struct CON_TABLE_TYPE
        {
            /// <summary>
            /// MPI Stationsaddress   (2  |0  |0  |0  |0  |0  )
            /// IP Address            (192|168|0  |1  |0  |0  )
            /// MAC Address           (08 |00 |06 |01 |AA |BB )
            /// </summary>
            public  CON_ADR_TYPE Adr ;           // Verbindungsadresse
            /// <summary>
            /// Typ der Adresse MPI(1) IP(2) MAC(3)
            /// </summary>
            public  byte AdrType;                // Typ der Adresse MPI(1) IP(2) MAC(3)
            public  byte SlotNr;                 // Slot-Nummer
            public  byte RackNr;                 // Rack-Nummer
        }


        //[DllImport("Prodave6.dll")]
        //static extern int LoadConnection_ex6(Int16 ConNr,string AccessPoint , Int16 ConTableLen, CON_TABLE_TYPE pConTable);
        //[DllImport("Prodave6.dll", EntryPoint = "LoadConnection_ex6", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        //static extern ushort LoadConnection_ex6(ushort ConNr, char[] pAccessPoint, int ConTableLen, byte[] ConTable);


        //[DllImport("Prodave6.dll")]
        //static extern ushort SetActiveConnection_ex6(int ConNr);
        //[DllImport("Prodave6.dll")]
        //static extern ushort db_read_ex6(ushort blknr, string DatType, ushort StartNr, int Amount, int BufLen, ref byte pBuchBuffer, int pDatLen);
        //[DllImport("Prodave6.dll")]
        //static extern ushort db_write_ex6(ushort blknr, string DatType, ushort StartNr, int Amount,ref int BufLen, ref byte pWriteBuffer);
        //[DllImport("Prodave6.dll")]
        //static extern ushort field_read_ex6(byte FieldType, ushort blknr, ushort StartNr, int Amount, int BufLen, ref byte pBuchBuffer, int pDatLen);
        //[DllImport("Prodave6.dll")]
        //static extern ushort field_write_ex6(byte FieldType, ushort blknr, ushort StartNr, int Amount, int BufLen, ref byte pWriteBuffer);

        [DllImport("Prodave6.dll", EntryPoint = "LoadConnection_ex6", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

        private static extern int LoadConnection_ex6(ushort ConNr, char[] pAccessPoint, int ConTableLen, byte[] ConTable);

        [DllImport("Prodave6.dll", EntryPoint = "UnloadConnection_ex6", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

        public static extern int UnloadConnection_ex6(ushort ConNr);

        [DllImport("Prodave6.dll", EntryPoint = "SetActiveConnection_ex6", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

        private static extern int SetActiveConnection_ex6(ushort ConNr);

        [DllImport("Prodave6.dll", EntryPoint = "db_read_ex6", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

        private static extern int db_read_ex6(ushort no_of_db, byte datatype, ushort startaddr, ref uint read_request_length, uint bufferlength, byte[] buffer, ref uint returnlength);

        [DllImport("Prodave6.dll", EntryPoint = "db_write_ex6", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

        private static extern int db_write_ex6(ushort no_of_db, byte datatype, ushort startaddr, ref uint write_request_length, uint bufferlength, byte[] buffer);

        
        
        [DllImport("Prodave6.dll")]
        static extern ushort GetErrorMessage_ex6(ushort ErrorNr, ushort BufLen,ref byte pBuffer);
        /// <summary>
        /// 初始化PLC网络
        /// </summary>
        /// <returns></returns>
        public static bool InitNetwork()
        {
            
            char[] pAccessPoint ={ 'S', '7', 'O', 'N', 'L', 'I', 'N', 'E' };
            byte[] conn = new byte[] { 172, 18, 132, 11, 0, 0, 2, 0, 0 };
            int length = (int)conn.Length;
            if (_InitCount > 3)
            {
                Errors = "Prodave已经三次初始化网络失败，网络通讯失败！请退出系统，检查网络！";
                return false;
            }
            int res = LoadConnection_ex6((ushort)0, pAccessPoint, length, conn);

            if (res == 0)
            {
                _IfInit = true;
                return true;
            }
            else
            {
                GetErrorText((ushort)res);
                _IfInit = false;
                _InitCount++;
                return false;
            }
        }
        static void GetErrorText(int  ret)
        {
            byte[] errorBuffer=new byte[256];
            ret = GetErrorMessage_ex6((ushort)ret, 256, ref errorBuffer[0]);
            Errors= Encoding.ASCII.GetString(errorBuffer);
            _IfInit = false;
            UnloadConnection_ex6(0);
        }
        
        /// <summary>
        /// 向MPI通讯缓冲区DB区的写入数据
        /// </summary>
        /// <param name="connNo">连接编号</param>
        /// <param name="dbNo">DB数据块编号</param>
        /// <param name="addrDW">写DB数据块的DW数据的开始地址</param>
        /// <param name="AMOUNT">写入数量</param>
        public static bool DB_Write_Prodave(byte connNo, ushort dbNo, ushort nr, uint AMOUNT, byte[] value)
        {
            byte DatType = 2;//byte DatType = 2;WORD DatType = 4;DWORD DatType = 6
            try
            {
                if (_IfInit != true)
                {
                    if (InitNetwork() == false)
                    {
                        return false;
                    }
                }
                res = SetActiveConnection_ex6(connNo);
                if (res == 0)
                {

                    res = db_write_ex6(dbNo,DatType, nr,ref AMOUNT, BufLen,value);
                    
                }
                if (res != 0)
                {
                    GetErrorText(res);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {

                Errors = ex.Message;
                return false;
            }


        }
        /// <summary>
        /// //'读出MPI通讯缓冲区DB区的数据
        /// </summary>
        /// <param name="connNo">连接编号</param>
        /// <param name="dbNo">DB数据块编号</param>
        /// <param name="addrDW">读DB数据块的DW数据的开始地址</param>
        /// <param name="AMOUNT">读取数量</param>
        /// <returns>所有字节型数组</returns>
        public static byte[] DB_Read_Prodave(byte connNo, ushort dbNo, ushort nr, uint AMOUNT)
        {
            byte[] value_byte=new byte[1024];
            uint pDatLen=0;
            byte DatType = 2;//byte DatType = 2;WORD DatType = 4;DWORD DatType = 6
            try
            {

                if (_IfInit != true)
                {
                    if (InitNetwork() == false)
                    {
                        return null;
                    }
                }
                
                res = SetActiveConnection_ex6(0);
                if (res == 0)
                {
                    res = db_read_ex6(dbNo, DatType, nr, ref AMOUNT, BufLen,  value_byte,ref pDatLen);
                }
                if (res != 0)
                {
                    GetErrorText(res);
                    return null;
                }
                else
                {
                    return value_byte;
                }
            }
            catch (Exception ex)
            {
                Errors = ex.Message;
                return null;
            }
        }
        /// <summary>
        /// //'读出MPI通讯缓冲区DB区的数据
        /// </summary>
        /// <param name="connNo">连接编号</param>
        /// <param name="dbNo">DB数据块编号</param>
        /// <param name="addrDW">读DB数据块的DW数据的开始地址</param>
        /// <param name="AMOUNT">读取数量</param>
        /// <param name="Bit">比特（位数）</param>
        /// <returns>所有字节型数组</returns>
        public static byte[] DB_Read_Prodave(byte connNo, ushort dbNo, ushort nr, uint AMOUNT, int Bit)
        {
            byte[] value_byte = new byte[1024];
            uint pDatLen = 0;
            byte DatType = 2;//byte DatType = 2;WORD DatType = 4;DWORD DatType = 6
            try
            {

                if (_IfInit != true)
                {
                    if (InitNetwork() == false)
                    {
                        return null;
                    }
                }
                
                res = SetActiveConnection_ex6(connNo);
                if (res == 0)
                {

                    res = db_read_ex6(dbNo, DatType, nr,ref AMOUNT, BufLen,  value_byte,ref pDatLen);
                }
                if (res != 0)
                {
                    GetErrorText(res);
                    return null;
                }
                else
                {
                    value_byte[0] = CCarryConvert.GetBitFromInteger(value_byte[0], Bit);

                    return value_byte;
                }
            }
            catch (Exception ex)
            {
                Errors = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// //'向指定连接connNo的DataTypeIdx数据存储区写入数据
        /// </summary>
        /// <param name="connNo">连接编号</param>
        /// <param name="DataTypeIdx">数据存储区的类型 "Ausgangsbyte",FieldType = Asc("a");
        ///"Datenbyte",FieldType = Asc("d");
        ///"Eingangsbyte",FieldType = Asc("e");
        ///"Merkerbyte",FieldType = Asc("m");
        ///"Timerwort",FieldType = Asc("t");
        ///"Z鋒lerwort",FieldType = Asc("z")</param>
        /// <param name="addrno">开始地址</param>
        /// <param name="AMOUNT">写入的个数</param>
        /// <param name="value_byte">写入的字节型数组数据</param>
        /// <returns></returns>
        /// 
        //public static bool write_Prodave(byte connNo, byte DataTypeIdx, ushort addrno, int AMOUNT, byte[] value_byte)
        //{
        //    try
        //    {
        //        if (IfInit != true)
        //        {
        //            if (InitNetwork() == false)
        //            {
        //                return false;
        //            }
        //        }
        //        res = SetActiveConnection_ex6(connNo);
        //        if (res == 0)
        //        {
        //            field_write_ex6(DataTypeIdx, 0, addrno, AMOUNT, BufLen, ref value_byte[0]);

        //        }
        //        if (res != 0)
        //        {

        //            GetErrorText(res);
        //            return false;

        //        }
        //        return true;
        //    }
        //    catch (Exception ex)
        //    {

        //        Errors = ex.Message;
        //        return false;

        //    }


        //}
        ///// <summary>
        ///// //'读出MPI通讯缓冲区的数据
        ///// </summary>
        ///// <param name="connNo">连接编号</param>
        ///// <param name="DataTypeIdx">数据存储区的类型 "Ausgangsbyte",FieldType = Asc("a");
        /////"Datenbyte",FieldType = Asc("d");
        /////"Eingangsbyte",FieldType = Asc("e");
        /////"Merkerbyte",FieldType = Asc("m");
        /////"Timerwort",FieldType = Asc("t");
        /////"Z鋒lerwort",FieldType = Asc("z")</param>
        ///// <param name="addrNo">开始读数据的地址</param>
        ///// <param name="AMOUNT">读取数量</param>
        ///// <returns>所有字节型数组</returns>
        //public static byte[] read_Prodave(byte connNo, byte DataTypeIdx, ushort addrNo, int AMOUNT)
        //{
        //    byte[] value_byte = new byte[1024];
        //    ushort pDatLen = 0;
        //    try
        //    {

        //        if (IfInit != true)
        //        {
        //            if (InitNetwork() == false)
        //            {
        //                return null;
        //            }
        //        }
        //        if (AMOUNT > 512)
        //            AMOUNT = 512;

        //        res = SetActiveConnection_ex6(connNo);
        //        if (res == 0)
        //        {
        //            res = field_read_ex6(DataTypeIdx, 0, addrNo, AMOUNT, BufLen, ref value_byte[0], pDatLen);
        //        }
        //        if (res != 0)
        //        {
        //            GetErrorText(res);
        //            return null;
        //        }
        //        else
        //        {
        //            return value_byte;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Errors = ex.Message;
        //        return null;
        //    }
        //}
    }
}
