using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Beckhoff.AxisProvider;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.TwinCat;
using MECF.Framework.RT.Core.Equipments;
using CyberX8_RT.Devices.AXIS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.IOCore;

namespace CyberX8_RT.Devices.PUF
{
    public class PufDistanceSensor : BaseDevice, IDevice
    {
        #region 常量
       
        private const string STUCK_WAFER_200_DISTANCE_OFFSET1 = "CheckStuckWafer200_DistanceOffset1";
        private const string STUCK_WAFER_200_DISTANCE_OFFSET2 = "CheckStuckWafer200_DistanceOffset2";
        private const string STUCK_WAFER_200_TORQUE_LIMIT = "CheckStuckWafer200_TorqueLimit_Percent";

        private const string DISTANCE_SENSOR1="DistanceSensor1";
        private const string DISTANCE_SENSOR2 = "DistanceSensor2";
        private const string DISTANCE_OFFSET1 = "DistanceOffset1";
        private const string DISTANCE_OFFSET2 = "DistanceOffset2";

        private const double STANDARD = 100;
        #endregion

        #region 内部变量
        //动态变量主要是用于calibrate显示
        private double _dynamicOffset1 = 0;
        private double _dynamicOffset2 = 0;
        //执行过程中主要用于以下两个变量
        private double _offset1 = 0;
        private double _offset2 = 0;
        /// <summary>
        /// distance sensor1
        /// </summary>
        private double _distanceSensor1;
        /// <summary>
        /// distance sensor2
        /// </summary>
        private double _distanceSensor2;
        /// <summary>
        /// Distance sensor阈值
        /// </summary>
        private double _checkStuckWafer_DistanceSensorThreshold_mm;
        #endregion
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="moduleName"></param>
        public PufDistanceSensor(string moduleName): base(moduleName,"DistanceSensor", "DistanceSensor", "DistanceSensor")
        {
            LoadConfigParameter();
            _dynamicOffset1 = _offset1;
            _dynamicOffset2 = _offset2;
        }
        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public bool Initialize()
        {
            InitializeData();
            SubscribeValueAction();
            return true;
        }
        /// <summary>
        /// 订阅变量数值发生变化
        /// </summary>
        private void SubscribeValueAction()
        {
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", DISTANCE_SENSOR1, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", DISTANCE_SENSOR2, UpdateVariableValue);
        }
        /// 更新变量数值
        /// </summary>
        /// <param name="variable"></param>
        /// <param name="value"></param>
        private void UpdateVariableValue(string variable, object value)
        {
            if (variable == $"{DISTANCE_SENSOR1}")
            {
                _distanceSensor1 = (double)value;
            }
            else if (variable == $"{DISTANCE_SENSOR2}")
            {
                _distanceSensor2 = (double)value;
            }
        }
        /// <summary>
        /// 初始化数据
        /// </summary>
        private void InitializeData()
        {
            DATA.Subscribe($"{Module}.{DISTANCE_OFFSET1}", () => _dynamicOffset1, Aitex.Core.Util.SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.{DISTANCE_OFFSET2}", () => _dynamicOffset2, Aitex.Core.Util.SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.{DISTANCE_SENSOR1}", () => _distanceSensor1, Aitex.Core.Util.SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.{DISTANCE_SENSOR2}", () => _distanceSensor2, Aitex.Core.Util.SubscriptionAttribute.FLAG.IgnoreSaveDB);
        }
        /// <summary>
        /// 保存参数
        /// </summary>
        /// <param name="offset1"></param>
        /// <param name="offset2"></param>
        public void SaveConfig(double offset1,double offset2)
        {
            _dynamicOffset1=offset1;
            _dynamicOffset2=offset2;
            SC.SetItemValue($"{Module}.{STUCK_WAFER_200_DISTANCE_OFFSET1}", offset1);
            SC.SetItemValue($"{Module}.{STUCK_WAFER_200_DISTANCE_OFFSET2}", offset2);
        }
        /// <summary>
        /// Stick Distance检验结果
        /// </summary>
        /// <returns></returns>
        public bool CheckStickDistanceStatus()
        {
            LoadConfigParameter();
            double inter1 = STANDARD - _distanceSensor1;
            double inter2=STANDARD - _distanceSensor2;
            double offsetInter1=Math.Abs(_offset1- inter1);
            double offsetInter2=Math.Abs(_offset2- inter2);
            if(offsetInter1>_checkStuckWafer_DistanceSensorThreshold_mm)
            {
                LOG.WriteLog(eEvent.ERR_PUF, Module, $"offset bias {offsetInter1} is over {_checkStuckWafer_DistanceSensorThreshold_mm}");
                return false;
            }
            if (offsetInter2 > _checkStuckWafer_DistanceSensorThreshold_mm)
            {
                LOG.WriteLog(eEvent.ERR_PUF, Module, $"offset bias {offsetInter2} is over {_checkStuckWafer_DistanceSensorThreshold_mm}");
                return false;
            }
            return true;
        }

        private void LoadConfigParameter()
        {
            _offset1 = SC.GetValue<double>($"{Module}.{STUCK_WAFER_200_DISTANCE_OFFSET1}");
            _offset2 = SC.GetValue<double>($"{Module}.{STUCK_WAFER_200_DISTANCE_OFFSET2}");

            if (SC.ContainsItem($"{Module}.CheckStuckWafer_DistanceSensorThreshold_mm"))
            {
                _checkStuckWafer_DistanceSensorThreshold_mm = SC.GetValue<double>($"{Module}.CheckStuckWafer_DistanceSensorThreshold_mm");
            }
        }
        public void Monitor()
        {
        }

        public void Reset()
        {
        }

        public void Terminate()
        {
        }
    }
}