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.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using Aitex.Core.Utilities;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.Common.Utilities;
using MECF.Framework.Common.WaferHolder;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.Loader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.Alarm;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Routine;
using System.Collections;
using System.Windows.Markup;
using MECF.Framework.Common.CommonData.Loader;
using Aitex.Core.Common;
using MECF.Framework.RT.Core.Equipments;
using CyberX8_RT.Modules.Dryer;
namespace CyberX8_RT.Modules.Loader
{
    public class LoaderEntity : Entity, IEntity, IModuleEntity
    {
        public enum LotTrackDatasStatus 
        { 
            None,
            Half,
            Complete
        }
        #region 属性
        public ModuleName Module { get; private set; }
        public bool IsInit
        {
            get { return fsm.State == (int)LOADERSTATE.Init; }
        }
        public bool IsIdle
        {
            get
            {
                return fsm.State == (int)LOADERSTATE.Idle;
            }
        }
        public bool IsError
        {
            get { return fsm.State == (int)LOADERSTATE.Error; }
        }
        public bool IsBusy
        {
            get { return !IsInit && !IsError && !IsIdle; }
        }
        public bool IsAuto { get; } = true;
        /// 
        /// 是否为工程模式
        /// 
        public bool IsEngineering { get; } = false;
        /// 
        /// 是否为产品模式
        /// 
        public bool IsProduction { get; } = true;
        public bool IsHomed
        {
            get { return _isHomed; }
        }
        /// 
        /// 当前状态机状态
        /// 
        public int State { get { return fsm.State; } }
        /// 
        /// 是否禁用
        /// 
        public bool IsDisable { get; internal set; }
        /// 
        /// Rotation是否SwitchOn
        /// 
        public bool IsRotationSwitchOn
        {
            get { return _rotationAxis.IsSwitchOn; }
        }
        /// 
        /// ShuttleA是否SwitchOn
        /// 
        public bool IsShuttleASwitchOn
        {
            get { return _shuttleAAxis.IsSwitchOn; }
        }
        /// 
        /// ShuttleB是否SwitchOn
        /// 
        public bool IsShuttleBSwitchOn
        {
            get { return _shuttleBAxis.IsSwitchOn; }
        }
        /// 
        /// TiltA是否SwitchOn
        /// 
        public bool IsTiltASwitchOn
        {
            get { return _tiltAAxis.IsSwitchOn; }
        }
        /// 
        /// TiltB是否SwitchOn
        /// 
        public bool IsTiltBSwitchOn
        {
            get { return _tiltBAxis.IsSwitchOn; }
        }
        /// 
        /// CrsA是否SwitchOn
        /// 
        public bool IsCrsASwitchOn
        {
            get { return _crsAAxis.IsSwitchOn; }
        }
        /// 
        /// CrsB是否SwitchOn
        /// 
        public bool IsCrsBSwitchOn
        {
            get { return _crsBAxis.IsSwitchOn; }
        }
        /// 
        /// WaferHolder信息
        /// 
        public WaferHolderInfo WaferHolderInfo { get { return WaferHolderManager.Instance.GetWaferHolder("Loader"); } }
        #endregion
        #region 内部变量
        private bool _isHomed = false;
        private IRoutine _currentRoutine;
        /// 
        /// Loader当前unload、load操作Slot
        /// 
        private Dictionary> _loaderOperatingWaferInfosList = new Dictionary> { { "unload", new List(new string[2]) }, { "load", new List(new string[2]) } };
        #region Axis
        JetAxisBase _shuttleAAxis;
        JetAxisBase _shuttleBAxis;
        JetAxisBase _tiltAAxis;
        JetAxisBase _tiltBAxis;
        JetAxisBase _crsAAxis;
        JetAxisBase _crsBAxis;
        JetAxisBase _rotationAxis;
        LoaderSideDevice _sideA;
        LoaderSideDevice _sideB;
        LoaderCommonDevice _loaderCommon;
        #endregion
        #region routine
        private LoaderHomeAllRoutine _homeAllRoutine;
        private LoaderSwitchAllOnRoutine _switchAllOnRoutine;
        private LoaderSwitchAllOffRoutine _switchAllOffRoutine;
        private LoaderUnloadSideRoutine _unloadSideRoutine;
        private LoaderLoadSideRoutine _loadSideRoutine;
        #endregion
        #region LotTrackDatas
        /// 
        /// Load LotTrackData
        /// 
        private List _loadLotTrackDatas = new List();
        /// 
        /// UnLoad LotTrackData
        /// 
        private List _unloadLotTrackDatas = new List();
        /// 
        /// UnLoad LotTrackDataBuffer
        /// 
        private List _unloadLotTrackDatasBuffer = new List();
        /// 
        /// LeakTest LotTrackData
        /// 
        private List _flowLotTrackdatas = new List();
        /// 
        /// LoadTime
        /// 
        private List _loadTimeList = new List();
        /// 
        /// LoadTime
        /// 
        private List _unloadTimeList = new List();
        /// 
        /// Unload Start Time
        /// 
        private DateTime _unloadStartTime;
        /// 
        /// LotTrackHead
        /// 
        private LotTrackFileHeaderCommonData _headerdata;
        /// 
        /// Load Datas Status
        private LotTrackDatasStatus _loadDatasStatus = LotTrackDatasStatus.None;
        /// 
        /// Unload Datas Status
        /// 
        private LotTrackDatasStatus _unloadDatasStatus = LotTrackDatasStatus.None;
        /// 
        /// Unload Datas Buffer Status
        /// 
        private LotTrackDatasStatus _unloadDatasBufferStatus = LotTrackDatasStatus.None;
        /// 
        /// Flow Test Datas status
        /// 
        private LotTrackDatasStatus _flowTestDatasStatus = LotTrackDatasStatus.None;
        #endregion
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public LoaderEntity(ModuleName module)
        {
            this.Module = module;
            _shuttleAAxis = DEVICE.GetDevice($"{module}.ShuttleA");
            _shuttleBAxis = DEVICE.GetDevice($"{module}.ShuttleB");
            _tiltAAxis = DEVICE.GetDevice($"{module}.TiltA");
            _tiltBAxis = DEVICE.GetDevice($"{module}.TiltB");
            _crsAAxis = DEVICE.GetDevice($"{module}.LSA");
            _crsBAxis = DEVICE.GetDevice($"{module}.LSB");
            _rotationAxis = DEVICE.GetDevice($"{module}.Rotation");
            _sideA = DEVICE.GetDevice($"{Module}.SideA");
            _sideB = DEVICE.GetDevice($"{Module}.SideB");
            _loaderCommon = DEVICE.GetDevice($"{module}.Common");
            WaferManager.Instance.SubscribeLocation(Module, 2);
            InitialOperation();
            InitializeRoutine();
            InitialDATA();
            InitialFsm();
        }
        /// 
        /// 初始化操作
        /// 
        private void InitialOperation()
        {
            OP.Subscribe($"{Module}.Abort", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.Abort); });
            OP.Subscribe($"{Module}.ClearError", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.ClearError); });
            OP.Subscribe($"{Module}.Common.HomeAll", (cmd, args) => { PostMsg((int)LoaderMSG.HomeAll); return true; });
            OP.Subscribe($"{Module}.Common.SwitchOnAll", (cmd, args) => { PostMsg((int)LoaderMSG.SwitchOnAll); return true; });
            OP.Subscribe($"{Module}.Common.SwitchOffAll", (cmd, args) => { PostMsg((int)LoaderMSG.SwitchOffAll); return true; });
        }
        /// 
        /// 初始化Routine
        /// 
        private void InitializeRoutine()
        {
            _homeAllRoutine=new LoaderHomeAllRoutine(Module.ToString());
            _switchAllOnRoutine=new LoaderSwitchAllOnRoutine(Module.ToString());
            _switchAllOffRoutine=new LoaderSwitchAllOffRoutine(Module.ToString());
            _unloadSideRoutine = new LoaderUnloadSideRoutine(Module.ToString());
            _loadSideRoutine=new LoaderLoadSideRoutine(Module.ToString());
        }
        /// 
        /// 初始化数据
        /// 
        private void InitialDATA()
        {
            InitializeSvid();
            DATA.Subscribe($"{Module}.FsmState", () => ((LOADERSTATE)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.IsHomed", () => _isHomed, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.IsError", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB);
        }
        /// 
        /// 初始化SVID
        /// 
        private void InitializeSvid()
        {
            DATA.Subscribe($"{Module}.State", () => ((LOADERSTATE)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LotID", () => WaferHolderInfo?.LotId, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.WSID", () => WaferHolderInfo?.Id, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LSAID", () => WaferHolderInfo?.CrsAId, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.LSBID", () => WaferHolderInfo?.CrsBId, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.SequenceRecipe", () => WaferHolderInfo?.SequenceId, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.WaferAID", () => WaferHolderInfo?.WaferAId, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.WaferBID", () => WaferHolderInfo?.WaferBId, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.Task", () => WaferHolderInfo?.CurrentControlJobId, SubscriptionAttribute.FLAG.IgnoreSaveDB);
        }
        /// 
        /// 初始化状态机
        /// 
        private void InitialFsm()
        {
            fsm = new StateMachine(Module.ToString(), (int)LOADERSTATE.Init, 100);
            fsm.EnableRepeatedMsg(true);
            AnyStateTransition(LoaderMSG.Error, EnterError, LOADERSTATE.Error);
            AnyStateTransition(LoaderMSG.ReturnInit, EnterInit, LOADERSTATE.Init);
            AnyStateTransition(LoaderMSG.ReturnIdle, NullFunc, LOADERSTATE.Idle);
            AnyStateTransition(LoaderMSG.Abort, Abort, LOADERSTATE.Init);
            //clear error
            Transition(LOADERSTATE.Error, LoaderMSG.ClearError, ResumeError, LOADERSTATE.Init);
            //HomeAll
            AnyStateTransition(LoaderMSG.HomeAll, HomeAll, LOADERSTATE.Homing);
            Transition(LOADERSTATE.Homing, FSM_MSG.TIMER, HomeAllMonitor, LOADERSTATE.Idle);
            //Switch On All
            Transition(LOADERSTATE.Error, LoaderMSG.SwitchOnAll, SwitchOnAll, LOADERSTATE.SwitchOning);
            Transition(LOADERSTATE.Init, LoaderMSG.SwitchOnAll, SwitchOnAll, LOADERSTATE.SwitchOning);
            Transition(LOADERSTATE.Idle, LoaderMSG.SwitchOnAll, SwitchOnAll, LOADERSTATE.SwitchOning);
            Transition(LOADERSTATE.SwitchOning, FSM_MSG.TIMER, SwitchOnAllMonitor, LOADERSTATE.Init);
            //Switch Off All
            Transition(LOADERSTATE.Error, LoaderMSG.SwitchOffAll, SwitchOffAll, LOADERSTATE.SwitchOffing);
            Transition(LOADERSTATE.Init, LoaderMSG.SwitchOffAll, SwitchOffAll, LOADERSTATE.SwitchOffing);
            Transition(LOADERSTATE.Idle, LoaderMSG.SwitchOffAll, SwitchOffAll, LOADERSTATE.SwitchOffing);
            Transition(LOADERSTATE.SwitchOffing, FSM_MSG.TIMER, SwitchOffAllMonitor, LOADERSTATE.Init);
            //Prepare for Place
            Transition(LOADERSTATE.Idle, LoaderMSG.PrepareForPlace, PrePareForPlace, LOADERSTATE.PrepreForPlacing);
            Transition(LOADERSTATE.PrepreForPlacing, FSM_MSG.TIMER, PrepareForPlaceMonitor, LOADERSTATE.WaitForUnload);
            Transition(LOADERSTATE.Idle, LoaderMSG.ReadyForPuf, NullFunc, LOADERSTATE.WaitForUnload);
            Transition(LOADERSTATE.WaitForUnload, LoaderMSG.UnloadSide, UnloadSide, LOADERSTATE.Unloading);
            Transition(LOADERSTATE.Unloading, FSM_MSG.TIMER, UnloadSideMonitor, LOADERSTATE.WaitForLoad);
            Transition(LOADERSTATE.WaitForLoad, LoaderMSG.LoadSide, LoadSide, LOADERSTATE.Loading);
            Transition(LOADERSTATE.Loading, FSM_MSG.TIMER, LoadSideMonitor, LOADERSTATE.Idle);
            //Flip
            Transition(LOADERSTATE.Idle, LoaderMSG.WaitFlip, NullFunc, LOADERSTATE.WaitForFlip);
            Transition(LOADERSTATE.WaitForFlip,LoaderMSG.PrepareForPlace, PrePareForPlace, LOADERSTATE.PrepreForPlacing);
            //Retry
            Transition(LOADERSTATE.Error, LoaderMSG.Retry, NullFunc, LOADERSTATE.Retrying);
            Transition(LOADERSTATE.Retrying,FSM_MSG.TIMER,LoaderRetry,LOADERSTATE.Retrying);
            Transition(LOADERSTATE.Retrying, LoaderMSG.UnloadSide, RetryUnloadSide, LOADERSTATE.Unloading);
            Transition(LOADERSTATE.Retrying, LoaderMSG.LoadSide, RetryLoadSide, LOADERSTATE.Loading);
            //ConfirmComplete
            Transition(LOADERSTATE.Init, LoaderMSG.ConfirmComplete, ClearModuleAlarm, LOADERSTATE.Init);
            Transition(LOADERSTATE.Idle, LoaderMSG.ConfirmComplete, ClearModuleAlarm, LOADERSTATE.Idle);
            Transition(LOADERSTATE.Error, LoaderMSG.ConfirmComplete, NullFunc, LOADERSTATE.ConfirmCompleting);
            Transition(LOADERSTATE.ConfirmCompleting,FSM_MSG.TIMER,ConfirmComplete, LOADERSTATE.ConfirmCompleting);
            Transition(LOADERSTATE.ConfirmCompleting, LoaderMSG.PrepareForPlace, NullFunc, LOADERSTATE.WaitForUnload);
            Transition(LOADERSTATE.ConfirmCompleting,LoaderMSG.UnloadSide,ConfirmUnloadSide, LOADERSTATE.WaitForLoad);
            Transition(LOADERSTATE.ConfirmCompleting, LoaderMSG.LoadSide, ConfirmLoadSide, LOADERSTATE.Idle);
            EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
            EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
        }
        /// 
        /// 恢复错误
        /// 
        /// 
        /// 
        private bool ResumeError(object[] param)
        {
            if (_isHomed)
            {
                PostMsg(LoaderMSG.ReturnIdle);
                return false;
            }
            return true;
        }
        /// 
        /// 检验Loader两边waferSize不一致
        /// 
        /// 
        public bool CheckLoaderWaferSizeNotEqual()
        {
            int sideAWaferSize = SC.GetValue($"Loader1.SideAWaferSize");
            int sideBWaferSize = SC.GetValue($"Loader1.SideBWaferSize");
            return sideAWaferSize != sideBWaferSize;
        }
        #region Abort
        private bool Abort(object parameter)
        {
            bool preHomed = IsHomed;
            _shuttleAAxis.StopPositionOperation();
            _shuttleBAxis.StopPositionOperation();
            _tiltAAxis.StopPositionOperation();
            _tiltBAxis.StopPositionOperation();
            _crsAAxis.StopPositionOperation();
            _crsBAxis.StopPositionOperation();
            _rotationAxis.StopPositionOperation();
            if (_currentRoutine != null)
            {
                _currentRoutine.Abort();
                _currentRoutine = null;
            }
            if (preHomed)
            {
                PostMsg(LoaderMSG.ReturnIdle);
                return false;
            }
            //Header信息
            if (_headerdata != null)
            {
                WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString());
                _headerdata.SequenceRecipe = (info != null ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : null);
                _headerdata.ProcessTransferList = (info != null ? info.SchedulerModules : null);
                LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _unloadLotTrackDatas, _loadLotTrackDatas, _flowLotTrackdatas, _headerdata, _loaderOperatingWaferInfosList, 
                    _loadTimeList, _unloadTimeList, _unloadStartTime, LotTrackDatasStatus.None, LotTrackDatasStatus.None, LotTrackDatasStatus.None, _unloadLotTrackDatasBuffer, LotTrackDatasStatus.None);
            }            
            return true;
        }
        #endregion
        /// 
        /// 进入错误状态
        /// 
        /// 
        /// 
        private bool EnterError(object param)
        {
            return true;
        }
        /// 
        /// 进入初始化状态
        /// 
        /// 
        /// 
        private bool EnterInit(object param)
        {
            _isHomed = false;
            return true;
        }
        #region HomeAll
        /// 
        /// Home All
        /// 
        /// 
        /// 
        private bool HomeAll(object[] param)
        {
            _isHomed = false;
            bool result= _homeAllRoutine.Start(param) == RState.Running;
            if (result)
            {
                _currentRoutine = _homeAllRoutine;
            }
            return result;
        }
        /// 
        /// Load All监控
        /// 
        /// 
        /// 
        private bool HomeAllMonitor(object[] param)
        {
            RState state = _homeAllRoutine.Monitor();
            if (state==RState.Failed||state==RState.Timeout)
            {
                _currentRoutine = null;
                PostMsg(LoaderMSG.Error);
                return false;
            }
            bool result= state == RState.End;
            if(result)
            {
                _currentRoutine = null;
                _isHomed = true;
            }
            return result;
        }
        #endregion
        #region Switch On All
        private bool SwitchOnAll(object[] param)
        {
            return _switchAllOnRoutine.Start(param) == RState.Running;
        }
        
        private bool SwitchOnAllMonitor(object[] param)
        {
            RState state = _switchAllOnRoutine.Monitor();
            if (state == RState.Failed || state == RState.Timeout)
            {
                PostMsg(LoaderMSG.ReturnInit);
                return false;
            }
            bool result= state == RState.End;
            if(result)
            {
                _isHomed = false;
            }
            return result;
        }
        #endregion
        #region Switch Off All
        private bool SwitchOffAll(object[] param)
        {
            return _switchAllOffRoutine.Start(param) == RState.Running;
        }
        private bool SwitchOffAllMonitor(object[] param)
        {
            RState state = _switchAllOffRoutine.Monitor();
            if (state == RState.Failed || state == RState.Timeout)
            {
                PostMsg(LoaderMSG.ReturnInit);
                return false;
            }
            bool result = state == RState.End;
            if (result)
            {
                _isHomed = false;
            }
            return result;
        }
        #endregion
        #region Prepare for Place
        /// 
        /// Prepare For Place
        /// 
        /// 
        private bool PrePareForPlace(object[] param)
        {
            //默认"TRNPA"
            string str = (param==null||param.Length==0)? "TRNPA":param[0].ToString();
            return _rotationAxis.PositionStation(str);
        }
        /// 
        /// Prepare For Place监控
        /// 
        /// 
        /// 
        private bool PrepareForPlaceMonitor(object param)
        {
            RState ret = _rotationAxis.Status;
            if (ret == RState.End)
            {
                return true;
            }
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                PostMsg(LoaderMSG.Error);
            }
            return false;
        }
        #endregion
        #region Unload Side
        /// 
        /// Unload Side
        /// 
        /// 
        /// 
        private bool UnloadSide(object[] param)
        {
            bool result= _unloadSideRoutine.Start(param) == RState.Running;
            if(result)
            {
                LotTrackDataClear();
                _currentRoutine = _unloadSideRoutine;                
                _unloadLotTrackDatas.Clear();
                _unloadLotTrackDatasBuffer.Clear();
                _unloadTimeList.Clear();
                _unloadTimeList.Add(DateTime.Now);
                _unloadStartTime = DateTime.Now;
                _loaderOperatingWaferInfosList["unload"] = GetWaferInfo();
                //Header信息
                _headerdata = new LotTrackFileHeaderCommonData();
                _headerdata.SoftWareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();               
                if (SC.ContainsItem("System.ToolID")) _headerdata.ToolID = SC.GetStringValue("System.ToolID");
                _loadDatasStatus = LotTrackDatasStatus.None;
                _unloadDatasStatus = LotTrackDatasStatus.None;
                _flowTestDatasStatus = LotTrackDatasStatus.None;
                _headerdata.ProcessTransferList = new List();
            }
            return result;
        }
        /// 
        /// Retry UloadSide
        /// 
        /// 
        /// 
        private bool RetryUnloadSide(object[] param)
        {
            int stepIndex = (int)param[0];
            bool result = _unloadSideRoutine.Retry(stepIndex)==RState.Running;
            if (result)
            {
                _unloadDatasStatus = LotTrackDatasStatus.Half;
                _unloadLotTrackDatas.Clear();
                _currentRoutine = _unloadSideRoutine;
            }
            return result;
        }
        /// 
        /// Unload Side监控
        /// 
        /// 
        /// 
        private bool UnloadSideMonitor(object param)
        {
            RState ret = _unloadSideRoutine.Monitor();
            if (ret == RState.End)
            {
                AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), LOADERSTATE.Unloading.ToString());
                _unloadLotTrackDatas = _unloadSideRoutine.UnloadLotTrackDatas;
                _unloadLotTrackDatasBuffer.AddRange(_unloadSideRoutine.UnloadLotTrackDatas);
                _unloadTimeList.Add(DateTime.Now);
                //Header信息
                WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString());
                _headerdata.SequenceRecipe = ((info != null && info.SequenceRecipe != null) ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : "");           
                if (info != null) _headerdata.ProcessTransferList.AddRange(info.SchedulerModules);
                info.SchedulerModules.Clear();
                LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _unloadLotTrackDatas, _loadLotTrackDatas, _flowLotTrackdatas, _headerdata, _loaderOperatingWaferInfosList,
                    _loadTimeList, _unloadTimeList, _unloadStartTime, _unloadDatasStatus, _loadDatasStatus, _flowTestDatasStatus, _unloadLotTrackDatasBuffer, _unloadDatasStatus, true);
                return true;
            }
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmList alarmList = new AlarmList(Module.ToString(), ((LOADERSTATE)fsm.State).ToString(), (int)LoaderMSG.UnloadSide,
                        _unloadSideRoutine.ErrorMsg, _unloadSideRoutine.ErrorStep, (int)AlarmType.Error);
                    AlarmListManager.Instance.AddAlarm(alarmList);
                }
                PostMsg(LoaderMSG.Error);
                _unloadLotTrackDatas = _unloadSideRoutine.UnloadLotTrackDatas;
                _unloadLotTrackDatasBuffer.AddRange(_unloadSideRoutine.UnloadLotTrackDatas);
                ////Header信息
                WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString());
                _headerdata.SequenceRecipe = ((info != null && info.SequenceRecipe != null) ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : "");
                if (info != null) _headerdata.ProcessTransferList.AddRange(info.SchedulerModules);
                info.SchedulerModules.Clear();
                LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _unloadLotTrackDatas, _loadLotTrackDatas, _flowLotTrackdatas, _headerdata, _loaderOperatingWaferInfosList, 
                    _loadTimeList, _unloadTimeList, _unloadStartTime, _unloadDatasStatus, _loadDatasStatus, _flowTestDatasStatus, _unloadLotTrackDatasBuffer, _unloadDatasStatus, true);
            }
            return false;
        }
        /// 
        /// 确认UnloadAll是否完成
        /// 
        /// 
        /// 
        private bool ConfirmUnloadSide(object[] param)
        {
            int stepIdex=(int)param[0];
            bool result = _unloadSideRoutine.CheckCompleteCondition(stepIdex);
            if(!result)
            {
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmList alarmList = new AlarmList(Module.ToString(), ((LOADERSTATE)fsm.State).ToString(), (int)LoaderMSG.UnloadSide,
                    _unloadSideRoutine.ErrorMsg, _unloadSideRoutine.ErrorStep, (int)AlarmType.Error);
                    AlarmListManager.Instance.AddAlarm(alarmList);
                }
                PostMsg(LoaderMSG.Error);
            }
            else
            {
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), LOADERSTATE.Unloading.ToString());
                }
            }
            return result;
        }
        #endregion
        #region Load Side
        /// 
        /// Load Side
        /// 
        /// 
        /// 
        private bool LoadSide(object[] param)
        {
            bool result= _loadSideRoutine.Start(param) == RState.Running;
            if(result)
            {
                _currentRoutine = _loadSideRoutine;
                //_loadTimeList.Clear();
                _flowLotTrackdatas.Clear();
                _loadLotTrackDatas.Clear();
                _loadDatasStatus = LotTrackDatasStatus.None;
                _flowTestDatasStatus = LotTrackDatasStatus.None;
                _unloadDatasStatus = LotTrackDatasStatus.Complete;
                _unloadDatasBufferStatus = LotTrackDatasStatus.None;
            }
            return result;
        }
        /// 
        /// Retry LoadSide
        /// 
        /// 
        /// 
        private bool RetryLoadSide(object[] param)
        {
            int stepIndex = (int)param[0];
            bool result = _loadSideRoutine.Retry(stepIndex) == RState.Running;
            if (result)
            {
                _unloadDatasStatus = LotTrackDatasStatus.Complete;
                _unloadDatasBufferStatus = LotTrackDatasStatus.Complete;
                SetLotTrackDatasStatus(stepIndex);               
                _currentRoutine = _loadSideRoutine;
            }
            return result;
        }
        /// 
        /// 监控LoadSide
        /// 
        /// 
        /// 
        private bool LoadSideMonitor(object param)
        {
            RState ret = _loadSideRoutine.Monitor();
            if (ret == RState.End)
            {
                AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), LOADERSTATE.Loading.ToString());
                _loadLotTrackDatas = _loadSideRoutine.LoadLotTrackDatas;
                _loadTimeList = _loadSideRoutine.LoadTimeList;
                _flowLotTrackdatas = _loadSideRoutine.FlowLotTrackDatas;
                bool clearFlag = _loadDatasStatus == LotTrackDatasStatus.None && _flowTestDatasStatus == LotTrackDatasStatus.None;
                _loaderOperatingWaferInfosList["load"] = GetWaferInfo(clearFlag);
                //Header信息
                WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString());
                _headerdata.SequenceRecipe = ((info != null && info.SequenceRecipe != null) ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : "");
                if(info != null) _headerdata.ProcessTransferList.AddRange(info.SchedulerModules);
                info.SchedulerModules.Clear();
                LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _unloadLotTrackDatas, _loadLotTrackDatas, _flowLotTrackdatas, _headerdata, _loaderOperatingWaferInfosList, 
                    _loadTimeList, _unloadTimeList,_unloadStartTime, _unloadDatasStatus, _loadDatasStatus, _flowTestDatasStatus, _unloadLotTrackDatasBuffer, _unloadDatasBufferStatus);
                return true;
            }
            if (ret == RState.Failed || ret == RState.Timeout)
            {
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmList alarmList = new AlarmList(Module.ToString(), ((LOADERSTATE)fsm.State).ToString(), (int)LoaderMSG.LoadSide,
                    _loadSideRoutine.ErrorMsg, _loadSideRoutine.ErrorStep, (int)AlarmType.Error);
                    AlarmListManager.Instance.AddAlarm(alarmList);
                }
                PostMsg(LoaderMSG.Error);
                _loadLotTrackDatas = _loadSideRoutine.LoadLotTrackDatas;
                _loadTimeList = _loadSideRoutine.LoadTimeList;
                _flowLotTrackdatas = _loadSideRoutine.FlowLotTrackDatas;
                bool clearFlag = _loadDatasStatus == LotTrackDatasStatus.None && _flowTestDatasStatus == LotTrackDatasStatus.None;
                _loaderOperatingWaferInfosList["load"] = GetWaferInfo(clearFlag);
                //Header信息
                WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString());
                _headerdata.SequenceRecipe = ((info != null && info.SequenceRecipe != null) ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : "");
                if (info != null) _headerdata.ProcessTransferList.AddRange(info.SchedulerModules);
                info.SchedulerModules.Clear();
                LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _unloadLotTrackDatas, _loadLotTrackDatas, _flowLotTrackdatas, _headerdata, _loaderOperatingWaferInfosList, 
                    _loadTimeList, _unloadTimeList, _unloadStartTime, _unloadDatasStatus, _loadDatasStatus, _flowTestDatasStatus, _unloadLotTrackDatasBuffer, _unloadDatasBufferStatus);
            }
            return false;
        }
        /// 
        /// 确认UnloadSide是否完成
        /// 
        /// 
        /// 
        private bool ConfirmLoadSide(object[] param)
        {
            int stepIdex = (int)param[0];
            bool result = _loadSideRoutine.CheckCompleteCondition(stepIdex);
            if (!result)
            {
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmList alarmList = new AlarmList(Module.ToString(), ((LOADERSTATE)fsm.State).ToString(), (int)LoaderMSG.LoadSide,
                    _loadSideRoutine.ErrorMsg, _loadSideRoutine.ErrorStep, (int)AlarmType.Error);
                    AlarmListManager.Instance.AddAlarm(alarmList);
                }
                PostMsg(LoaderMSG.Error);
            }
            else
            {
                if (Singleton.Instance.IsAutoRunning)
                {
                    AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(),LOADERSTATE.Loading.ToString());
                }
            }
            return result;
        }
        #endregion
        #region LotTrack      
        /// 
        /// 获取Wafer信息
        /// 
        private List GetWaferInfo(bool clearPath = false)
        {
            List waferIDs = new List(new string[2]);
            WaferHolderInfo whInfo = WaferHolderManager.Instance.GetWaferHolder(Module.ToString());
            if (whInfo == null) return null;
            waferIDs[0] = string.IsNullOrEmpty(whInfo.WaferAId) ? "" : whInfo.WaferAId;
            waferIDs[1] = string.IsNullOrEmpty(whInfo.WaferBId) ? "" : whInfo.WaferBId;
            if (clearPath && !string.IsNullOrEmpty(waferIDs[0])) WaferManager.Instance.ClearWaferLotTrackPath(ModuleName.Loader1, 0);
            if (clearPath && !string.IsNullOrEmpty(waferIDs[1])) WaferManager.Instance.ClearWaferLotTrackPath(ModuleName.Loader1, 1);
            return waferIDs;
        }
        /// 
        /// 清除信息
        /// 
        private void LotTrackDataClear()
        {
            _headerdata = null;
            _loadLotTrackDatas.Clear();
            _unloadLotTrackDatas.Clear();
            _flowLotTrackdatas.Clear();
            _loadTimeList.Clear();
            _unloadTimeList.Clear();
            _loaderOperatingWaferInfosList["load"].Clear();
            _loaderOperatingWaferInfosList["unload"].Clear();
        }
        /// 
        /// 设置Load LotTrackDatas记录状态
        /// 
        /// 
        private void SetLotTrackDatasStatus(int stepIndex)
        {
            if (stepIndex == 0 || stepIndex == -1)
            {
                _loadDatasStatus = LotTrackDatasStatus.Half;
                _flowTestDatasStatus = LotTrackDatasStatus.None;
            }
            else if (stepIndex == 1)
            {
                _loadDatasStatus = LotTrackDatasStatus.Complete;
                _flowTestDatasStatus = LotTrackDatasStatus.None;
            }
            else
            {
                _loadDatasStatus = LotTrackDatasStatus.Complete;
                _flowTestDatasStatus = LotTrackDatasStatus.Complete;
            }
        }       
        #endregion
        #region LoaderRetry
        /// 
        /// Retry
        /// 
        /// 
        /// 
        private bool LoaderRetry(object[] param)
        {
            AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
            if (alarmList != null)
            {
                CheckToPostMessage(eEvent.ERR_LOADER, 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==LOADERSTATE.Unloading.ToString())
                {
                    CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(),(int)LoaderMSG.UnloadSide,alarmList.ModuleStep);
                }
                else if(alarmList.ModuleState==LOADERSTATE.Loading.ToString())
                {
                    CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.LoadSide,alarmList.ModuleStep);
                }
                else if (alarmList.ModuleState == LOADERSTATE.PrepreForPlacing.ToString())
                {
                    CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.PrepareForPlace, alarmList.ModuleStep);
                }
                else
                {
                    PostMsg(LoaderMSG.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
        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_LOADER, Module.ToString(), (int)LoaderMSG.HomeAll))
                    {
                        return (int)FSM_MSG.NONE;
                    }
                    else
                    {
                        return (int)FSM_MSG.ALARM;
                    }
                case "Abort":
                    CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.Abort);
                    return (int)FSM_MSG.NONE;
                case "PrepareForPlace":
                    if (State == (int)LOADERSTATE.WaitForUnload||State==(int)LOADERSTATE.PrepreForPlacing)
                    {
                        return (int)LoaderMSG.PrepareForPlace;
                    }
                    if (CheckToPostMessage(eEvent.WARN_LOADER, Module.ToString(), (int)LoaderMSG.PrepareForPlace,args))
                    {
                        return (int)LoaderMSG.PrepareForPlace;
                    }
                    else
                    {
                        return (int)FSM_MSG.NONE;
                    }
                case "Retry":
                    if (CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.Retry,args))
                    {
                        return (int)LoaderMSG.Retry;
                    }
                    else
                    {
                        return (int)FSM_MSG.NONE;
                    }
                case "ConfirmComplete":
                    if (CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.ConfirmComplete, args))
                    {
                        return (int)LoaderMSG.ConfirmComplete;
                    }
                    else
                    {
                        return (int)FSM_MSG.NONE;
                    }
            }
            return (int)FSM_MSG.NONE;
        }
    }
    public enum LoaderMSG
    {
        ReturnInit,
        ReturnIdle,
        Abort,
        HomeAll,
        GoToSavedPosition,
        StopFlow,
        SwitchOnAll,
        SwitchOffAll,
        Error,
        ClearError,
        PrepareForPlace,
        ReadyForPuf,
        UnloadSide,
        LoadSide,
        Retry,
        ConfirmComplete,
        WaitFlip,
    }
}