using BsRmlib.EDM;
using Newtonsoft.Json;
using NPOI.SS.UserModel;
using NPOI.XSSF.Model;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Drawing;
using System.Security.Claims;
using System.Threading;

namespace MesWork
{
    public class B_Cnc_Edm
    {
        /// <summary>
        /// 
        /// </summary>
        private CClient edm = null;
        /// <summary>
        /// 
        /// </summary>
        public bool OnLine = false;
        /// <summary>
        /// 
        /// </summary>
        public string ip = "-1";
        /// <summary>
        /// 
        /// </summary>
        public int port = -1;
        /// <summary>
        /// 
        /// </summary>
        public int interval = -1;
        /// <summary>
        /// 
        /// </summary>
        public bool isRun = true;
        /// <summary>
        /// 
        /// </summary>
        public string Id = "-1";
        /// <summary>
        /// 
        /// </summary>
        public string Name = "";


        /// <summary>
        /// 机床状态
        /// -1-离线，0-待机，1-运行，2-报警
        /// </summary>
        public int edmCtrlStatus = 0;
        /// <summary>
        /// 机床报警号及信息
        /// </summary>
        public ushort edmGetError = 0;
        public ushort edmGetError_Old = 0;
        public string edmGetErrMsg = "";
        /// <summary>
        /// 机床提示号及信息
        /// </summary>
        public ushort edmGetComment = 0;
        public ushort edmGetComment_Old = 0;
        public string edmGetComMsg = "";
        /// <summary>
        /// 机床电流电压
        /// </summary>
        public int edmGetCurrent = 0;
        public int edmGetVoltage = 0;

        public string programName = "";

       

        public string edmGetRunTime = "";

        public string progContent = "";

        public uint toolNum_Set = 0;

        public ushort doorAtStatus = 3;
        public ushort doorAtStatus_Old = 3;

        public DateTime start = DateTime.Now;

        public ushort workbench_HasPart = 0;
        public ushort workbench_HasPart_Old = 0;
        public ushort spindleClamp_HasPart = 0;
        public ushort spindleClamp_HasPart_Old = 0;
        public ushort toolLib_HasPart = 0;
        public ushort toolLib_HasPart_Old = 0;
        public int IsSpark = 0;
        public int IsSpark_Old = 0;




        public double[] absolute_j = new double[12];
        public double[] relative_j = new double[12];
        /// <summary>
        /// 
        /// </summary>
        public double[] machine_j = new double[12];
        /// <summary>
        /// 
        /// </summary>
        public double[] jDemo = new double[12];
        /// <summary>
        /// 
        /// </summary>
        public List<JointConfig> Joints = null;
        /// <summary>
        /// 
        /// </summary>
        public string sendStr_Old = "";
        /// <summary>
        /// 
        /// </summary>
        public string payloadInfoStr_Old = "";

        /// <summary>
        /// 
        /// </summary>
        public B_Cnc_Edm()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ipPort"></param>
        /// <param name="interval"></param>
        /// <param name="j1_6"></param>
        /// <param name="modelManagement"></param>
        /// <param name="modelCode"></param>
        public void Start(string ip, int port,int interval, int intervalUpdate, string DeviceCode, string OpName, List<JointConfig> Joints
            ,string tagID_DoorOpen = "", string tagID_DoorClose = ""
            , string tagID_Workbench = "", string tagID_SpindleClamp = "", string tagID_ToolLib = "", string modelCode_Spark = "")
        {
            this.ip = ip;
            this.port = port;
            this.interval = interval;
            this.Id = DeviceCode;
            this.Name = OpName;
            this.Joints = Joints;

            new Thread(new ThreadStart(delegate ()
            {
                while (isRun)
                {
                    try
                    {
                      
                        if (edm == null)
                        {
                            edmCtrlStatus = -1;
                            ReConnRobot();
                        }
                        if (OnLine = edm.IsConnected())
                        {
                            machine_j = ReadResult_To_Array();

                            //到位状态：O:打开或关闭过程中,1:打开到位,2:关闭到位
                            doorAtStatus = edm.EdmStatFrontDoor();
                            if (doorAtStatus_Old != doorAtStatus)
                            {
                                switch (doorAtStatus_Old)
                                {
                                    case 0://0->其他：不处理
                                        break;
                                    case 1://1->0：关闭
                                        MesWorkForm.S_C_B_TagIDTrigger(Name, tagID_DoorClose, "1");
                                        break;
                                    case 2://2->0：打开
                                        MesWorkForm.S_C_B_TagIDTrigger(Name, tagID_DoorOpen, "1");
                                        break;
                                  
                                }
                            }
                            doorAtStatus_Old = doorAtStatus;

                            //机床状态;0-停止，1-运行，2-报警，3-暂停
                            var edmCtrlStatus_NC = edm.EdmCtrlStatus();

                            switch (edmCtrlStatus_NC)
                            {
                                case EnumEdmStatus.Stop:
                                    edmCtrlStatus = 0;
                                    break;
                                case EnumEdmStatus.Run:
                                    edmCtrlStatus = 1;
                                    break;
                                case EnumEdmStatus.Halt:
                                    edmCtrlStatus = 3;
                                    break;
                            }

                            //机床报警号及信息
                            edmGetError = edm.EdmGetError();
                            edmGetErrMsg = edm.EdmGetErrMsg(edmGetError);
                            if (edmGetError_Old != edmGetError)
                            {
                               // B_DB_Opera.Event_AlarmAndTip_Start(Name, edmGetError, edmGetErrMsg, edmGetError.ToString(),1);
                            }
                            edmGetError_Old = edmGetError;

                            //机床提示号及信息
                            edmGetComment = edm.EdmGetComment();
                            edmGetComMsg = edm.EdmGetComMsg(edmGetComment);
                            if (edmGetComment_Old != edmGetComment)
                            {
                               // B_DB_Opera.Event_AlarmAndTip_Start(Name, edmGetComment, edmGetComMsg, edmGetComment.ToString(),2);
                            }
                            edmGetComment_Old = edmGetComment;

                            //机床电流电压
                            edmGetCurrent = edm.EdmGetCurrent();
                            edmGetVoltage = edm.EdmGetVoltage();

                            if (edmGetCurrent > 5)
                            {
                                IsSpark = 1;
                            }
                            else
                            {
                                IsSpark = 0; 
                            }

                            if (IsSpark_Old != IsSpark)
                            {
                               // MesWorkForm.S_C_B_SparkTrigger(Name, modelCode_Spark, IsSpark.ToString());
                            }
                            IsSpark_Old = IsSpark;




                            //获取当前机床主程序
                            programName = edm.PrgGetSelMain();

                            //运行时间
                            edmGetRunTime = edm.EdmGetRunTime().ToString();

                            //程序内容
                            progContent = edm.EdmGetDispNc().nc;

                            //刀具号
                            toolNum_Set = edm.EdmGetToolNo();


                            workbench_HasPart = edm.EdmStatWorkbenExistPiece();
                            if (workbench_HasPart_Old != workbench_HasPart)
                            {
                                MesWorkForm.S_C_B_TagIDTrigger(Name, tagID_Workbench, workbench_HasPart.ToString());
                            }
                            workbench_HasPart_Old = workbench_HasPart;

                            spindleClamp_HasPart = edm.EdmStatSpindleExistTool();
                            if (spindleClamp_HasPart_Old != spindleClamp_HasPart)
                            {
                                MesWorkForm.S_C_B_TagIDTrigger(Name, tagID_SpindleClamp, spindleClamp_HasPart.ToString());
                            }
                            spindleClamp_HasPart_Old = spindleClamp_HasPart;

                            toolLib_HasPart = edm.EdmStatMagaginExistTool();
                            if (toolLib_HasPart_Old != toolLib_HasPart)
                            {
                                MesWorkForm.S_C_B_TagIDTrigger(Name, tagID_ToolLib, toolLib_HasPart.ToString());
                            }
                            toolLib_HasPart_Old = toolLib_HasPart;
                        }
                        else
                        {
                            edmCtrlStatus = -1;
                            Thread.Sleep(10_000);
                            ReConnRobot();
                            continue;
                        }
                        for (int i = 0; i < Joints.Count ; i++)
                        {
                            Joints[i].DeviceCode = DeviceCode;
                            Joints[i].Value = machine_j[i].ToString();
                        }

                        var sendStr = MesWorkForm.Move_Joint(Joints);
                        if (sendStr_Old != sendStr)
                        {
                            sendStr_Old = sendStr;
                            MesWorkForm.SendMsg(sendStr);
                        }




                    }
                    catch (Exception err) { }
                    Thread.Sleep(interval);
                }
            }))
            { IsBackground = true }.Start();

            new Thread(new ThreadStart(delegate () {
                while (isRun)
                {
                    try
                    {
                        for (int i = 0; i < Joints.Count; i++)
                        {
                            Joints[i].DeviceCode = DeviceCode;
                            Joints[i].Value = machine_j[i].ToString();
                        }

                        var payload = MesWorkForm.Move_Joint(Joints);
                        MesWorkForm.SendMsg(payload);

                    }
                    catch (Exception err) 
                    { }
                    Thread.Sleep(intervalUpdate);
                }
            }))
            { IsBackground = true }.Start();

            new Thread(new ThreadStart(delegate ()
            {
                while (isRun)
                {
                    UpdateDataToSql();
                    UpdateStationStatusToSql();


                    var deviceInfo = new DeviceInfo();
                    deviceInfo.order = "";
                    deviceInfo.Name = Name;
                    deviceInfo.Id = Id;

                    deviceInfo.Status = edmCtrlStatus.ToString();
                    deviceInfo.Program = programName;
                    deviceInfo.ProgramStatus = "";
                    deviceInfo.Feed = "";
                    deviceInfo.Speed = "";
                    deviceInfo.Rapid = "";
                    deviceInfo.Current = edmGetCurrent.ToString();
                    deviceInfo.Voltage = edmGetVoltage.ToString();
                    deviceInfo.Axis = new List<AxisInfo>();
                    deviceInfo.Tool = null;
                    deviceInfo.OtherParameter = new List<ParameterInfo>();
                    deviceInfo.Alarm = new List<AlarmInfo>();
                    if (edmGetErrMsg.Length > 0)
                    {
                        deviceInfo.Alarm.Add(new AlarmInfo()
                        {
                            AlarmCode = edmGetError.ToString(),
                            Alarm = edmGetErrMsg,
                            AlarmTime = DateTime.Now.ToString("G")
                        });
                    }
                    deviceInfo.Tip = new List<TipInfo>();
                    if (edmGetComMsg.Length > 0)
                    {
                        deviceInfo.Tip.Add(new TipInfo()
                        {
                            TipCode = edmGetComment.ToString(),
                            Tip = edmGetComMsg,
                            TipTime = DateTime.Now.ToString("G")
                        });
                    }

                    deviceInfo.Axis.Add(new AxisInfo() { AxisName = "X", AxisValue = machine_j[0].ToString() });
                    deviceInfo.Axis.Add(new AxisInfo() { AxisName = "Y", AxisValue = machine_j[1].ToString() });
                    deviceInfo.Axis.Add(new AxisInfo() { AxisName = "Z", AxisValue = machine_j[2].ToString() });
                    deviceInfo.Axis.Add(new AxisInfo() { AxisName = "U", AxisValue = machine_j[3].ToString() });
                    deviceInfo.Axis.Add(new AxisInfo() { AxisName = "V", AxisValue = machine_j[4].ToString() });
                    deviceInfo.Axis.Add(new AxisInfo() { AxisName = "W", AxisValue = machine_j[5].ToString() });

                    var payloadInfoStr = MesWorkForm.Make_DeviceInfo(new List<DeviceInfo>() { deviceInfo });

                    DateTime current = DateTime.Now;
                    if ((current - start).TotalMilliseconds > 1000)
                    {
                        // if (payloadInfoStr_Old != payloadInfoStr)
                        {
                            payloadInfoStr_Old = payloadInfoStr;
                            MesWorkForm.SendMsg(payloadInfoStr);
                        }
                        start = current;
                    }


                    Thread.Sleep(1000);
                }
            }))
            { IsBackground = true }.Start();

            new Thread(new ThreadStart(delegate ()
            {
                while (isRun)
                {
                    InsertStationStatusToSql();
                    Thread.Sleep(60 * 1000);
                }
            }))
            { IsBackground = true }.Start();

        }

        /// <summary>
        /// 
        /// </summary>
        public void TimelyUpdate()
        {
            var sendStr = MesWorkForm.Move_Joint(Joints);
            MesWorkForm.SendMsg(sendStr);
        }


        /// <summary>
        /// 
        /// </summary>
        ~B_Cnc_Edm()
        {
            DisConn();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public void DisConn()
        {
            isRun = false;
            Thread.Sleep(199);
            edm?.Disconnect();

        }


       /// <summary>
       /// 
       /// </summary>
        private void ReConnRobot()
        {
            if (edm != null)
            {
                edm?.Disconnect();
            }
            edm = new CClient();
            var success = edm.Connect(ip, (uint)port);
            if (success)
            {
            }

        }

     


        /// <summary>
        /// 
        /// </summary>
        /// <param name="j1_6"></param>
        /// <returns></returns>
        private double[] ReadResult_To_Array()
        {
            if (MesWorkForm.IsDemoMesServer == 1)
            {
                return jDemo;
            }

            double[] joint = new double[12];

            var X = edm.EdmGetMachine(EnumAxisNo.X) / GetAxisDec(EnumAxisNo.X);
            var Y = edm.EdmGetMachine(EnumAxisNo.Y) / GetAxisDec(EnumAxisNo.Y);
            var Z = edm.EdmGetMachine(EnumAxisNo.Z) / GetAxisDec(EnumAxisNo.Z);
            var U = edm.EdmGetMachine(EnumAxisNo.U) / GetAxisDec(EnumAxisNo.U);
            var V = 0;
            var W = 0;

            joint[0] = X;
            joint[1] = Y;
            joint[2] = Z;
            joint[3] = U;
            joint[4] = V;
            joint[5] = W;


            return joint;
        }

        private double GetAxisDec(EnumAxisNo axis)
        {
            CPosInfo info = edm.EdmGetPosInfo(axis);
            if (info.dec == 3)
                return 1000.0;
            else if (info.dec == 4)
                return 10000.0;
            return 1000.0;
        }

        /// <summary>
        /// 手动测试读取
        /// </summary>
        /// <param name="j1_6"></param>
        /// <param name="j7"></param>
        /// <returns></returns>
        public string ReadTest(string robotName)
        {
            return "【" + robotName + "】" + MesWorkForm.Move_Joint(Joints);  
        }

        public void UpdateDataToSql()
        {
            //StoredProcedure("Event_CNC_Update");
        } 
      
        //private void StoredProcedure(string pName)
        //{
        //    var sqlParameter = new SqlParameter[] {
        //         new SqlParameter("@DeviceCode", Id),
        //         new SqlParameter("@Online", OnLine.ToString()),
        //         new SqlParameter("@StationName", Name),
        //         new SqlParameter("@SlaveAddr", $"{ip}:{port}"),
        //         new SqlParameter("@Path", 1),

        //         new SqlParameter("@程序号",0 ),
        //         new SqlParameter("@程序名称", programName),
        //         new SqlParameter("@主轴转速组", JsonConvert.SerializeObject(new double[6])),
        //         new SqlParameter("@坐标_绝对组", JsonConvert.SerializeObject(new double[6])),
        //         new SqlParameter("@坐标_相对组", JsonConvert.SerializeObject(new double[6])),
        //         new SqlParameter("@坐标_机械组", JsonConvert.SerializeObject(machine_j)),
        //         new SqlParameter("@伺服负载组", JsonConvert.SerializeObject(new double[6])),
        //         new SqlParameter("@进给速度",0 ),
        //         new SqlParameter("@进给倍率",0),
        //         new SqlParameter("@主轴倍率", 0),
        //         new SqlParameter("@已加工数量",0 ),
        //         new SqlParameter("@总加工数量", 0),
        //         new SqlParameter("@工作模式",JsonConvert.SerializeObject(new double[6] )),
        //         new SqlParameter("@TM模式", 0),
        //         new SqlParameter("@自动模式", 0),
        //         new SqlParameter("@运行状态",0),
        //         new SqlParameter("@轴_停留状态",0),
        //         new SqlParameter("@matb", 0),
        //         new SqlParameter("@急停", 0),
        //         new SqlParameter("@报警",0 ),
        //         new SqlParameter("@编辑状态", 0),
        //         new SqlParameter("@开机时间", 0),
        //         new SqlParameter("@运行时间", edmGetRunTime),
        //         new SqlParameter("@切削时间",0 ),
        //         new SqlParameter("@循环时间", 0),
        //         new SqlParameter("@机床时间", 0),
        //         new SqlParameter("@加工次数", 0),
        //         new SqlParameter("@额定次数", 0),
        //         new SqlParameter("@程序内容", progContent),
        //         new SqlParameter("@刀具号", (int)toolNum_Set),
        //         //北京电火花项目
        //         new SqlParameter("@机床状态",(int)edmCtrlStatus),
        //         new SqlParameter("@报警代码",(int)edmGetError),
        //         new SqlParameter("@报警内容",edmGetErrMsg),
        //         new SqlParameter("@提示代码",(int)edmGetError),
        //         new SqlParameter("@提示内容",edmGetErrMsg),
        //         new SqlParameter("@电流",(int)edmGetCurrent),
        //         new SqlParameter("@电压",(int)edmGetVoltage),


        //        };
        //    MesWorkForm.taskSql.Enqueue(new NJ_ZC.ParamT
        //    {
        //        procedureName = pName,
        //        sqlParameter = sqlParameter
        //    });
        //}


        private void UpdateStationStatusToSql()
        {
            //Event_StationStatus("Event_StationStatus_Update");
        }
        private void InsertStationStatusToSql()
        {
            //Event_StationStatus("Event_StationStatus_Insert");
        }

        //public void Event_StationStatus(string pName)
        //{
        //    try
        //    {
        //        var ChangeTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

        //        MesWorkForm.taskSql.Enqueue(new NJ_ZC.ParamT
        //        {
        //            procedureName = pName,
        //            sqlParameter = new SqlParameter[] {
        //                new SqlParameter("@OpName", Name),
        //                     new SqlParameter("@Status", (int)edmCtrlStatus),
        //                     new SqlParameter("@ChangeTime",ChangeTime)
        //                 }
        //        });

        //    }
        //    catch (Exception err)
        //    {
        //    }


        //}



    }
}
