using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QMAPP.FJC.Entity.Basic;
using OPCPLC;
using QMAPP.FJC.DAL.Basic;
using QMAPP.FJC.Entity;
using System.Configuration;
using OPCAutomation;
using System.Threading;

namespace EQUIPINTERFACETEST
{
    /// <summary>
    /// 浇注设备
    /// </summary>
    public class CastingMachineTest
    {
        //用来存储工控机发起连接服务器建立双通道连接的设备信息
        public List<string> connectMachineList_casting;

        //用来存储生产设备信息
        public List<MachineInfo> machineList_casting;

        //用来存储设备加工参数信息
        //key值样式为:设备号+模具号+读写状态+操作类别+数据库字段
        public Dictionary<string, int> parameterValueDict_casting;


        private Dictionary<int, string> clientHandleDict_casting = new Dictionary<int, string>();

        private Dictionary<string, string> colunmConDict = new Dictionary<string, string>();


        private int clientHandleValue = 0;

        //加工参数列表静态变量
        public List<ParameterConfig> paraConfigList_casting;

        //设备参数信息
        public List<ParameterConfig> moldList_casting;

        //OPC零件信息列表静态变量
        public Dictionary<string, OPCPLCAutomation> opcplcConnectionList_casting;

        public void InitParameter()
        {
            parameterValueDict_casting = new Dictionary<string, int>();

            moldList_casting = new List<ParameterConfig>();

            machineList_casting = new List<MachineInfo>();
            //获取数据库中所有的生产设备信息

            opcplcConnectionList_casting = new Dictionary<string, OPCPLCAutomation>();

            try
            {
                #region 获取数据库中所有的生产设备信息

                MachineInfoDAL machineDal = new MachineInfoDAL();

                machineList_casting = machineDal.GetList(new MachineInfo() { PROCESSTYPE = EnumGeter.ProcessType.jiaozhu.GetHashCode().ToString() });

                #endregion

                #region 获取所有的配置信息

                ParameterConfigDAL paraConDal = new QMAPP.FJC.DAL.Basic.ParameterConfigDAL();
                paraConfigList_casting = paraConDal.GetList(new ParameterConfig() { MACHINECODDE = machineList_casting[0].MACHINECODDE });

                #endregion

                #region 获取设备模块信息

                //对加工参数配置信息按照设备及模具信息进行分组
                var objlist = from pc in paraConfigList_casting
                              group pc by new { pc.MACHINECODDE, pc.MOLDNUMBER } into g
                              select new ParameterConfig { MACHINECODDE = g.Key.MACHINECODDE, MOLDNUMBER = g.Key.MOLDNUMBER };

                //添加到静态变量中
                foreach (var ob in objlist)
                {
                    moldList_casting.Add(new ParameterConfig() { MACHINECODDE = ob.MACHINECODDE, MOLDNUMBER = ob.MOLDNUMBER });
                }

                //按照设备进行排序
                moldList_casting = moldList_casting.OrderBy(o => o.MACHINECODDE).OrderBy(o => o.MOLDNUMBER).ToList<ParameterConfig>();

                #endregion

                #region 加载模块下的加工参数配置信息

                //变量所有的模具信息
                foreach (var m in moldList_casting)
                {
                    MachineInfo machineEntity = machineList_casting.First(o => o.MACHINECODDE == m.MACHINECODDE);

                    #region 加工参数

                    List<ParameterConfig> paraList = paraConfigList_casting
                         .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER && o.COLUMNTYPE == "0")
                         .ToList<ParameterConfig>();


                    if (paraList.Count > 0)
                    {
                        OPCPLCAutomation gtxConnection = new OPCPLC.OPCPLCAutomation();

                        //opcServer服务器IP
                        string opcServerIP = ConfigurationManager.AppSettings.Get("OPCServerIP");

                        //opcServer服务名称
                        string opcServerName = ConfigurationManager.AppSettings.Get("OPCServerName");

                        gtxConnection.GetListOPCServers("127.0.0.1");
                        //连接Opc服务
                        gtxConnection.ConnectRemoteServer(opcServerName, "127.0.0.1");

                        gtxConnection.CreateGroup(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":GetData");

                        //变该模块下的所有参数信息
                        foreach (var pc in paraList)
                        {
                            //初始化字典名称:  设备名称+模块编号+字段名称
                            string dicKeyStr = machineEntity.MACHINECODDE + ":" + m.MOLDNUMBER + ":" + pc.COLUMNCODE;

                            //初始化字段信息值为0
                            parameterValueDict_casting.Add(dicKeyStr, 0);

                            //获取opc中tagName
                            string itemName = pc.CONNECTIONSTRING;

                            clientHandleValue++;

                            clientHandleDict_casting.Add(clientHandleValue, dicKeyStr);

                            //将字典中的与PLC内存地址向绑定
                            parameterValueDict_casting[dicKeyStr] = gtxConnection.AddKepItem(itemName, clientHandleValue);

                            colunmConDict.Add(dicKeyStr, m.MACHINECODDE + ":" + m.MOLDNUMBER + ":GetData");
                        
                        }

                        //添加PLC连接信息
                        opcplcConnectionList_casting.Add(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":GetData", gtxConnection);
                    }

                    #endregion 

                    #region 写入参数

                    List<ParameterConfig> writeList = paraConfigList_casting
                        .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER && (o.COLUMNTYPE == "2" || o.COLUMNTYPE == "6"))
                        .ToList<ParameterConfig>();


                    if (writeList.Count > 0)
                    {
                        OPCPLCAutomation gtxConnection = new OPCPLC.OPCPLCAutomation();

                        //opcServer服务器IP
                        string opcServerIP = ConfigurationManager.AppSettings.Get("OPCServerIP");

                        //opcServer服务名称
                        string opcServerName = ConfigurationManager.AppSettings.Get("OPCServerName");

                        gtxConnection.GetListOPCServers("127.0.0.1");
                        //连接Opc服务
                        gtxConnection.ConnectRemoteServer(opcServerName, "127.0.0.1");

                        gtxConnection.CreateGroup(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":WriteData");

                        //变该模块下的所有参数信息
                        foreach (var pc in writeList)
                        {
                            //初始化字典名称:  设备名称+模块编号+字段名称
                            string dicKeyStr = machineEntity.MACHINECODDE + ":" + m.MOLDNUMBER + ":" + pc.COLUMNCODE;

                            //初始化字段信息值为0
                            parameterValueDict_casting.Add(dicKeyStr, 0);

                            //获取opc中tagName
                            string itemName = pc.CONNECTIONSTRING;

                            clientHandleValue++;

                            clientHandleDict_casting.Add(clientHandleValue, dicKeyStr);

                            //将字典中的与PLC内存地址向绑定
                            parameterValueDict_casting[dicKeyStr] = gtxConnection.AddKepItem(itemName, clientHandleValue);

                            colunmConDict.Add(dicKeyStr, m.MACHINECODDE + ":" + m.MOLDNUMBER + ":WriteData");
                        }

                        //添加PLC连接信息
                        opcplcConnectionList_casting.Add(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":WriteData", gtxConnection);
                    }

                    #endregion

                    #region 完成标记和设备扫描条码信息

                    List<ParameterConfig> monitorList = paraConfigList_casting
                        .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER && o.COLUMNTYPE == "1")
                        .ToList<ParameterConfig>();

                    if (monitorList.Count > 0)
                    {
                        OPCPLCAutomation gtxConnection = new OPCPLC.OPCPLCAutomation();

                        //opcServer服务器IP
                        string opcServerIP = ConfigurationManager.AppSettings.Get("OPCServerIP");

                        //opcServer服务名称
                        string opcServerName = ConfigurationManager.AppSettings.Get("OPCServerName");

                        gtxConnection.GetListOPCServers("127.0.0.1");
                        //连接Opc服务
                        gtxConnection.ConnectRemoteServer(opcServerName, "127.0.0.1");

                        gtxConnection.CreateGroup(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":Monitor");


                        //变该模块下的所有参数信息
                        foreach (var pc in monitorList)
                        {
                            //初始化字典名称:  设备名称+模块编号+字段名称
                            string dicKeyStr = machineEntity.MACHINECODDE + ":" + m.MOLDNUMBER + ":" + pc.COLUMNCODE;

                            //初始化字段信息值为0
                            parameterValueDict_casting.Add(dicKeyStr, 0);

                            //获取opc中tagName
                            string itemName = pc.CONNECTIONSTRING;

                            clientHandleValue++;

                            clientHandleDict_casting.Add(clientHandleValue, dicKeyStr);

                            //将字典中的与PLC内存地址向绑定
                            parameterValueDict_casting[dicKeyStr] = gtxConnection.AddKepItem(itemName, clientHandleValue);

                            colunmConDict.Add(dicKeyStr, m.MACHINECODDE + ":" + m.MOLDNUMBER + ":Monitor");
                        }

                        gtxConnection.KepGroups.DefaultGroupIsActive = true;//激活组。  
                        gtxConnection.KepGroups.DefaultGroupDeadband = 0;// 死区值,设为0时,服务器端该组内任何数据变化都通知组。  
                        gtxConnection.KepGroups.DefaultGroupUpdateRate = 200;//默认组群的刷新频率为200ms  
                        gtxConnection.KepGroup.UpdateRate = 200;//刷新频率为1秒。  
                        gtxConnection.KepGroup.IsSubscribed = true;//使用订阅功能,即可以异步,默认false 

                        gtxConnection.KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);

                        //添加PLC连接信息
                        opcplcConnectionList_casting.Add(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":Monitor", gtxConnection);

                    }

                    #endregion
                }

                #endregion
            }
            catch (Exception ex)
            {

            }
        }


        private void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {

            try
            {
                //延迟一秒
                Thread.Sleep(1000);

                //为了测试,所以加了控制台的输出,来查看事物ID号
                //Console.WriteLine("********"+TransactionID.ToString()+"*********");
                for (int i = 1; i <= NumItems; i++)
                {
                    //获取写入的值
                    var itemValue = ItemValues.GetValue(i);

                    //获取客户端句柄
                    int chvalue = Convert.ToInt32(ClientHandles.GetValue(i));

                    //获取服务端字典key值
                    string dicKeyStr = clientHandleDict_casting[chvalue];

                    //获取设备信息
                    string machCode = dicKeyStr.Substring(0, dicKeyStr.IndexOf(':'));

                    string moldAndColumn = dicKeyStr.Substring(dicKeyStr.IndexOf(':') + 1);

                    //获取模块信息
                    string moldNumber = moldAndColumn.Substring(0, moldAndColumn.IndexOf(':'));

                    //获取字段名称
                    string columnCode = dicKeyStr.Substring(dicKeyStr.LastIndexOf(':') + 1);

                    ParameterConfig currentPC = paraConfigList_casting.First(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && o.COLUMNCODE == columnCode);

                    //完成标记
                    if (currentPC.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.COMPLETEFLAG.GetHashCode().ToString())
                    {
                        //如果完成标记表示更新了加工参数
                        //获取所有的加工参数
                        if ((Boolean)itemValue == true)
                        {
                            Console.WriteLine(System.DateTime.Now.ToLongTimeString() + "完成标记修改为true");

                            List<ParameterConfig> paraList = paraConfigList_casting
                             .Where(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && o.COLUMNTYPE == "0")
                             .ToList<ParameterConfig>();

                           
                           Console.WriteLine("读取加工参数标记值为:" + opcplcConnectionList_casting["1A-FB0004:1:WriteData"].ReadtagValue(parameterValueDict_casting["1A-FB0004:1:READED"]).ToString());

                            Console.WriteLine("开始读取加工参数");

                            foreach (var parameter in paraList)
                            {

                                string item = parameter.MACHINECODDE + ":" + parameter.MOLDNUMBER + ":" + parameter.COLUMNCODE;

                                string conListKey = colunmConDict[item];

                                OPCPLCAutomation con = opcplcConnectionList_casting[conListKey];

                                var result = con.ReadtagValue(parameterValueDict_casting[item]);

                                if (result != null)
                                {
                                    //if (parameter.COLUMNCODE == "DAY" || parameter.COLUMNCODE == "MONTH" || parameter.COLUMNCODE == "YEAR" || parameter.COLUMNCODE == "HOUR"
                                    

                                    Console.WriteLine(item.ToString() + "值为" + result.ToString());
                                    WriteLog.Write(item.ToString() + "值为" + result.ToString());
                                   
                                }
                            }


                            opcplcConnectionList_casting["1A-FB0004:1:WriteData"].WritetagValue(parameterValueDict_casting["1A-FB0004:1:READED"], true);
                            Console.WriteLine("修改已读取加工参数标记");


                            Console.WriteLine(":::::::读取加工参数完成:::::::");

                        }
                        else
                        {
                            Console.WriteLine("完成标记修改为false");
                        }

                    }

                }
            }
            catch (Exception ex)
            {

                Console.WriteLine("系统出现异常:"+ex.Message);
            }

        }




        public  void WriteParameter()
        {
            //opcplcConnectionList_casting["1A-FB0004:1:WriteData"].WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG1"], false);
            opcplcConnectionList_casting["1A-FB0004:1:WriteData"].WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG1"], true);

           //var o=opcplcConnectionList_casting["1A-FB0004:1:WriteData"].ReadtagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG2"]);
           //Console.WriteLine(o.ToString());
            //opcplcConnectionList_casting["1A-FB0004:1:WriteData"].WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG3"], false);
            //opcplcConnectionList_casting["1A-FB0004:1:WriteData"].WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG4"], false);
            //opcplcConnectionList_casting["1A-FB0004:1:WriteData"].WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG5"], false);
            ////opcplcConnectionList_casting["1A-FB0004:1:WriteData"].WritetagValue(parameterValueDict_casting["1A-FB0004:1:READED"], false);
        
        }

        public void Test()
        {

            try
            {

                while (true)
                {
                    Thread.Sleep(5000);

                    WriteLog.Write(System.DateTime.Now.ToString("yyyy:MM:dd HH:mm:ss"));

                    foreach (var item in parameterValueDict_casting.Keys)
                    {

                        string conListKey = colunmConDict[item];

                        OPCPLCAutomation con = opcplcConnectionList_casting[conListKey];

                        var result = con.ReadtagValue(parameterValueDict_casting[item]);

                        if (result != null)
                        {
                            Console.WriteLine(item.ToString() + "值为" + result.ToString());
                            WriteLog.Write(item.ToString() + "值为" + result.ToString());
                        }
                        else
                        {
                            Console.WriteLine(item.ToString() + "值为null");

                            WriteLog.Write(item.ToString() + "值为null");
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                
                throw ex;
            }
            


        }

        public void ChangeMcReady_Flag1()
        {
            opcplcConnectionList_casting.Values.First().WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG1"], false);
            opcplcConnectionList_casting.Values.First().WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG2"], true);
            opcplcConnectionList_casting.Values.First().WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG3"], true);
            opcplcConnectionList_casting.Values.First().WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG4"], true);
            opcplcConnectionList_casting.Values.First().WritetagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG5"], true);
            //var result = opcplcConnectionList_casting.Values.First().ReadtagValue(parameterValueDict_casting["1A-FB0004:1:MCREADYFLAG1"]);
            //Console.WriteLine("1A-FB0004:1:MCREADYFLAG1修改后" + "值为" + result.ToString());
        }

        internal void ReadAllg003()
        {

            var result = opcplcConnectionList_casting[colunmConDict["1A-FB0004:1:ALLG003"]].ReadtagValue(parameterValueDict_casting["1A-FB0004:1:ALLG003"]);
            Console.WriteLine("ALLG003值为:" + result);
        }
    }
}