using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic;
using CommonClassLib;
namespace SimensCP5611
{
    /// <summary>
    /// Richard.liu 2008
    /// 西门子ＰＬＣ　Ｓ７－３００的ＭＰＩ通讯的静态类，不需要构造和５６１１卡的初始化；
    /// 网络通讯产生的错误记录在ErrorsText属性中；
    /// </summary>
    public static class CSimensCP5611
    {
          static bool IfInit = false;
         /*'****************************************************************************************************************************
       'variables for program
       '****************************************************************************************************************************
       */

          static int InitCount = 0;

          public static int CP5611InitCount
          {
              get { return CSimensCP5611.InitCount; }
              set { CSimensCP5611.InitCount = value; }
          }
          static uint[] value_word = new uint[200];
          static byte[] value_byte = new byte[200];
          
          static int res;
          static int BLOCKNO=0;

          static string Errors;
         /// <summary>
         /// 与mpi网络通讯的故障信息
         /// </summary>
          public static string ErrorsText
          {
              get { return  Errors; }
              set {Errors=value ;}
              
          }
       
        [DllImport("W95_s7.dll")]
        static extern int load_tool(byte nr, string dev, byte[,] adr);
        /*'****************************************************************************************************************************
        'declarations for S7-300/400
        '****************************************************************************************************************************
         */
         [DllImport("W95_s7.dll")]
        static extern int new_ss(byte no);
         [DllImport("W95_s7.dll")]
         public static extern int unload_tool() ;
         //[DllImport("W95_s7.dll")]
         //static extern int ag_info(infotyp value );
         [DllImport("W95_s7.dll")]
        static extern int ag_zustand(ref byte value);
         [DllImport("W95_s7.dll")]
        static extern int db_buch(ushort[] value);

        /*' blockno, no, amount, value*/
         [DllImport("W95_s7.dll")]
         static extern int db_read(int db, int dw, int anz,ref uint value);
         [DllImport("W95_s7.dll")]
         static extern int db_write(int  db , int  dw , int anz ,ref int value );
         [DllImport("W95_s7.dll")]
         static extern int d_field_read(int  db, int nr , int anz ,ref  byte value);
         [DllImport("W95_s7.dll")]
         static extern int d_field_write(int db , int  nr , int  anz ,ref byte  value ) ;
        //'no, amount, value
         [DllImport("W95_s7.dll")]
         static extern int e_field_read(int  nr , int  anz  , ref byte value ) ;
         [DllImport("W95_s7.dll")]
         static extern int a_field_read(int  nr,int  anz ,ref byte  value);
         [DllImport("W95_s7.dll")]
         static extern int a_field_write(int  nr , int  anz , ref byte  value);
         [DllImport("W95_s7.dll")]
         static extern int m_field_read (int  nr, int anz, ref byte value);
         [DllImport("W95_s7.dll")]
         static extern int m_field_write(int nr, int anz,  ref byte value);
         
         [DllImport("W95_s7.dll")]
         static extern int t_field_read  (int nr, int anz, int value);
         [DllImport("W95_s7.dll")]
         static extern int z_field_read  (int nr, int anz, int value);
         [DllImport("W95_s7.dll")]
         static extern int z_field_write  (int nr, int anz, int value);
        //' data, value
         //[DllImport("W95_s7.dll")]
         //static extern int mix_read  (mixdatatype data , byte value);
         //[DllImport("W95_s7.dll")]
         //static extern int mix_write  (mixdatatype data  , byte value);
        //' no, bitno
         [DllImport("W95_s7.dll")]
         static extern int mb_setbit  (short  no, short  bitno);
         [DllImport("W95_s7.dll")]
         static extern int mb_resetbit  (short  no, short  bitno);
        //' no, bitno, value
         [DllImport("W95_s7.dll")]
         static extern int mb_bittest  (short  no, short  bitno, ref short value);

        /*'****************************************************************************************************************************
        'declarations for TeleService
        '****************************************************************************************************************************
        'modem name, standort name, tel.no, username, password , window handel, message, wparam
        
         */
         [DllImport("W95_s7.dll")]
         static extern int ts_dial  (string  ModemName , string StandortName  , string TelNo  , string UserName  , string Password  , int Handle, int Message, int  WParam , string res1  );
         [DllImport("W95_s7.dll")]
         static extern int ts_hang_up_dial  ();

        //'set indicaton on ring -> message if ts-adapter is connected
        //'modem name, no of rings, window handel, message, wparam
         [DllImport("W95_s7.dll")]
         static extern int ts_set_ringindicator  (string  ModemName  , int  Rings, int  Handle, int  Message, int  WParam, string   res1 );

        //'information from ring connected ts-adapter
        //'userid (16 bytes) , asid (1 byte)
         [DllImport("W95_s7.dll")]
         static extern int ts_read_info  (byte value,byte  MPIAdr );
         [DllImport("W95_s7.dll")]
         static extern int ts_hang_up_ring  ();

        //'modem no, modem name, modem name len
         [DllImport("W95_s7.dll")]
         static extern int ts_get_modem_name  (int  no, string  ModemName ,int  ModemNameLen );

        /*'****************************************************************************************************************************
        'declarations for komfort.dll
        '****************************************************************************************************************************
        'errorno, errortext
         */
        [DllImport("komfort.dll")]
         static extern int error_message (int nr,object value);
        //'buffer, amount bytes
         [DllImport("komfort.dll")]
         static extern void swab_buffer (int value, int  anz );
        
         /// <summary>
         ///  初始化CP5611卡
         /// </summary>
         /// <returns>true初始化成功，false失败</returns>
         static bool InitMpi()
         {
            byte[,] btr = new byte[2, 4];
            btr[0, 0] = 2;//连接1中PLC的起始地址
            btr[0, 1] = 0;//SEGMENTID
            btr[0, 2] = 2;//SLOTNO
            btr[0, 3] = 0;//RACKNO
            btr[1, 0] = 0;//连接2中PLC的起始地址
            btr[1, 1] = 0;//SEGMENTID
            btr[1, 2] = 0;//SLOTNO
            btr[1, 3] = 0;//RACKNO
            if (InitCount > 3)
            {
                Errors = "Profibus总线卡：CP5611已经三次初始化失败，总线通讯失败！请退出系统，检查总线网络！";
                return false;
            }
            res = load_tool(1, "S7ONLINE", btr); //'考虑什么时候调用unload_tool()
            if (res != 0)
            {
                ErrMpi();
                InitCount++;
                
                return false;
            }
            else
                IfInit = true;
                return true;
                
         }
         /// <summary>
         /// //'向指定连接connNo的DataTypeIdx数据存储区写入数据
         /// </summary>
         /// <param name="connNo">连接编号</param>
         /// <param name="DataTypeIdx">数据存储区的类型DataTypeIdx=2是Flag(M区)</param>
         /// <param name="addrno">开始地址</param>
         /// <param name="AMOUNT">写入的个数</param>
         /// <param name="value_byte">写入的字节型数组数据</param>
         /// <returns></returns>
         /// 
         public   static bool write_CP5611(byte connNo, int DataTypeIdx,int addrno,int AMOUNT, byte[] value_byte) 
         {
             try 
             {
                 if (IfInit != true)
                 {
                     if (InitMpi() == false)
                     {
                         return false;
                     }
                 }
                res = new_ss(connNo);
                if (res == 0)
                {
                    switch (DataTypeIdx)
                    {
                        
                        case 1:

                            res = a_field_write(addrno, AMOUNT,ref  value_byte[0]);
                            //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "a_field_write", addrno.ToString(), value_byte);
                            break;
                        case 2:
                            
                            res = m_field_write(addrno, AMOUNT,ref  value_byte[0] );//'Flag数据类型
                            //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "m_field_write", addrno.ToString(), value_byte);
                            break;
                        
                        case 7:

                            res = d_field_write(BLOCKNO, addrno, AMOUNT,ref value_byte[0]);
                            //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "d_field_write", BLOCKNO.ToString() + ":" + addrno.ToString(), value_byte);
                            break;
                        default :
                            res = 33028;
                            break;
                    }
                    
                }
                if (res != 0)
                {
                        
                    ErrMpi();
                    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>
        public static bool  DBwrite_CP5611(byte connNo,int dbNo, int nr, int AMOUNT, byte[] value)
        {
            try
            {
                if (IfInit != true)
                {
                    if (InitMpi() == false)
                    {
                        return false;
                    }
                }
                res = new_ss( connNo);
                if (res == 0)
                {
                    res =d_field_write(dbNo, nr,AMOUNT,ref value[0]);
                    //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "d_field_write", dbNo.ToString() + ":" + nr.ToString(), value);
                }
                if (res != 0)
                {
                    ErrMpi();
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {

                Errors = ex.Message;
                return false;
            }


        }
         /// <summary>
         /// //'读出MPI通讯缓冲区的数据
         /// </summary>
         /// <param name="connNo">连接编号</param>
         /// <param name="DataTypeIdx">数据存储区的类型DataTypeIdx=2是Flag(M区)</param>
         /// <param name="addrNo">开始读数据的地址</param>
         /// <param name="AMOUNT">读取数量</param>
         /// <returns>所有字节型数组</returns>
         public static byte[] read_CP5611(byte connNo,int DataTypeIdx,int addrNo,int AMOUNT) 
         {
             try
             {

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

                 res = new_ss( connNo);
                 if (res == 0)
                 {
                     switch (DataTypeIdx)
                     {
                         case 0:
                             res = e_field_read(addrNo, AMOUNT,ref value_byte[0]);
                             //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "e_field_read", addrNo.ToString(), value_byte);

                             break;
                         case 1:
                             res = a_field_read(addrNo, AMOUNT,ref value_byte[0]);
                             //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "a_field_read", addrNo.ToString(), value_byte);
                             break;
                         case 2:
                             res = m_field_read(addrNo, AMOUNT,ref value_byte[0]);// 'Flag数据类型
                             //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "m_field_read", addrNo.ToString(), value_byte);
                             break;
                         case 3:
                             break;

                         case 4:
                             break;
                         case 5:
                             res = 33028;
                             break;
                         case 6:
                             res = 33028;
                             break;
                         case 7:

                             res = d_field_read(BLOCKNO, addrNo, AMOUNT,ref value_byte[0]);
                             //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "d_field_read", BLOCKNO.ToString() + ":" + addrNo.ToString(), value_byte);
                             break;

                     }
                 }
                 if (res != 0)
                 {
                     ErrMpi();
                     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>
        /// <returns>所有字节型数组</returns>
        public static byte[] DB_Read_CP5611( byte connNo, int dbNo, int nr, int AMOUNT)
        {
            try
            {

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

                res = new_ss(connNo);
                if (res == 0)
                {
                    res =d_field_read(dbNo, nr, AMOUNT, ref value_byte[0]);
                    //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "d_field_read", dbNo.ToString() + ":" + nr.ToString(), value_byte);
                }
                if (res != 0)
                {
                    ErrMpi();
                    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_CP5611(byte connNo, byte dbNo, int nr, int AMOUNT,int Bit)
        {
            try
            {

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

                res = new_ss( connNo);
                if (res == 0)
                {
                    
                    res =d_field_read (dbNo, nr, AMOUNT,ref value_byte[0]);
                    //CCarryConvert.WriteDarkCasket("SimensCP5611.CSimensCP5611", "d_field_read", dbNo.ToString() + ":" + nr.ToString(), value_byte);

                }
                if (res != 0)
                {
                    ErrMpi();
                    return null;
                }
                else
                {
                    value_byte[0] =CCarryConvert.GetBitFromInteger( value_byte[0],Bit);
                    
                    return value_byte;
                }
            }
            catch (Exception ex)
            {
                Errors = ex.Message;
                return null;
            }
        }
         /// <summary>
         /// 输出Mpi通讯错误信息
         /// </summary>
         static void ErrMpi()
         {
             try
             {
                 Errors = CReadTextConfig.GetMPIErrors(res);
                 //int aa = error_message(0, "Error.eng");
                 //Errors = "                                                                          ";
                 //aa = error_message(Convert.ToInt32(res), Errors);
             }
             catch (Exception ex)
             {
                 Errors = ex.Message;
             }
         }
         
    }
}
