using Aitex.Core.RT.Device;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CyberX8_RT.Devices.PowerSupplier
{
    public class PowerSupplierSetCurrentRoutine : RoutineBase, IRoutine
    {
        private enum SetCurrentStep
        {
            CloseOutput,
            SetPoint,
            EnableOutput,
            Delay,
            CheckCurrent,
            End
        }
        #region 内部变量
        private double _current = 0;
        private CellPowerSupplier _powerSupplier;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public PowerSupplierSetCurrentRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(SetCurrentStep.CloseOutput, () => _powerSupplier.DisableOutput(), _delay_1ms)
                .Run(SetCurrentStep.SetPoint, SetCurrentPoint, CheckCurrentSetPoint, _delay_2s)
                .Run(SetCurrentStep.EnableOutput, () => _powerSupplier.EnableOutput(), _delay_1ms)
                .Wait(SetCurrentStep.CheckCurrent, () => { return _powerSupplier.PowerSupplierData.Current > 0; },_delay_2s)
                .End(SetCurrentStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 关闭输出
        /// 
        /// 
        private bool CloseOutput()
        {
            return _powerSupplier.DisableOutput();
        }
        /// 
        /// 设置电流
        /// 
        /// 
        private bool SetCurrentPoint() 
        {
            return _powerSupplier.SetCurrent(_current);
        }
        /// 
        /// 检验设置电源数值是否成功
        /// 
        /// 
        private bool CheckCurrentSetPoint()
        {
            return Math.Abs(_powerSupplier.PowerSupplierData.SetPoint - _current) <= Math.Abs(0.1 * _current);
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _current=(double)objs[0];
            _powerSupplier = DEVICE.GetDevice(Module);
            return Runner.Start(Module, $"Start Set Point {_current}");
        }
    }
}