using Aitex.Core.RT.Device;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Routine;
using PunkHPX8_Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.TwinCat;
using MECF.Framework.Common.IOCore;
using Aitex.Core.RT.Log;
namespace PunkHPX8_RT.Devices.Safety
{
    public class SafetyResetRoutine : RoutineBase, IRoutine
    {
        private enum SafetyResetStep
        {
            RunStop,
            ErrAck,
            LockCasseteDoors,
            LockCellDoors,
            LockAlignerDoors,
            FacilityStoEstopRestart,
            FacilityEstopDelay,
            PlatingCell12Sto1EstopRestart,
            PlatingCell12Sto1EstopDelay,
            PlatingCell12Sto2EstopRestart,
            PlatingCell12Sto2EstopDelay,
            PlatingCell34Sto1EstopRestart,
            PlatingCell34Sto1EstopDelay,
            PlatingCell34Sto2EstopRestart,
            PlatingCell34Sto2EstopDelay,
            Res12StoEstopRestart,
            Res12StoEstopDelay,
            Res34StoEstopRestart,
            Res34StoEstopDelay,
            VpwStoEstopRestart,
            VpwStoEstopDelay,
            SrdStoEstopRestart,
            SrdStoEstopDelay,
            SlsRestart,
            End
        }
        #region 常量
        private const string RUNSTOP = "RunStop";
        #endregion
        #region 内部变量
        private SafetyToggleRoutine _errAckToggleRoutine;
        private SafetyToggleRoutine _facilityStoEstopRestart;
        private SafetyToggleRoutine _platingCell12Sto1EstopRestart;
        private SafetyToggleRoutine _platingCell12Sto2EstopRestart;
        private SafetyToggleRoutine _platingCell34Sto1EstopRestart;
        private SafetyToggleRoutine _platingCell34Sto2EstopRestart;
        private SafetyToggleRoutine _res12StoEstopRestart;
        private SafetyToggleRoutine _res34StoEstopRestart;
        private SafetyToggleRoutine _vpwStoEstopRestart;
        private SafetyToggleRoutine _srdStoEstopRestart;
        private SafetyDevice _device;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public SafetyResetRoutine(string module) : base(module)
        {
            _errAckToggleRoutine = new SafetyToggleRoutine(module);
            _facilityStoEstopRestart = new SafetyToggleRoutine(module);
            _platingCell12Sto1EstopRestart=new SafetyToggleRoutine(module);
            _platingCell12Sto2EstopRestart=new SafetyToggleRoutine(module);
            _platingCell34Sto1EstopRestart= new SafetyToggleRoutine(module);    
            _platingCell34Sto2EstopRestart = new SafetyToggleRoutine(module);
            _res12StoEstopRestart=new SafetyToggleRoutine(module);
            _res34StoEstopRestart=new SafetyToggleRoutine(module);
            _vpwStoEstopRestart = new SafetyToggleRoutine(module);
            _srdStoEstopRestart=new SafetyToggleRoutine (module);
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manaul abort safety reset");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(SafetyResetStep.RunStop, RunStop, _delay_1ms)
                .Run(SafetyResetStep.ErrAck, () => { return _errAckToggleRoutine.Start("ErrAck") == RState.Running; },
                () => { return CheckRoutineStatus(_errAckToggleRoutine); }, _delay_1s)
                .Run(SafetyResetStep.LockCasseteDoors, () => { return _device.LockCasseteDoor(); },CheckCasseteLocked, _delay_5s)
                .Run(SafetyResetStep.LockCellDoors, LockCellDoors,CheckCellLocked, _delay_1ms)
                .Run(SafetyResetStep.LockAlignerDoors, () => { return _device.LockAlignerDoor(); },CheckAlignerLocked, _delay_1ms)
                .Run(SafetyResetStep.FacilityStoEstopRestart, () => { return _facilityStoEstopRestart.Start("FacilityStoEstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_facilityStoEstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.FacilityEstopDelay,100)//100 delay
                .Run(SafetyResetStep.PlatingCell12Sto1EstopDelay, () => { return _platingCell12Sto1EstopRestart.Start("PlatingCell12Sto1EstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_platingCell12Sto1EstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.PlatingCell12Sto1EstopDelay, 100)//100 delay
                .Run(SafetyResetStep.PlatingCell12Sto2EstopDelay, () => { return _platingCell12Sto2EstopRestart.Start("PlatingCell12Sto2EstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_platingCell12Sto2EstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.PlatingCell12Sto2EstopDelay, 100)//100 delay
                .Run(SafetyResetStep.PlatingCell34Sto1EstopDelay, () => { return _platingCell34Sto1EstopRestart.Start("PlatingCell34Sto1EstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_platingCell34Sto1EstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.PlatingCell34Sto1EstopDelay, 100)//100 delay
                .Run(SafetyResetStep.PlatingCell34Sto2EstopDelay, () => { return _platingCell34Sto2EstopRestart.Start("PlatingCell34Sto2EstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_platingCell34Sto2EstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.PlatingCell34Sto2EstopDelay, 100)//100 delay
                .Run(SafetyResetStep.Res12StoEstopDelay, () => { return _res12StoEstopRestart.Start("Res12StoEstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_res12StoEstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.Res12StoEstopDelay, 100)//100 delay
                .Run(SafetyResetStep.Res34StoEstopDelay, () => { return _res34StoEstopRestart.Start("Res34StoEstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_res34StoEstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.Res34StoEstopDelay, 100)//100 delay
                .Run(SafetyResetStep.VpwStoEstopRestart, () => { return _vpwStoEstopRestart.Start("VpwStoEstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_vpwStoEstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.VpwStoEstopDelay, 100)//100 delay
                .Run(SafetyResetStep.SrdStoEstopRestart, () => { return _srdStoEstopRestart.Start("SrdStoEstopRestart") == RState.Running; },
                () => { return CheckRoutineStatus(_srdStoEstopRestart); }, _delay_1s)
                .Delay(SafetyResetStep.SrdStoEstopRestart, 100)//100 delay
                .End(SafetyResetStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 
        /// 
        /// 
        private bool RunStop()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{RUNSTOP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// 
        /// 检验是否完成
        /// 
        /// 
        /// 
        private bool CheckRoutineStatus (IRoutine routine)
        {
            RState rsState = routine.Monitor();
            return rsState == RState.End;
        }
        /// 
        /// 检验Process door locked状态
        /// 
        /// 
        private bool CheckCasseteLocked()
        {
            return _device.SafetyData.CassetteDoorsLeftLocked&& _device.SafetyData.CassetteDoorsRightLocked;
        }
        /// 
        /// lock cell doors
        /// 
        /// 
        private bool LockCellDoors()
        {
            return _device.LockCell12Door() && _device.LockCell34Door();
        }
        /// 
        /// 检验Cell locked状态
        /// 
        /// 
        private bool CheckCellLocked()
        {
            return _device.SafetyData.Cell12DoorsLeftLocked && _device.SafetyData.Cell12DoorsRightLocked && _device.SafetyData.Cell34DoorsLeftLocked &&
                _device.SafetyData.Cell34DoorsRightLocked;
        }
        /// 
        /// 检验Aligner door locked
        /// 
        /// 
        private bool CheckAlignerLocked()
        {
            return _device.SafetyData.AlignerDoorClosed;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _device = DEVICE.GetDevice("Safety");
            return Runner.Start(Module, "Start Reset safety");
        }
    }
}