using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Utilities;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.PUF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CyberX8_RT.Modules.PUF
{
    public class PufGotoRobotForPlaceRoutine : RoutineBase, IRoutine
    {
        private enum GotoRobotStep
        {
            ChuckIn,
            WaitChuck,
            RotationFlip,
            RotationFlipWait,
            FlipGotoSide,
            FlipGotoSideWait,
            RotationGotoRobot,
            RotationWait,
            End
        }
        #region 常量
        private const string VACUUM_OFF = "VacuumOff";
        #endregion
        #region 内部变量
        /// 
        /// Side
        /// 
        private string _side = "";
        /// 
        /// Flip Axis
        /// 
        private JetAxisBase _flipAxis;
        /// 
        /// Rotation Axis
        /// 
        private JetAxisBase _rotationAxis;
        /// 
        /// Puf Vacuum
        /// 
        private PufVacuum _pufVacuum;
        /// 
        /// chuck routine
        /// 
        private PufChuckRoutine _chuckRoutine;
        /// 
        /// Flip Side
        /// 
        private string _flipSide;
        /// 
        /// 是否需要翻转
        /// 
        private bool _needFlip;
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public PufGotoRobotForPlaceRoutine(string module) : base(module)
        {
            _chuckRoutine = new PufChuckRoutine(module);
        }
        /// 
        /// 中止
        /// 
        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }
        /// 
        /// 监控
        /// 
        /// 
        public RState Monitor()
        {
            Runner.Run(GotoRobotStep.ChuckIn, () => _chuckRoutine.Start(false) == RState.Running, _delay_1ms)
                .WaitWithStopCondition(GotoRobotStep.WaitChuck, () => CommonFunction.CheckRoutineEndState(_chuckRoutine),
                    CheckChuckStopStatus)
                .Run(GotoRobotStep.RotationFlip, RotationGotoFlip,_delay_1ms)
                .WaitWithStopCondition(GotoRobotStep.RotationFlipWait,CheckRotationGotoFlipStatus,CheckRotationGotoFlipStopStatus)
                .Run(GotoRobotStep.FlipGotoSide, () => { return _flipAxis.PositionStation(_flipSide); }, _delay_1ms)
                .WaitWithStopCondition(GotoRobotStep.FlipGotoSideWait, CheckFlipPositionStatus, CheckFlipPositionRunStop)
                 .Run(GotoRobotStep.RotationGotoRobot, () => { return _rotationAxis.PositionStation("Robot"); }, _delay_1ms)
                .WaitWithStopCondition(GotoRobotStep.RotationWait, CheckRotationPositionStatus, CheckRotationPositionRunStop)
                .End(GotoRobotStep.End, NullFun, _delay_1ms);
            return Runner.Status;
        }
        /// 
        /// 检验chuck routine停止状态
        /// 
        /// 
        private bool CheckChuckStopStatus()
        {
            bool result = CommonFunction.CheckRoutineStopState(_chuckRoutine);
            if (!result)
            {
                NotifyError(eEvent.ERR_PUF, _chuckRoutine.ErrorMsg, 0);
            }
            return result;
        }
        /// 
        /// Rotation Goto Flip
        /// 
        /// 
        private bool RotationGotoFlip()
        {
            if(_needFlip)
            {
                return _rotationAxis.PositionStation("Flip");
            }
            else
            {
                return true;
            }
        }
        /// 
        /// 检验Rotation Goto Flip状态
        /// 
        /// 
        private bool CheckRotationGotoFlipStatus()
        {
            if(_needFlip)
            {
                return _rotationAxis.Status == RState.End;
            }
            else
            {
                return true;
            }
        }
        /// 
        /// 检验Rotation Goto Flip停止状态
        /// 
        /// 
        private bool CheckRotationGotoFlipStopStatus()
        {
            if(_needFlip)
            {
                return _rotationAxis.Status == RState.End;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// 检验Rotation移动状态
        /// 
        /// 
        private bool CheckRotationPositionStatus()
        {
            return _rotationAxis.Status == RState.End;
        }
        /// 
        /// 检验Rotation是否还在运动
        /// 
        /// 
        private bool CheckRotationPositionRunStop()
        {
            return _rotationAxis.Status == RState.Failed;
        }
        /// 
        /// 检验Flip移动状态
        /// 
        /// 
        private bool CheckFlipPositionStatus()
        {
            return _flipAxis.Status == RState.End;
        }
        /// 
        /// 检验Flip是否还在运动
        /// 
        /// 
        private bool CheckFlipPositionRunStop()
        {
            return _flipAxis.Status == RState.Failed;
        }
        /// 
        /// 启动
        /// 
        /// 
        /// 
        public RState Start(params object[] objs)
        {
            _side = objs[0].ToString();
            if(_side=="SideA")
            {
                _flipSide = "SideB";//Flip 运动至Side相反位置,即使用SideA,则Flip运动至SideB
            }
            else
            {
                _flipSide = "SideA";
            }
            _flipAxis = DEVICE.GetDevice($"{Module}.Flip");
            _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
            _pufVacuum = DEVICE.GetDevice($"{Module}.Vacuum");
            if(!CheckPreCondition())
            {
                return RState.Failed;
            }
            _needFlip = !_flipAxis.CheckPositionIsInStation(_flipAxis.MotionData.MotorPosition, _flipSide);
            return Runner.Start(Module, "Go to Robot");
        }
        /// 
        /// 前置条件
        /// 
        /// 
        private bool CheckPreCondition()
        {
            if(!_flipAxis.IsHomed)
            {
                LOG.WriteLog(eEvent.ERR_PUF, Module, "Flip Axis is not homed");
                return false;
            }
            if (!_rotationAxis.IsHomed)
            {
                LOG.WriteLog(eEvent.ERR_PUF, Module, "Rotation Axis is not homed");
                return false;
            }
            if (_side == "SideA")
            {
                if(_pufVacuum.ChuckAVacuumStatus!=VACUUM_OFF)
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, "Side A is not Vacuum off");
                    return false;
                }
            }
            else if(_side=="SideB")
            {
                if (_pufVacuum.ChuckBVacuumStatus != VACUUM_OFF)
                {
                    LOG.WriteLog(eEvent.ERR_PUF, Module, "Side B is not Vacuum off");
                    return false;
                }
            }
            if(!_rotationAxis.CheckGotoPosition("Robot"))
            {
                return false;
            }
            return true;
        }
    }
}