using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Sorter.Common;
using CyberX8_Core;
using CyberX8_RT.Devices.EFEM;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.SubstrateTrackings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CyberX8_RT.Modules.EFEM
{
    public class EfemRobotMapRoutine : RoutineBase, IRoutine
    {
        enum RoutineStep
        {
            GotoMapWaitIdle,
            GotoMap,
            WaitEFEMIdle,
            Map,
            RequestMapWaitIdle,
            RequestMap,
            BackWaitIdle,
            Back,
            End,
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="efem"></param>
        public EfemRobotMapRoutine(EfemBase efem):base(ModuleName.EfemRobot.ToString())
        {
            _efem = efem;
        }

        #region 内部变量
        private int _timeout = 0;
        private ModuleName _module = ModuleName.EfemRobot;
        private EfemBase _efem;
        #endregion
        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="objs"></param>
        /// <returns></returns>
        public RState Start(params object[] objs)
        {
            Reset();

            _module=(ModuleName)objs[0];

            _timeout = SC.GetValue<int>("EFEM.LoadPort.MotionTimeout");

            return Runner.Start(Module, $"Start Map {_module}");
        }

        public RState Monitor()
        {
            Runner.Wait(RoutineStep.GotoMapWaitIdle, WaitModuleReady)
            .Run(RoutineStep.GotoMap, GotoMap, CheckStepDone, _timeout * 1000)
            .Wait(RoutineStep.WaitEFEMIdle, WaitModuleReady)
            .Run(RoutineStep.Map, Map, CheckStepDone, _timeout * 1000)
            .Wait(RoutineStep.RequestMapWaitIdle, WaitModuleReady)
            .Run(RoutineStep.RequestMap, RequestMap, CheckStepDone, _timeout * 1000)
            .Wait(RoutineStep.BackWaitIdle, WaitModuleReady)
            .Run(RoutineStep.Back, Back, CheckStepDone, _timeout * 1000)
            .End(RoutineStep.End, NullFun, _delay_1s);

            return Runner.Status;
        }
        private bool GotoMap()
        {
            return _efem.GotoMap(_module, Hand.Blade1);
        }
        private bool Map()
        {
            return _efem.Map(_module);
        }

        private bool Back()
        {
            return _efem.GotoMap(_module, Hand.Blade1, "RE");
        }

        private bool RequestMap()
        {
            return _efem.RequestMapResult(_module);
        }

        private bool WaitModuleReady()
        {
            return _efem.Status == RState.End;
        }

        private bool CheckStepDone()
        {
            if (_efem.Status == RState.End)
            {
                return true;
            }
            else if (_efem.Status == RState.Failed)
            {
                NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot picking failed: {_efem.Status}", -1);
                return true;
            }

            return false;
        }
        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }
    }
}