using Aitex.Core.Util;

namespace Aitex.Core.RT.Tolerance
{
	/// <summary>
	/// 误差检查器。
	/// </summary>
	public class ToleranceChecker
	{
        #region Variables

        private readonly DeviceTimer _timer = new();
        private readonly R_TRIG _trigger = new();
        private bool _started;

        #endregion

        #region Properties

        /// <summary>
        /// 返回是否检测到误差超限异常。
        /// </summary>
        public bool Trig => _trigger.Q;
        
        /// <summary>
        /// 返回被检测值是否已超出误差范围。
        /// </summary>
        public bool Result => _trigger.M;

        /// <summary>
        /// 复位定时器和误差超限触发器。
        /// </summary>
        public bool RST
        {
            set
            {
                _started = false;
                _trigger.RST = value;
            }
        }

        #endregion


        #region Constructors

        /// <summary>
        /// 构造误差检查器对象实例。
        /// </summary>
        public ToleranceChecker()
        {
            _timer.Start(0.0);
        }

        /// <summary>
        /// 构造误差检查器对象实例。
        /// </summary>
        /// <param name="durationSec">误差超限持续时长。</param>
        public ToleranceChecker(double durationSec)
        {
            _timer.Start(durationSec * 1000.0);
        }

        #endregion


        #region Methods

        /// <summary>
        /// 检查器复位。
        /// </summary>
        /// <param name="durationSec">误差超限持续时长。</param>
        public void Reset(double durationSec)
        {
            _timer.Start(durationSec * 1000.0);
            RST = true;
        }

        /// <summary>
        /// 后台扫描函数，判断被监测值是否在指定的时间内持续超出范围。
        /// </summary>
        /// <param name="value">被监测值。</param>
        /// <param name="min">范围下限。</param>
        /// <param name="max">范围上限。</param>
        /// <param name="durationSec">持续时长，单位秒。</param>
        public void Monitor(double value, double min, double max, double durationSec)
        {
            if (!_started || (value >= min && value <= max))
            {
                _started = true;
                _timer.Start(durationSec * 1000.0);
            }
            _trigger.CLK = _timer.IsTimeout();
        }

        #endregion



    }
}
