using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.Facilities;
using CyberX8_RT.Devices.SRD;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.SubstrateTrackings;
using Aitex.Core.Common;
namespace CyberX8_RT.Modules.SRD
{
    public class SRDLoaderRoutine : RoutineBase, IRoutine
    {
        private enum SRDLoaderStep 
        {
            Loader_LiftUpOff,
            Loader_FlippersIn,
            Loader_N2On,
            Loader_Delay,
            Loader_N2Off,
            Loader_ChuckVacuumOn,
            Loader_FlippersOut,
            End
        }
        #region 常量 
        #endregion
        #region 内部变量
        /// 
        /// Rotation Axis
        /// 
        private JetAxisBase _rotationAxis;
        /// 
        /// SRD Common
        /// 
        private SrdCommonDevice _srdCommon;
        /// 
        /// Total SRD
        /// 
        private TotalSRDDevice _totalSRDDevice;
        /// 
        /// System Facility
        /// 
        private SystemFacilities _systemFacilities;
        /// 
        /// 当前WaferSize
        /// 
        private int _waferSize = 200;
        #endregion
        #region 属性
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public SRDLoaderRoutine(string module) : base(module)
        {
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("SRD Loader Abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(SRDLoaderStep.Loader_LiftUpOff, LiftUpOff, CheckLiftUpOffEndStatus, CheckLiftUpOffStopStatus)
                .Run(SRDLoaderStep.Loader_FlippersIn, FlippersIn, CheckFlippersInEndStatus, CheckFlippersInStopStatus)
                .Run(SRDLoaderStep.Loader_N2On, N2On, _delay_1ms)
                .Delay(SRDLoaderStep.Loader_Delay, 500)
                .Run(SRDLoaderStep.Loader_N2Off, N2Off, _delay_1ms)
                .Run(SRDLoaderStep.Loader_ChuckVacuumOn, ChuckVacuumOn, CheckChuckVacuumOnEndStatus, CheckChuckVacuumOnStopStatus)
                .Run(SRDLoaderStep.Loader_FlippersOut, FlippersOut, CheckFlippersOutEndStatus, CheckFlippersOutStopStatus)
                .End(SRDLoaderStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _srdCommon = DEVICE.GetDevice($"{Module}.Common");
            _totalSRDDevice = DEVICE.GetDevice("SRD");
            _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            _systemFacilities = DEVICE.GetDevice("System.Facilities");
            if (!GetWaferSize())
            {
                NotifyError(eEvent.ERR_SRD, "Wafer Size is invalid", 0);
                return RState.Failed;
            }
            if (!CheckPreCondition())
            {
                return RState.Failed;
            }
            return Runner.Start(Module, "SRD Loader Start");
        }
        /// 
        /// Check Pre Condition
        /// 
        /// 
        private bool CheckPreCondition()
        {
            //Check Rotation Home
            if (!_rotationAxis.IsHomed)
            {
                NotifyError(eEvent.ERR_SRD, "Rotation is not homed", 0);
                return false;
            }
            //Check Vacuum off
            if (!_srdCommon.CommonData.ChuckVacuum)
            {
                NotifyError(eEvent.ERR_SRD, "Chuck Vacuum is on", 0);
                return false;
            }
            //Check LiftUp
            if (!_srdCommon.CommonData.LiftUp)
            {
                NotifyError(eEvent.ERR_SRD, "LiftUp is off", 0);
                return false;
            }
            //Check LiftUp Status
            if (!_srdCommon.CommonData.LiftUpStatus)
            {
                NotifyError(eEvent.ERR_SRD, "LiftUp sensor is off", 0);
                return false;
            }
            //Check Wafer Present
            if (!_srdCommon.CommonData.WaferPresent)
            {
                NotifyError(eEvent.ERR_SRD, "WaferPresent sensor is off", 0);
                return false;
            }
            //Check LoaderDI
            if (!_systemFacilities.LoaderDiEnable)
            {
                NotifyError(eEvent.ERR_SRD, "Load DI Is Disable", 0);
                return false;
            }
            //Check Flippers
            if (_srdCommon.CommonData.FlippersIn150 || _srdCommon.CommonData.FlippersIn200)
            {
                NotifyError(eEvent.ERR_SRD, "FlippersIn is on", 0);
                return false;
            }
            if (!_srdCommon.CommonData.Flipper1Out150Status || !_srdCommon.CommonData.Flipper2Out150Status || !_srdCommon.CommonData.Flipper3Out150Status
                || !_srdCommon.CommonData.Flipper1Out200Status || !_srdCommon.CommonData.Flipper2Out200Status || !_srdCommon.CommonData.Flipper3Out200Status)
            {
                NotifyError(eEvent.ERR_SRD, "Flippers are at In position", 0);
                return false;
            }
           
            return true;
        }
        /// 
        /// Get current WaferSize
        /// 
        /// 
        private bool GetWaferSize()
        {
            WaferInfo waferInfo = WaferManager.Instance.GetWafer(ModuleNameString.ToEnum(Module), 0);
            if (waferInfo == null)
            {
                return false;
            }
            switch (waferInfo.Size)
            {
               
                case WaferSize.WS4:
                    _waferSize = 100;
                    break;
                case WaferSize.WS6:
                case WaferSize.WS150:
                case WaferSize.WS159:
                    _waferSize = 150;
                    break;
                case WaferSize.WS0:
                case WaferSize.WS8:
                    _waferSize = 200;
                    break;
                default:
                    return false;
            }
            return true;
        }
        /// 
        /// LiftUpOff
        /// 
        /// 
        /// 
        private bool LiftUpOff()
        {
            bool result = _srdCommon.LiftUpOffAction("", null);
            if (!result)
            {
                NotifyError(eEvent.ERR_SRD, "Lift Up Off Action is failed", 0);
                return result;
            }           
            return true;
        }
        /// 
        /// 检验LiftUpOff结束状态
        /// 
        /// 
        /// 
        private bool CheckLiftUpOffEndStatus()
        {
            return _srdCommon.Status == RState.End && !_srdCommon.CommonData.LiftUpStatus;
        }
        /// 
        /// 检验LiftUpOff结束状态
        /// 
        /// 
        /// 
        private bool CheckLiftUpOffStopStatus()
        {
            if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
            {
                NotifyError(eEvent.ERR_SRD, "Check LiftUpOff is failed", 0);
                return true;
            }
            return false;
        }
        /// 
        /// Flippers In
        /// 
        /// 
        /// 
        private bool FlippersIn()
        {
            bool result = false;
            object[] objects = new object[1];
            objects[0] = _waferSize;
            result = _srdCommon.FlipperInAction("", objects);
            if (!result)
            {
                NotifyError(eEvent.ERR_SRD, $"FlipperIn{_waferSize} Action is failed", 0);
                return result;
            }
            
            return true;
        }
        /// 
        /// 检验FlippersIn结束状态
        /// 
        /// 
        /// 
        private bool CheckFlippersInEndStatus()
        {
            return _srdCommon.Status == RState.End;
        }
        /// 
        /// 检验FlippersIn结束状态
        /// 
        /// 
        /// 
        private bool CheckFlippersInStopStatus()
        {
            if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
            {
                NotifyError(eEvent.ERR_SRD, $"Check FlipperIn{_waferSize} Action is failed", 0);
                return true;
            }
            return false;
        }
        /// 
        /// 打开 Wafer N2
        /// 
        /// 
        private bool N2On()
        {
            bool result = _srdCommon.N2OnAction("", null);
            if (!result)
            {
                NotifyError(eEvent.ERR_SRD, $"N2 On Action is failed", 0);
            }
            return result;
        }
        /// 
        /// 关闭 Wafer N2
        /// 
        /// 
        private bool N2Off()
        {
            bool result = _srdCommon.N2OffAction("", null);
            if (!result)
            {
                NotifyError(eEvent.ERR_SRD, $"N2 Off Action is failed", 0);
            }
            return result;
        }
        /// 
        /// ChuckVacuumOn
        /// 
        /// 
        /// 
        private bool ChuckVacuumOn()
        {
            bool result = _srdCommon.ChuckVacuumOnAction("", null);
            if (!result)
            {
                NotifyError(eEvent.ERR_SRD, "ChuckVacuumOn Action is failed", 0);
                return result;
            }
            return true;
        }
        /// 
        /// 检验ChuckVacuumOn结束状态
        /// 
        /// 
        /// 
        private bool CheckChuckVacuumOnEndStatus()
        {
            return _srdCommon.Status == RState.End && !_srdCommon.CommonData.ChuckVacuum;
        }
        /// 
        /// 检验ChuckVacuumOn结束状态
        /// 
        /// 
        /// 
        private bool CheckChuckVacuumOnStopStatus()
        {
            if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
            {
                NotifyError(eEvent.ERR_SRD, "Check ChuckVacuumOn is failed", 0);
                return true;
            }
            return false;
        }
        /// 
        /// Flippers Out
        /// 
        /// 
        /// 
        private bool FlippersOut()
        {
            bool result = false;
            object[] objects = new object[1];
            objects[0] = _waferSize;
            result = _srdCommon.FlipperOutAction("", objects);
            if (!result)
            {
                NotifyError(eEvent.ERR_SRD, $"FlipperOut{_waferSize} Action is failed", 0);
                return result;
            }
            return true;
        }
        /// 
        /// 检验FlippersOut结束状态
        /// 
        /// 
        /// 
        private bool CheckFlippersOutEndStatus()
        {
            return _srdCommon.Status == RState.End;
        }
        /// 
        /// 检验FlippersOut结束状态
        /// 
        /// 
        /// 
        private bool CheckFlippersOutStopStatus()
        {
            if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
            {
                NotifyError(eEvent.ERR_SRD, $"Check FlipperOut{_waferSize} Action is failed", 0);
                return true;
            }
            return false;
        }
    }
}