using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using CyberX8_Core;
using CyberX8_RT.Devices.Reservoir;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.IOCore;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.TwinCat;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace CyberX8_RT.Devices.Dose
{
    public class CrossDoseResetRoutine : RoutineBase, IRoutine
    {
        private enum ResetStep
        {
            Reset_True,
            Reset_Wait,
            Reset_False,
            End
        }
        private enum POSStatus
        {
            Busy,
            InTarget,
            Warning,
            Error
        }
        #region 内部变量
        /// 
        /// 模块名称
        /// 
        private string _moduleName;
        /// 
        /// 超时时间
        /// 
        private int _timeOut = 2000;
        /// 
        /// CompactMembranReservoirDevice 
        /// 
        private CompactMembranReservoirDevice _cmReservoirDevice;
        /// 
        /// ReservoirsPersistentValue
        /// 
        private ReservoirsPersistentValue _persistentValue;
        #endregion
        #region 属性
        public RState CurrentState { get { return Runner.Status; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public CrossDoseResetRoutine(string module) : base(module)
        {
            _moduleName = module;
        }
        /// 
        /// Monitor
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(ResetStep.Reset_True, SetTrue, _delay_1ms)
                .Wait(ResetStep.Reset_Wait, WaitCompleteEndStatus, _timeOut)
                .Run(ResetStep.Reset_False, SetFalse, _delay_1ms)
                .End(ResetStep.End, ClearData, _delay_1ms);
            return Runner.Status;
        }
        #region Operation
        /// 
        /// Reset置1
        /// 
        /// 
        private bool SetTrue()
        {
            //Reset = 1
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{_moduleName}.TransferPumpReset");
            bool result = IOModuleManager.Instance.WriteIoValue(ioName, true);
            if (!result)
            {
                return false;
            }
            return true;
        }
        /// 
        /// Wait Reset Done End
        /// 
        /// 
        private bool WaitCompleteEndStatus()
        {
            ushort status = (ushort)_cmReservoirDevice.ReservoirData.TransferPumpPOSStatus;
            if (!CheckPOSStatus(status, POSStatus.Error))
            {
                return true;
            }
            return false;
        }       
        /// 
        /// Reset置0
        /// 
        /// 
        private bool SetFalse()
        {
            //Reset = 0
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{_moduleName}.TransferPumpReset");
            bool result = IOModuleManager.Instance.WriteIoValue(ioName, false);
            if (!result)
            {
                return false;
            }
            _cmReservoirDevice.InitializeCrossDose(true);
            return true;
        }
        /// 
        /// 清除数据
        /// 
        /// 
        private bool ClearData()
        {
            _persistentValue.AutoCrossDoseStartTime = DateTime.MinValue;
            _persistentValue.AutoCrossDoseStartAmpHour = 0;
            _cmReservoirDevice.ReservoirData.RemainingCrossDoseVolume = 0;
            ReservoirsPersistentManager.Instance.UpdatePersistentValue(_moduleName);
            return true;
        }
        #endregion
        /// 
        /// Start
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _cmReservoirDevice = DEVICE.GetDevice($"{_moduleName}");
            if (_cmReservoirDevice == null)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, _moduleName, "Compact Membran Reservoir Device is not exist");
                return RState.Failed;
            }
            _persistentValue = ReservoirsPersistentManager.Instance.GetReservoirsPersistentValue(_moduleName);
            if (_persistentValue == null)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, _moduleName, "Reservoir Persistent Value Object is not exist");
                return RState.Failed;
            }
            return Runner.Start(Module, "Reset Cross Dose");
        }
        /// 
        /// Abort
        /// 
        public void Abort()
        {
            Runner.Stop($"Stop Reset");
        }
        /// 
        /// POS状态判断
        /// 
        /// 
        /// 
        /// 
        private bool CheckPOSStatus(ushort status, POSStatus statusName)
        {
            bool result = false;
            switch (statusName)
            {
                case POSStatus.Busy:
                    byte bit0 = (byte)(status & 0b0001);
                    result = (bit0 == 1) ? true : false;
                    break;
                case POSStatus.InTarget:
                    byte bit1 = (byte)((status & 0b0010) >> 1);
                    result = (bit1 == 1) ? true : false;
                    break;
                case POSStatus.Warning:
                    byte bit2 = (byte)((status & 0b0100) >> 2);
                    result = (bit2 == 1) ? true : false;
                    break;
                case POSStatus.Error:
                    byte bit3 = (byte)((status & 0b1000) >> 3);
                    result = (bit3 == 1) ? true : false;
                    break;
                default:
                    break;
            }
            return result;
        }
    } 
}