using Aitex.Core.Common;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.RecipeCenter;
using Aitex.Core.Util;
using Aitex.Core.Utilities;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.SubstrateTrackings;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.SRD;
using CyberX8_RT.Modules.Transporter;
using System;
using MECF.Framework.Common.Persistent.SRD;
using MECF.Framework.Common.ToolLayout;
using CyberX8_RT.Modules.Dryer;
using MECF.Framework.Common.Alarm;
using MECF.Framework.Common.CommonData;
using CyberX8_RT.Modules.Loader;
namespace CyberX8_RT.Modules.SRD
{
    public class SRDEntity : Entity, IEntity, IModuleEntity
    {
        #region 常量
        private const string AUTO = "Auto";
        private const string MANUAL = "Manual";
        private const string DISABLED = "Disabled";
        private const string ENGINEERING = "Engineering";
        private const string PRODUCTION = "Production";
        #endregion
        #region 内部变量
        /// 
        /// 是否Homed
        /// 
        private bool _isHomed;
        /// 
        /// rotation电机
        /// 
        private JetAxisBase _rotationAxis;
        /// 
        /// arm电机 
        /// 
        private JetAxisBase _armAxis;
        /// 
        /// IsPresenceTesting
        /// 
        private bool _isPresenceTesting = false;
        /// 
        /// IsAWCCycling
        /// 
        private bool _isAWCCycling = false;
        /// 
        /// 当前Recipe
        /// 
        private SrdRecipe _currentRecipe = null;
        /// 
        /// 持久化对象
        /// 
        private SRDPersistentValue _persistentValue;
        /// 
        /// run recipe start time
        /// 
        private DateTime _runRecipeStartTime;
        /// 
        ///  run recipe complete time
        /// 
        private DateTime _runRecipeCompleteTime;
        /// 
        /// Wafer已Loader完
        /// 
        private bool _isLoaded = false;
        #endregion
        #region Routine
        /// 
        /// SRD Home
        /// 
        private SRDHomeRoutine _homeRoutine;
        /// 
        /// SRD初始化Home Routine
        /// 
        private SRDInitializeHomeRoutine _initializeHomeRoutine;
        /// 
        /// SRD SwicthOn
        /// 
        private SRDSwitchOnRoutine _switchOnRoutine;
        /// 
        /// SRD SwicthOff
        /// 
        private SRDSwitchOffRoutine _switchOffRoutine;
        /// 
        /// SRD Initialize
        /// 
        private SRDInitializeRoutine _initializeRoutine;
        /// 
        /// SRD Common Device
        /// 
        private SrdCommonDevice _srdCommon;
        /// 
        /// SRD GoToPosition
        /// 
        private SRDPositionRoutine _positionRoutine;
        /// 
        /// SRD StartRotation
        /// 
        private SRDRotationRoutine _rotationRoutine;
        /// 
        /// SRD PresenceTest
        /// 
        private SRDPresenceTestRoutine _presenceTestRoutine;
        /// 
        /// SRD ProcessRecipe
        /// 
        private SRDProcessRecipeRoutine _processRecipeRoutine;
        /// 
        /// SRD AWC Cycle
        /// 
        private SRDAWCCycleRoutine _awcCycleRoutine;
        /// 
        /// SRD Process Error
        /// 
        private SRDProcessErrorRoutine _processErrorRoutine;
        /// 
        /// SRD Loader Routine
        /// 
        private SRDLoaderRoutine _loaderRoutine;
        /// 
        /// SRD Unloader Routine
        /// 
        private SRDUnloaderRoutine _unloaderRoutine;
        /// 
        /// RecipeCycle
        /// 
        private int _cycle = 0;
        /// 
        /// recipe时长
        /// 
        private int _recipeTime;
        #endregion
        #region 属性
        /// 
        /// 模块名称
        /// 
        public ModuleName Module { get; private set; }
        /// 
        /// 初始化状态
        /// 
        public bool IsInit
        {
            get { return fsm.State == (int)SRDState.Init; }
        }
        /// 
        /// 空闲状态
        /// 
        public bool IsIdle
        {
            get
            {
                return fsm.State == (int)SRDState.Idle;
            }
        }
        /// 
        /// 当前状态机状态
        /// 
        public int State { get { return fsm.State; } }
        /// 
        /// 是否发生错误
        /// 
        public bool IsError
        {
            get { return fsm.State == (int)SRDState.Error; }
        }
        /// 
        /// 是否正在作业
        /// 
        public bool IsBusy
        {
            get { return !IsInit && !IsError && !IsIdle; }
        }
        /// 
        /// 是否已Home
        /// 
        public bool IsHomed
        {
            get { return _isHomed; }
        }
        /// 
        /// 是否正在用水
        /// 
        public bool IsUsingWater
        {
            get { return _processRecipeRoutine.IsUsingWater; }
        }
        /// 
        /// SRD门是否关闭
        /// 
        public bool IsSrdDoorClosed
        {
            get { return !_srdCommon.CommonData.DoorOpened && _srdCommon.CommonData.DoorClosed; }
        }
        /// 
        /// SRD真空是否开启
        /// 
        public bool IsSrdChuckVacuum
        {
            get { return _srdCommon.CommonData.ChuckVacuum; }
        }
        /// 
        /// 是否禁用
        /// 
        public bool IsDisable { get { return _persistentValue == null || _persistentValue.OperatingMode == DISABLED; } }
        /// 
        /// 自动模式
        /// 
        public bool IsAuto { get { return _persistentValue != null && _persistentValue.OperatingMode == AUTO; } }
        /// 
        /// 自动模式
        /// 
        public bool IsManual { get { return _persistentValue != null && _persistentValue.OperatingMode == MANUAL; } }
        /// 
        /// Arm是否SwitchOn
        /// 
        public bool IsArmSwitchOn
        {
            get { return _armAxis.IsSwitchOn; }
        }
        /// 
        /// Rotation是否SwitchOn
        /// 
        public bool IsRotationSwitchOn
        {
            get { return _rotationAxis.IsSwitchOn; }
        }
        /// 
        /// 已完成的RunRecipeCycle次数
        ///        
        public int AchievedCycle { get { return _processRecipeRoutine.AchievedCycle; } }
        /// 
        /// PresenceTest状态
        /// 
        public bool IsPresenceTesting
        {
            get { return _isPresenceTesting; }
        }
        /// 
        /// AWCCycle状态
        /// 
        public bool IsAWCCycling
        {
            get { return _isAWCCycling; }
        }
        /// 
        /// 当前状态机
        /// 
        public string CurrentStateMachine
        {
            get { return GetCurrentStateMachine(); }
        }
        /// 
        /// 是否为工程模式
        /// 
        public bool IsEngineering { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == ENGINEERING; } }
        /// 
        /// 是否为产品模式
        /// 
        public bool IsProduction { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == PRODUCTION; } }
        /// 
        /// Wafer已Loader完
        /// 
        public bool IsLoaded
        {
            get { return _isLoaded; }
        }
        
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public SRDEntity(ModuleName module)
        {
            this.Module = module;
            _armAxis = DEVICE.GetDevice($"{module}.Arm");
            _rotationAxis = DEVICE.GetDevice($"{module}.Rotation");
            WaferManager.Instance.SubscribeLocation(Module, 1);
            InitialFsm();
        }
        /// 
        /// 总初始化
        /// 
        /// 
        protected override bool Init()
        {
            _srdCommon = DEVICE.GetDevice($"{Module}.Common");
            InitializeParameter();
            InitialDATA();
            InitialRoutine();
            InitialOperation();
            return true;
        }
        /// 
        /// 初始化参数
        /// 
        private void InitializeParameter()
        {
            _persistentValue = SRDPersistentManager.Instance.GetModulePersistentValue(Module.ToString());
            if (_persistentValue == null)
            {
                LOG.WriteLog(eEvent.ERR_SRD, Module.ToString(), "Persistent Value Object is not exist");
            }
        }
        /// 
        /// 初始化数据
        /// 
        private void InitialDATA()
        {
            DATA.Subscribe($"{Module}.FsmState", () => ((SRDState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.IsHomed", () => _isHomed, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.IsError", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.SrdDoorClosed", () => IsSrdDoorClosed, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.AchievedCycle", () => AchievedCycle, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.IsPresenceTesting", () => IsPresenceTesting, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.CurrentStateMachine", () => CurrentStateMachine, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.IsAWCCycling", () => IsAWCCycling, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.CurrentRecipe", () => _currentRecipe != null ? _currentRecipe.Ppid : "", SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.TotalTime", () => _recipeTime, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.TimeRemain", () => CalculateTimeRemain(), SubscriptionAttribute.FLAG.IgnoreSaveDB); 
            DATA.Subscribe($"{Module}.OperatingMode", () => _persistentValue != null ? _persistentValue.OperatingMode : "None", SubscriptionAttribute.FLAG.IgnoreSaveDB);
        }
        /// 
        /// 初始化状态机
        /// 
        private void InitialFsm()
        {
            fsm = new StateMachine(Module.ToString(), (int)SRDState.Init, 20);
            fsm.EnableRepeatedMsg(true);
            AnyStateTransition(SRDMSG.Error, EnterError, SRDState.Error);
            Transition(SRDState.Error, SRDMSG.ResumeError, (param) => { return true; }, SRDState.Init);
            //Initialized
            AnyStateTransition(SRDMSG.Initialize, InitializeAll, SRDState.Initializing);
            Transition(SRDState.Initializing, FSM_MSG.TIMER, InitializeAllTimeout, SRDState.Initialized);
            //SwitchOn
            Transition(SRDState.Init, SRDMSG.SwitchOn, SwitchOnAll, SRDState.SwitchOning);
            Transition(SRDState.Idle, SRDMSG.SwitchOn, SwitchOnAll, SRDState.SwitchOning);
            Transition(SRDState.Error, SRDMSG.SwitchOn, SwitchOnAll, SRDState.SwitchOning);
            Transition(SRDState.Initialized, SRDMSG.SwitchOn, SwitchOnAll, SRDState.SwitchOning);
            Transition(SRDState.SwitchOning, FSM_MSG.TIMER, SwitchOnTimeout, SRDState.Init);
            //SwitchOff
            Transition(SRDState.Init, SRDMSG.SwitchOff, SwitchOffAll, SRDState.SwitchOffing);
            Transition(SRDState.Idle, SRDMSG.SwitchOff, SwitchOffAll, SRDState.SwitchOffing);
            Transition(SRDState.Error, SRDMSG.SwitchOff, SwitchOffAll, SRDState.SwitchOffing);
            Transition(SRDState.Initialized, SRDMSG.SwitchOff, SwitchOffAll, SRDState.SwitchOffing);
            Transition(SRDState.SwitchOffing, FSM_MSG.TIMER, SwitchOffTimeout, SRDState.Init);
            // Home
            Transition(SRDState.Init, SRDMSG.HomeAll, HomeAll, SRDState.Homing);
            Transition(SRDState.Initialized, SRDMSG.HomeAll, HomeAll, SRDState.Homing);
            Transition(SRDState.Error, SRDMSG.HomeAll, HomeAll, SRDState.Homing);
            Transition(SRDState.Idle, SRDMSG.HomeAll, HomeAll, SRDState.Homing);
            Transition(SRDState.Abort, SRDMSG.HomeAll, HomeAll, SRDState.Homing);
            Transition(SRDState.Homing, FSM_MSG.TIMER, HomingTimeout, SRDState.Idle);
            //Initialize Home
            Transition(SRDState.Init, SRDMSG.InitializeHome, InitializeHome, SRDState.InitializeHoming);
            Transition(SRDState.Error, SRDMSG.InitializeHome, InitializeHome, SRDState.InitializeHoming);
            Transition(SRDState.InitializeHoming, FSM_MSG.TIMER, InitializeHomeTimeout, SRDState.Idle);
            Transition(SRDState.Abort, SRDMSG.InitializeHome, InitializeHome, SRDState.InitializeHoming);
            Transition(SRDState.Idle, SRDMSG.InitializeHome, InitializeHome, SRDState.InitializeHoming);
            //Process Recipe 
            Transition(SRDState.Idle, SRDMSG.ProcessRecipe, ProcessRecipe, SRDState.ProcessReciping);
            Transition(SRDState.ProcessReciping, FSM_MSG.TIMER, ProcessRecipeTimeout, SRDState.Idle);
            Transition(SRDState.ProcessReciping, SRDMSG.ProcessError, ProcessError, SRDState.ProcessError);
            Transition(SRDState.ProcessError, FSM_MSG.TIMER, ProcessErrorMonitor, SRDState.Error);
            //GoToSavedPosition
            Transition(SRDState.Idle, SRDMSG.GoToSavedPosition, GotoPosition, SRDState.Positioning);
            Transition(SRDState.Positioning, FSM_MSG.TIMER, GotoPositionTimeout, SRDState.Idle);
            //StartRotation
            Transition(SRDState.Idle, SRDMSG.StartRotation, StartRotation, SRDState.Rotating);
            Transition(SRDState.Rotating, FSM_MSG.TIMER, RotationTimeout, SRDState.Idle);
            //StopRotation
            Transition(SRDState.Rotating, SRDMSG.StopRotation, StopRotation, SRDState.Stopping);
            Transition(SRDState.Stopping, FSM_MSG.TIMER, StopRotationTimeout, SRDState.Idle);
            //Abort
            Transition(SRDState.ProcessReciping, SRDMSG.Abort, AbortProcessRecipe, SRDState.Abort);
            Transition(SRDState.PresenceTesting, SRDMSG.Abort, AbortPresenceTest, SRDState.Abort);
            Transition(SRDState.AWCCycling, SRDMSG.Abort, AbortAWCCycle, SRDState.Abort);
            Transition(SRDState.ProcessError, SRDMSG.Abort, AbortProcessError, SRDState.Abort);
            //PresenceTestStart
            Transition(SRDState.Idle, SRDMSG.PresenceTestStart, PresenceTest, SRDState.PresenceTesting);
            Transition(SRDState.PresenceTesting, FSM_MSG.TIMER, PresenceTestTimeout, SRDState.Idle);
            //AWC Cycle
            Transition(SRDState.Idle, SRDMSG.AWCCycleStart, AWCCycle, SRDState.AWCCycling);
            Transition(SRDState.AWCCycling, FSM_MSG.TIMER, AWCCycleTimeout, SRDState.Idle);
            Transition(SRDState.AWCCycling, SRDMSG.HomeAll, HomeAll, SRDState.AWCHoming);
            Transition(SRDState.AWCHoming, FSM_MSG.TIMER, HomingTimeout, SRDState.AWCCycling);
            //Retry
            Transition(SRDState.Error, SRDMSG.Retry, NullFunc, SRDState.Retrying);
            Transition(SRDState.Retrying, FSM_MSG.TIMER, SRDRetry, SRDState.Retrying);
            Transition(SRDState.Retrying, SRDMSG.ProcessRecipe, RetryRunRecipe, SRDState.ProcessReciping);
            //ConfirmComplete
            Transition(SRDState.Init, SRDMSG.ConfirmComplete, ClearModuleAlarm, SRDState.Init);
            Transition(SRDState.Idle, SRDMSG.ConfirmComplete, ClearModuleAlarm, SRDState.Idle);
            Transition(SRDState.Error, SRDMSG.ConfirmComplete, NullFunc, SRDState.ConfirmCompleting);
            Transition(SRDState.ConfirmCompleting, FSM_MSG.TIMER, ConfirmComplete, SRDState.ConfirmCompleting);
            Transition(SRDState.ConfirmCompleting, SRDMSG.ProcessRecipe, ConfirmProcessRecipe, SRDState.Idle);
            //Enter Init
            Transition(SRDState.Idle, SRDMSG.Init, NullFunc, SRDState.Init);
            //Loader 
            Transition(SRDState.Idle, SRDMSG.Loader, LoaderWafer, SRDState.Loading);
            Transition(SRDState.Loading, FSM_MSG.TIMER, LoaderWaferMonitor, SRDState.Idle);
            //UnLoader 
            Transition(SRDState.Idle, SRDMSG.Unloader, UnloaderWafer, SRDState.Unloading);
            Transition(SRDState.Unloading, FSM_MSG.TIMER, UnloaderWaferMonitor, SRDState.Idle);
            EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
            EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
        }
        /// 
        /// 初始化Routine
        /// 
        private void InitialRoutine()
        {
            _initializeHomeRoutine = new SRDInitializeHomeRoutine(Module.ToString());
            _homeRoutine = new SRDHomeRoutine(Module.ToString());
            _switchOnRoutine = new SRDSwitchOnRoutine(Module.ToString());
            _switchOffRoutine = new SRDSwitchOffRoutine(Module.ToString());
            _initializeRoutine = new SRDInitializeRoutine(Module.ToString());
            _positionRoutine = new SRDPositionRoutine(Module);
            _rotationRoutine = new SRDRotationRoutine(Module, _rotationAxis);
            _presenceTestRoutine = new SRDPresenceTestRoutine(Module.ToString());
            _processRecipeRoutine = new SRDProcessRecipeRoutine(Module.ToString(), _rotationAxis, _armAxis, _srdCommon);
            _awcCycleRoutine = new SRDAWCCycleRoutine(Module);
            _processErrorRoutine=new SRDProcessErrorRoutine(Module.ToString());
            _loaderRoutine = new SRDLoaderRoutine(Module.ToString());
            _unloaderRoutine = new SRDUnloaderRoutine(Module.ToString());
        }
        /// 
        /// 初始化操作
        /// 
        private void InitialOperation()
        {
            OP.Subscribe($"{Module}.HomeAll", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.HomeAll); });
            OP.Subscribe($"{Module}.InitializeHome", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.InitializeHome); });
            OP.Subscribe($"{Module}.SwitchOnAll", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.SwitchOn); });
            OP.Subscribe($"{Module}.SwitchOffAll", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.SwitchOff); });
            OP.Subscribe($"{Module}.CycleManualProcessRecipe", (cmd, args) => 
            {
                SrdRecipe recipe = RecipeFileManager.Instance.LoadGenericityRecipe(args[0].ToString());
                if (recipe == null)
                {
                    LOG.WriteLog(eEvent.ERR_SRD, Module.ToString(), $"{args[0]} recipe is null");
                    return false;
                }
                object[] objects = new object[args.Length];
                objects[0] = recipe;
                for (int i = 1; i < args.Length; i++)
                {
                    objects[i] = args[i];
                }
                return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.ProcessRecipe, objects); 
            });
            //OP.Subscribe($"{Module}.Arm.GotoSavedPosition", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.GoToSavedPosition, "Arm", args); });
            //OP.Subscribe($"{Module}.Rotation.GotoSavedPosition", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.GoToSavedPosition, "Rotation", args); });
            OP.Subscribe($"{Module}.Abort", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.Abort); });
            OP.Subscribe($"{Module}.StartRotation", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.StartRotation, "Rotation", args); });
            OP.Subscribe($"{Module}.StopRotation", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.StopRotation); });
            OP.Subscribe($"{Module}.PresenceTestStart", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.PresenceTestStart, args); });
            OP.Subscribe($"{Module}.AWCCycle", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.AWCCycleStart, args); });
            OP.Subscribe($"{Module}.Loader", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.Loader); });
            OP.Subscribe($"{Module}.Unloader", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.Unloader); });
        }
        /// 
        /// Enter Init
        /// 
        public void EnterInit()
        {
            if ((SRDState)fsm.State != SRDState.Idle) return;
            else
            {
                CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.Init);
            }
        }
        /// 
        /// 进入Error状态
        /// 
        /// 
        /// 
        private bool EnterError(object[] param)
        {
            _isHomed = false;
            return true;
        }
        #region Initialized
        /// 
        /// Initialize
        /// 
        /// 
        /// 
        private bool InitializeAll(object[] param)
        {
            if (fsm.State == (int)MetalState.Initializing)
            {
                LOG.WriteLog(eEvent.WARN_SRD, Module.ToString(), "state is Initializing,cannot do initialize");
                return false;
            }
            return _initializeRoutine.Start() == RState.Running;
        }
        /// 
        /// Initialize 监控
        /// 
        /// 
        /// 
        private bool InitializeAllTimeout(object[] param)
        {
            RState ret = _initializeRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                PostMsg(SRDMSG.Error);
                return false;
            }
            bool result = ret == RState.End;
            if (result)
            {
                _isHomed = false;
            }
            return result;
        }
        #endregion
        #region Switch On
        /// 
        /// SwitchAll
        /// 
        /// 
        /// 
        private bool SwitchOnAll(object[] param)
        {
            return _switchOnRoutine.Start() == RState.Running;
        }
        private bool SwitchOnTimeout(object[] param)
        {
            RState ret = _switchOnRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                PostMsg(SRDMSG.Error);
                return false;
            }
            bool result = ret == RState.End;
            if (result)
            {
                _isHomed = false;
            }
            return result;
        }
        #endregion
        #region Switch Off
        /// 
        /// SwitchAll
        /// 
        /// 
        /// 
        private bool SwitchOffAll(object[] param)
        {
            return _switchOffRoutine.Start() == RState.Running;
        }
        private bool SwitchOffTimeout(object[] param)
        {
            RState ret = _switchOffRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                PostMsg(SRDMSG.Error);
                return false;
            }
            bool result = ret == RState.End;
            if (result)
            {
                _isHomed = false;
            }
            return result;
        }
        #endregion
        #region Home
        /// 
        /// HomeAll
        /// 
        /// 
        /// 
        private bool HomeAll(object[] param)
        {
            _isHomed = false;
            return _homeRoutine.Start() == RState.Running;
        }
        /// 
        /// Home超时
        /// 
        /// 
        /// 
        private bool HomingTimeout(object[] param)
        {
            RState ret = _homeRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                PostMsg(SRDMSG.Error);
                return false;
            }
            bool result = ret == RState.End;
            if (result)
            {
                _isHomed = true;
            }
            return result;
        }
        #endregion        
        #region Process Recipe
        /// 
        /// ProcessRecipe
        /// 
        /// 
        /// 
        private bool ProcessRecipe(object[] param)
        {
            SrdRecipe recipe= param[0] as SrdRecipe;
            if(param.Length >= 2) _cycle = (int)param[1];
            bool result = _processRecipeRoutine.Start(param) == RState.Running;
            if (result)
            {
                if (CellItemRecipeTimeManager.Instance.ContainRecipe(recipe.Ppid))
                {
                    _recipeTime = _cycle * CellItemRecipeTimeManager.Instance.GetRecipeTotalTime(recipe.Ppid);
                }
                else
                {
                    _recipeTime = 0;
                }
                _currentRecipe = recipe;
                _runRecipeStartTime = DateTime.Now;
                FaModuleNotifier.Instance.NotifySRDRecipeStart(Module, recipe.Ppid);
            }
            return result;
        }
        /// 
        /// ProcessRecipe超时
        /// 
        /// 
        /// 
        private bool ProcessRecipeTimeout(object[] param)
        {
            RState ret = _processRecipeRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                PostMsg(SRDMSG.ProcessError);
                //记录LotTrack
                _runRecipeCompleteTime = DateTime.Now;
                _processRecipeRoutine.SRDLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2");
                SRDLotTrackUtil.ExportSRDLotTrack(Module.ToString(), _processRecipeRoutine.SRDLotTrackDatas,
                    _processRecipeRoutine.SRDLotTrackHeaderDatas, IsAuto);
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmList alarmList = new AlarmList(Module.ToString(), ((SRDState)fsm.State).ToString(), (int)SRDMSG.ProcessRecipe,
                        _processRecipeRoutine.ErrorMsg, _processRecipeRoutine.ErrorStep, (int)AlarmType.Error);
                    AlarmListManager.Instance.AddAlarm(alarmList);
                }
                if (_currentRecipe != null)
                {
                    FaModuleNotifier.Instance.NotifySRDRecipeFailed(Module, _currentRecipe.Ppid);
                }
                return false;
            }
            bool result = ret == RState.End;
            if (result)
            {
                double elapsedMilliseconds = _processRecipeRoutine.ElapsedMilliseconds;
                int recipeTime = (int)Math.Floor(elapsedMilliseconds / _cycle / 1000);
                CellItemRecipeTimeManager.Instance.UpdateRecipeTime(_currentRecipe.Ppid, recipeTime);
                //记录LotTrack
                _runRecipeCompleteTime = DateTime.Now;
                _processRecipeRoutine.SRDLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2");
                SRDLotTrackUtil.ExportSRDLotTrack(Module.ToString(), _processRecipeRoutine.SRDLotTrackDatas,
                    _processRecipeRoutine.SRDLotTrackHeaderDatas, IsAuto);
                if (_currentRecipe != null)
                {
                    FaModuleNotifier.Instance.NotifySRDRecipeEnd(Module, _currentRecipe.Ppid);
                }
                _currentRecipe = null;
                AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), SRDState.ProcessReciping.ToString());
            }
            return result;
        }
        /// 
        /// Abort Recipe
        /// 
        /// 
        /// 
        private bool AbortProcessRecipe(object[] param)
        {
            _processRecipeRoutine.Abort();
            //记录LotTrack
            _runRecipeCompleteTime = DateTime.Now;
            _processRecipeRoutine.SRDLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2");
            SRDLotTrackUtil.ExportSRDLotTrack(Module.ToString(), _processRecipeRoutine.SRDLotTrackDatas,
                _processRecipeRoutine.SRDLotTrackHeaderDatas, IsAuto);
            return true;
        }
        /// 
        /// 计算剩余时间
        /// 
        /// 
        private double CalculateTimeRemain()
        {
            if (IsBusy)
            {
                return _recipeTime != 0 ? (_recipeTime - Math.Floor((double)_processRecipeRoutine.ElapsedMilliseconds / 1000)) : 0;
            }
            else
            {
                return 0;
            }
        }
        /// 
        /// ProcessError
        /// 
        /// 
        /// 
        private bool ProcessError(object[] param)
        {
            return _processErrorRoutine.Start(param)==RState.Running;
        }
        /// 
        /// Process Error监控
        /// 
        /// 
        /// 
        private bool ProcessErrorMonitor(object[] param)
        {
            RState state = _processErrorRoutine.Monitor();
            if (state == RState.End||state==RState.Failed||state==RState.Timeout)
            {
                return true;
            }
            return false;
        }
        private bool AbortProcessError(object[] param)
        {
            _processErrorRoutine.Abort();      
            return false;
        }
        /// 
        /// Retry RunRecipe
        /// 
        /// 
        /// 
        private bool RetryRunRecipe(object[] param)
        {
            int stepIndex = (int)param[0];
            bool result = _processRecipeRoutine.Retry(stepIndex) == RState.Running;
            if (result)
            {
                if (_currentRecipe != null)
                {
                    if (CellItemRecipeTimeManager.Instance.ContainRecipe(_currentRecipe.Ppid))
                    {
                        _recipeTime = _cycle * CellItemRecipeTimeManager.Instance.GetRecipeTotalTime(_currentRecipe.Ppid);
                    }
                    else
                    {
                        _recipeTime = 0;
                    }
                    _runRecipeStartTime = DateTime.Now;
                }
            }
            return result;
        }
        /// 
        /// 确认ProcessRecipe是否完成
        /// 
        /// 
        /// 
        private bool ConfirmProcessRecipe(object[] param)
        {
            int stepIdex = (int)param[0];
            bool result = _processRecipeRoutine.CheckCompleteCondition(stepIdex);
            if (!result)
            {
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmList alarmList = new AlarmList(Module.ToString(), ((SRDState)fsm.State).ToString(), (int)SRDMSG.ProcessRecipe,
                    _processRecipeRoutine.ErrorMsg, _processRecipeRoutine.ErrorStep, (int)AlarmType.Error);
                    AlarmListManager.Instance.AddAlarm(alarmList);
                }
                PostMsg(SRDMSG.Error);
            }
            else
            {
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), SRDState.ProcessReciping.ToString());
                }
            }
            return result;
        }
        #endregion
        #region AWC Cycle
        /// 
        /// AWC Cycle
        /// 
        /// 
        private bool AWCCycle(object[] param)
        {
            return _awcCycleRoutine.Start(param) == RState.Running;
        }
        /// 
        /// AWC Cycle超时
        /// 
        /// 
        /// 
        private bool AWCCycleTimeout(object[] param)
        {
            RState ret = _awcCycleRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                _isAWCCycling = false;
                PostMsg(SRDMSG.Error);
                return false;
            }
            //设置IsPresenceTesting
            if (ret == RState.Running)
            {
                _isAWCCycling = true;
            }
            else
            {
                _isAWCCycling = false;
            }
            return ret == RState.End;
        }
        /// 
        /// Abort AWC Cycle
        /// 
        /// 
        /// 
        private bool AbortAWCCycle(object[] param)
        {
            _awcCycleRoutine.Abort();
            return true;
        }
        #endregion
        #region InitializeHome
        /// 
        /// InitializeHome
        /// 
        /// 
        /// 
        private bool InitializeHome(object[] param)
        {
            _isHomed = false;
            return _initializeHomeRoutine.Start() == RState.Running;
        }
        /// 
        /// InitializeHome超时
        /// 
        /// 
        /// 
        private bool InitializeHomeTimeout(object[] param)
        {
            RState ret = _initializeHomeRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                PostMsg(SRDMSG.Error);
                return false;
            }
            bool result = ret == RState.End;
            if (result)
            {
                _isHomed = true;
            }
            return result;
        }
        #endregion        
        #region RunRecipeRetry
        /// 
        /// Retry
        /// 
        /// 
        /// 
        private bool SRDRetry(object[] param)
        {
            AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
            if (alarmList != null)
            {
                CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), alarmList.ModuleCmd,
                    alarmList.ModuleStep);
            }
            return false;
        }
        #endregion
        #region ConfirmComplete
        /// 
        /// 确认是否完成
        /// 
        /// 
        /// 
        private bool ConfirmComplete(object[] param)
        {
            AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
            if (alarmList != null)
            {
                if (alarmList.ModuleState == SRDState.ProcessReciping.ToString())
                {
                    CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.ProcessRecipe, alarmList.ModuleStep);
                }
                else
                {
                    PostMsg(SRDState.Error);
                }
            }
            return false;
        }
        /// 
        /// 清除报警
        /// 
        /// 
        /// 
        private bool ClearModuleAlarm(object[] param)
        {
            AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
            if (alarmList != null)
            {
                AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), "");
            }
            return true;
        }
        #endregion
        #region Loader
        /// 
        /// SRD Loader Wafer
        /// 
        /// 
        /// 
        private bool LoaderWafer(object[] param)
        {
            return _loaderRoutine.Start(param) == RState.Running;
        }
        /// 
        /// SRD Loader Wafer Monitor
        /// 
        /// 
        /// 
        private bool LoaderWaferMonitor(object[] param)
        {
            RState state = _loaderRoutine.Monitor();
            if (state == RState.End || state == RState.Failed || state == RState.Timeout)
            {
                _isLoaded = state == RState.End;
                return true;
            }
            return false;
        }
        #endregion
        #region Unloader
        /// 
        /// SRD Unloader Wafer
        /// 
        /// 
        /// 
        private bool UnloaderWafer(object[] param)
        {
            return _unloaderRoutine.Start(false) == RState.Running;
        }
        /// 
        /// SRD Unloader Wafer Monitor
        /// 
        /// 
        /// 
        private bool UnloaderWaferMonitor(object[] param)
        {
            RState state = _unloaderRoutine.Monitor();
            if (state == RState.End || state == RState.Failed || state == RState.Timeout)
            {
                _isLoaded = !(state == RState.End);
                return true;
            }
            return false;
        }
        #endregion
        public bool Check(int msg, out string reason, params object[] args)
        {
            reason = "";
            return false;
        }
        public bool CheckAcked(int msg)
        {
            return false;
        }
        public int Invoke(string function, params object[] args)
        {
            switch (function)
            {
                case "HomeAll":
                    if (IsIdle)
                    {
                        return (int)FSM_MSG.NONE;
                    }
                    if (CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.InitializeHome))
                    {
                        return (int)SRDMSG.Initialize;
                    }
                    else
                    {
                        return (int)FSM_MSG.NONE;
                    }
                case "Retry":
                    if (CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.Retry, args))
                    {
                        return (int)SRDMSG.Retry;
                    }
                    else
                    {
                        return (int)FSM_MSG.NONE;
                    }
                case "ConfirmComplete":
                    if (CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.ConfirmComplete, args))
                    {
                        return (int)SRDMSG.ConfirmComplete;
                    }
                    else
                    {
                        return (int)FSM_MSG.NONE;
                    }
            }
            return (int)FSM_MSG.NONE;
        }
        #region GoToPosition
        /// 
        /// Go to Position
        /// 
        /// 
        /// 
        private bool GotoPosition(object[] param)
        {
            string axis = param[0].ToString();
            object[] objs = (object[])param[1];
            string position = objs[1].ToString();
            var result = CheckGotoPositionPreCondition(axis, position);
            if (result.result)
            {
                return _positionRoutine.Start(result.axis, position) == RState.Running;
            }
            else
            {
                return false;
            }
        }
        /// 
        /// 检验GotoPosition前置条件
        /// 
        /// 
        /// 
        /// 
        private (bool result, JetAxisBase axis) CheckGotoPositionPreCondition(string axis, string position)
        {
            switch (axis)
            {
                case "Rotation":
                    return (_rotationAxis.CheckGotoPosition(position), _rotationAxis);
                case "Arm":
                    return (_armAxis.CheckGotoPosition(position), _armAxis);
                default:
                    return (false, null);
            }
        }
        /// 
        /// GotoPosition超时
        /// 
        /// 
        /// 
        private bool GotoPositionTimeout(object[] param)
        {
            RState ret = _positionRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                return true;
            }
            return ret == RState.End;
        }
        #endregion
        #region 旋转
        /// 
        /// 开始旋转
        /// 
        /// 
        /// 
        private bool StartRotation(object[] param)
        {
            string axis = param[0].ToString();
            object[] objs = (object[])param[1];
            double time = double.Parse(objs[0].ToString());
            double speed = double.Parse(objs[1].ToString());
            return _rotationRoutine.Start(_rotationAxis, time, speed) == RState.Running;
        }
        /// 
        /// RotationTimeout
        /// 
        /// 
        /// 
        private bool RotationTimeout(object[] param)
        {
            RState ret = _rotationRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                //PostMsg(SRDMSG.Error);
                return true;
            }
            return ret == RState.End;
        }
        /// 
        /// 停止旋转
        /// 
        /// 
        /// 
        private bool StopRotation(object[] param)
        {
            _rotationAxis.StopPositionOperation();
            return _rotationAxis.Status == RState.Running;
        }
        /// 
        /// 停止旋转监控
        /// 
        /// 
        /// 
        private bool StopRotationTimeout(object[] param)
        {
            RState ret = _rotationAxis.Status;
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                //PostMsg(SRDMSG.Error);
                return true;
            }
            return ret == RState.End;
        }
        #endregion
        #region PresenceTest       
        private bool PresenceTest(object[] param)
        {
            _recipeTime = 0;
            return _presenceTestRoutine.Start(param) == RState.Running;
        }
        private bool PresenceTestTimeout(object[] param)
        {
            RState ret = _presenceTestRoutine.Monitor();
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                _isPresenceTesting = false;
                PostMsg(SRDMSG.Error);
                return false;
            }
            //设置IsPresenceTesting
            if (ret == RState.Running)
            {
                _isPresenceTesting = true;
            }
            else
            {
                _isPresenceTesting = false;
            }
            return ret == RState.End;
        }
        /// 
        /// Abort PresenceTest
        /// 
        /// 
        /// 
        private bool AbortPresenceTest(object[] param)
        {
            _presenceTestRoutine.Abort();
            return true;
        }
        #endregion
        /// 
        /// 获取当前子状态机
        /// 
        private string GetCurrentStateMachine()
        {
            string state = "";          
            switch ((SRDState)fsm.State)
            {
                case SRDState.Init:
                    state = "Init";
                    break;
                case SRDState.Initializing:
                    state = _initializeRoutine.CurrentStateMachine;
                    break;
                case SRDState.Homing:
                    state = _homeRoutine.CurrentStateMachine;
                    break;                
                case SRDState.SwitchOning:
                    state = _switchOnRoutine.CurrentStateMachine;
                    break;
                case SRDState.SwitchOffing:
                    state = _switchOffRoutine.CurrentStateMachine;
                    break;
                case SRDState.Positioning:
                    state = _positionRoutine.CurrentStateMachine;
                    break;
                case SRDState.Rotating:
                    state = _rotationRoutine.CurrentStateMachine;
                    break;
                case SRDState.PresenceTesting:
                    state = _presenceTestRoutine.CurrentStateMachine;
                    break;
                case SRDState.ProcessReciping:
                    state = _processRecipeRoutine.CurrentStateMachine;
                    break;
                case SRDState.AWCCycling:
                    state = _awcCycleRoutine.CurrentStateMachine;
                    break;
                default:
                    state = Enum.GetName(typeof(SRDState),fsm.State);
                    break;
            }
            return state;
        }
        /// 
        /// 设置IsAWCCycling
        /// 
        /// 
        public void SetIsAWCCycling(bool flag)
        {
            _isAWCCycling = flag;
        }
    }
    public enum SRDMSG
    {
        Initialize,
        InitializeHome,
        ProcessRecipe,
        ResumeError,
        SwitchOn,
        SwitchOff,
        HomeAll,
        Error,
        GoToSavedPosition,
        Abort,
        StartRotation,
        StopRotation,
        PresenceTestStart,
        PresenceTestStop,
        AWCCycleStart,
        Init,
        ProcessError,
        Retry,
        ConfirmComplete,
        Loader,
        Unloader
    }
}