using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.OperationCenter;
using OpenSEMI.ClientBase;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Threading;
using CyberX8_MainPages.Unity;
using MECF.Framework.Common.Utilities;
using MECF.Framework.Common.Jobs;
using CyberX8_MainPages.PMs;
using MECF.Framework.Common.RecipeCenter;
using System.Collections.ObjectModel;
using System.Windows.Media.Animation;


namespace CyberX8_MainPages.ViewModels
{
    internal class JobOperationViewModel : BindableBase
    {
        #region 私有字段
        /// <summary>
        /// LP1的Wafer相关信息
        /// </summary>
        private WaferAssociationInfo _lp1WaferAssociation;
        /// <summary>
        /// LP2的Wafer相关信息
        /// </summary>
        private WaferAssociationInfo _lp2WaferAssociation;
        /// <summary>
        /// LP3的Wafer相关信息
        /// </summary>
        private WaferAssociationInfo _lp3WaferAssociation;
        /// <summary>
        /// LP1的Wafer数量
        /// </summary>
        private int m_LP1WaferCount;
        /// <summary>
        /// LP2的Wafer数量
        /// </summary>
        private int m_LP2WaferCount;
        /// <summary>
        /// LP3的Wafer数量
        /// </summary>
        private int m_LP3WaferCount;
        /// <summary>
        /// RT查询数据字典
        /// </summary>
        private Dictionary<string, object> m_RtDataValues;
        /// <summary>
        /// RT查询Key列表
        /// </summary>
        private List<string> m_RtDataKeys = new List<string>();
        /// <summary>
        /// Sequence数据列表 LP1
        /// </summary>     
        private ObservableCollection<string> m_SequenceSelectedItemsSource1 = new ObservableCollection<string>();
        /// <summary>
        /// Sequence数据列表 LP2
        /// </summary>     
        private ObservableCollection<string> m_SequenceSelectedItemsSource2 = new ObservableCollection<string>();
        /// <summary>
        /// Sequence数据列表 LP3
        /// </summary>     
        private ObservableCollection<string> m_SequenceSelectedItemsSource3 = new ObservableCollection<string>();
        /// <summary>
        /// LP1Sequence名称
        /// </summary>       
        private string m_LP1SequenceName;
        /// <summary>
        /// LP2Sequence名称
        /// </summary>       
        private string m_LP2SequenceName;
        /// <summary>
        /// LP3Sequence名称
        /// </summary>       
        private string m_LP3SequenceName;
        /// <summary>
        /// UiRecipeManager
        /// </summary>
        private UiRecipeManager _uiRecipeManager = new UiRecipeManager();
        /// <summary>
        /// 定时器
        /// </summary>
        DispatcherTimer _timer;
        /// <summary>
        /// LP1界面Enable
        /// </summary>
        private bool m_ButtonIsEnableLP1;
        /// <summary>
        /// LP2界面Enable
        /// </summary>
        private bool m_ButtonIsEnableLP2;
        /// <summary>
        /// LP3界面Enable
        /// </summary>
        private bool m_ButtonIsEnableLP3;
        /// <summary>
        /// LP1 SequenceName Buffer
        /// </summary>
        private string _LP1SequenceNameBuffer;
        /// <summary>
        /// LP2 SequenceName Buffer
        /// </summary>
        private string _LP2SequenceNameBuffer;
        /// <summary>
        /// LP3 SequenceName Buffer
        /// </summary>
        private string _LP3SequenceNameBuffer;

        private bool _isLp1Unable;
        private bool _isLp2Unable;
        private bool _isLp3Unable;

        private bool _lp1Unable;
        private bool _lp2Unable;
        private bool _lp3Unable;

        private bool _isLP1AutoStoped = true;
        private bool _isLP2AutoStoped = true;
        private bool _isLP3AutoStoped = true;
        private bool _isLP1AutoStarted = false;
        private bool _isLP2AutoStarted = false;
        private bool _isLP3AutoStarted = false;
        private bool _isLP1CanCreatedJob = false;
        private bool _isLP2CanCreatedJob = false;
        private bool _isLP3CanCreatedJob = false;

        /// <summary>
        /// LP1 RecipeMode
        /// </summary>
        private bool _lp1RecipeMode;
        /// <summary>
        /// LP2 RecipeMode
        /// </summary>
        private bool _lp2RecipeMode;
        /// <summary>
        /// LP3 RecipeMode
        /// </summary>
        private bool _lp3RecipeMode;
        /// <summary>
        /// LP1 Docked
        /// </summary>
        private bool _isLP1Docked;
        /// <summary>
        /// LP2 Docked
        /// </summary>
        private bool _isLP2Docked;
        /// <summary>
        /// LP3 Docked
        /// </summary>
        private bool _isLP3Docked;
        #endregion

        #region 属性 
        /// <summary>
        /// RT查询数据字典
        /// </summary>
        public Dictionary<string, object> RtDataValues
        {
            get { return m_RtDataValues; }
            set { SetProperty(ref m_RtDataValues, value); }
        }
        /// <summary>
        /// LP1的Wafer相关信息
        /// </summary>
        public WaferAssociationInfo LP1WaferAssociation
        {
            get { return _lp1WaferAssociation; }
            set { SetProperty(ref _lp1WaferAssociation, value); }
        }
        /// <summary>
        /// LP2的Wafer相关信息
        /// </summary>
        public WaferAssociationInfo LP2WaferAssociation
        {
            get { return _lp2WaferAssociation; }
            set { SetProperty(ref _lp2WaferAssociation, value); }
        }
        /// <summary>
        /// LP3的Wafer相关信息
        /// </summary>
        public WaferAssociationInfo LP3WaferAssociation
        {
            get { return _lp3WaferAssociation; }
            set { SetProperty(ref _lp3WaferAssociation, value); }
        }
        /// <summary>
        /// LP1的Wafer数量
        /// </summary>
        public int LP1WaferCount
        {
            get { return m_LP1WaferCount; }
            set { SetProperty(ref m_LP1WaferCount, value); }
        }
        /// <summary>
        /// LP2的Wafer数量
        /// </summary>
        public int LP2WaferCount
        {
            get { return m_LP2WaferCount; }
            set { SetProperty(ref m_LP2WaferCount, value); }
        }
        /// <summary>
        /// LP3的Wafer数量
        /// </summary>
        public int LP3WaferCount
        {
            get { return m_LP3WaferCount; }
            set { SetProperty(ref m_LP3WaferCount, value); }
        }
        /// <summary>
        /// Sequence数据列表 LP1
        /// </summary>      
        public ObservableCollection<string> SequenceSelectedItemsSource1
        {
            get { return m_SequenceSelectedItemsSource1; }
            set { SetProperty(ref m_SequenceSelectedItemsSource1, value); }
        }
        /// <summary>
        /// Sequence数据列表 LP2
        /// </summary>      
        public ObservableCollection<string> SequenceSelectedItemsSource2
        {
            get { return m_SequenceSelectedItemsSource2; }
            set { SetProperty(ref m_SequenceSelectedItemsSource2, value); }
        }
        /// <summary>
        /// Sequence数据列表 LP3
        /// </summary>      
        public ObservableCollection<string> SequenceSelectedItemsSource3
        {
            get { return m_SequenceSelectedItemsSource3; }
            set { SetProperty(ref m_SequenceSelectedItemsSource3, value); }
        }
        /// <summary>
        /// LP1Sequence名称
        /// </summary>       
        public string LP1SequenceName
        {
            get { return m_LP1SequenceName; }
            set { SetProperty(ref m_LP1SequenceName, value); }
        }
        /// <summary>
        /// LP2Sequence名称
        /// </summary>        
        public string LP2SequenceName
        {
            get { return m_LP2SequenceName; }
            set { SetProperty(ref m_LP2SequenceName, value); }
        }
        /// <summary>
        /// LP3Sequence名称
        /// </summary>        
        public string LP3SequenceName
        {
            get { return m_LP3SequenceName; }
            set { SetProperty(ref m_LP3SequenceName, value); }
        }
        /// <summary>
        /// LP1界面Enable
        /// </summary>
        public bool ButtonIsEnableLP1
        {
            get { return m_ButtonIsEnableLP1; }
            set { SetProperty(ref m_ButtonIsEnableLP1, value); }
        }
        /// <summary>
        /// LP2界面Enable
        /// </summary>
        public bool ButtonIsEnableLP2
        {
            get { return m_ButtonIsEnableLP2; }
            set { SetProperty(ref m_ButtonIsEnableLP2, value); }
        }
        /// <summary>
        /// LP3界面Enable
        /// </summary>
        public bool ButtonIsEnableLP3
        {
            get { return m_ButtonIsEnableLP3; }
            set { SetProperty(ref m_ButtonIsEnableLP3, value); }
        }

        /// <summary>
        /// Created job 按钮可用性
        /// </summary>
        public bool IsLP1CanCreatedJob
        {
            get { return _isLP1CanCreatedJob; }
            set { SetProperty(ref _isLP1CanCreatedJob, value); }
        }
        public bool IsLP2CanCreatedJob
        {
            get { return _isLP2CanCreatedJob; }
            set { SetProperty(ref _isLP2CanCreatedJob, value); }
        }
        public bool IsLP3CanCreatedJob
        {
            get { return _isLP3CanCreatedJob; }
            set { SetProperty(ref _isLP3CanCreatedJob, value); }
        }
        public bool IsLP1AutoStoped
        {
            get { return _isLP1AutoStoped; }
            set { SetProperty(ref _isLP1AutoStoped, value); }
        }
        public bool IsLP2AutoStoped
        {
            get { return _isLP2AutoStoped; }
            set { SetProperty(ref _isLP2AutoStoped, value); }
        }
        public bool IsLP3AutoStoped
        {
            get { return _isLP3AutoStoped; }
            set { SetProperty(ref _isLP3AutoStoped, value); }
        }
        public bool IsLP1AutoStarted
        {
            get { return _isLP1AutoStarted; }
            set { SetProperty(ref _isLP1AutoStarted, value); }
        }
        public bool IsLP2AutoStarted
        {
            get { return _isLP2AutoStarted; }
            set { SetProperty(ref _isLP2AutoStarted, value); }
        }
        public bool IsLP3AutoStarted
        {
            get { return _isLP3AutoStarted; }
            set { SetProperty(ref _isLP3AutoStarted, value); }
        }
        public bool IsLP1Unable
        {
            get { return _isLp1Unable; }
            set { SetProperty(ref _isLp1Unable, value); }
        }
        public bool IsLP2Unable
        {
            get { return _isLp2Unable; }
            set { SetProperty(ref _isLp2Unable, value); }
        }
        public bool IsLP3Unable
        {
            get { return _isLp3Unable; }
            set { SetProperty(ref _isLp3Unable, value); }
        }

        public bool LP1Unable
        {
            get { return _lp1Unable; }
            set { SetProperty(ref _lp1Unable, value); }
        }
        public bool LP2Unable
        {
            get { return _lp2Unable; }
            set { SetProperty(ref _lp2Unable, value); }
        }
        public bool LP3Unable
        {
            get { return _lp3Unable; }
            set { SetProperty(ref _lp3Unable, value); }
        }
        /// <summary>
        /// LP1 RecipeMode(Engineering:true, Production:false)
        /// </summary>
        public bool LP1RecipeMode
        {
            get { return _lp1RecipeMode; }
            set { SetProperty(ref _lp1RecipeMode, value); }
        }
        /// <summary>
        /// LP2 RecipeMode(Engineering:true, Production:false)
        /// </summary>
        public bool LP2RecipeMode
        {
            get { return _lp2RecipeMode; }
            set { SetProperty(ref _lp2RecipeMode, value); }
        }
        /// <summary>
        /// LP3 RecipeMode(Engineering:true, Production:false)
        /// </summary>
        public bool LP3RecipeMode
        {
            get { return _lp3RecipeMode; }
            set { SetProperty(ref _lp3RecipeMode, value); }
        }
        #endregion

        #region 命令
        private DelegateCommand<object> _SelectAllCommand;
        public DelegateCommand<object> SelectAllCommand =>
            _SelectAllCommand ?? (_SelectAllCommand = new DelegateCommand<object>(OnSelectAll));

        private DelegateCommand<object> _UnSelectAllCommand;
        public DelegateCommand<object> UnSelectAllCommand =>
            _UnSelectAllCommand ?? (_UnSelectAllCommand = new DelegateCommand<object>(OnUnSelectAll));

        private DelegateCommand<object> _CreateJobCommand;
        public DelegateCommand<object> CreateJobCommand =>
            _CreateJobCommand ?? (_CreateJobCommand = new DelegateCommand<object>(OnCreateJob));

        private DelegateCommand<object> _AbortJobCommand;
        public DelegateCommand<object> AbortJobCommand =>
            _AbortJobCommand ?? (_AbortJobCommand = new DelegateCommand<object>(OnAbortJob));

        private DelegateCommand<object> _StartCommand;
        public DelegateCommand<object> StartCommand =>
            _StartCommand ?? (_StartCommand = new DelegateCommand<object>(OnStart));

        private DelegateCommand<object> _StopCommand;
        public DelegateCommand<object> StopCommand =>
            _StopCommand ?? (_StopCommand = new DelegateCommand<object>(OnStop));

        private DelegateCommand<object> _AbortCommand;
        public DelegateCommand<object> AbortCommand =>
            _AbortCommand ?? (_AbortCommand = new DelegateCommand<object>(OnAbort));

        private DelegateCommand<object> _SelectionChangedCommand;
        public DelegateCommand<object> SelectionChangedCommand
            =>
            _SelectionChangedCommand ?? (_SelectionChangedCommand = new DelegateCommand<object>(OnSelectionChanged));

        private DelegateCommand<object> _SetSequenceCommand;
        public DelegateCommand<object> SetSequenceCommand =>
           _SetSequenceCommand ?? (_SetSequenceCommand = new DelegateCommand<object>(OnSetSequence));

        private DelegateCommand<object> _LPMapCommand;
        public DelegateCommand<object> LPMapCommand =>
            _LPMapCommand ?? (_LPMapCommand = new DelegateCommand<object>(OnLPMap));
        private DelegateCommand<object> _SeqTypeChangeCommand;
        public DelegateCommand<object> SeqTypeChangeCommand =>
            _SeqTypeChangeCommand ?? (_SeqTypeChangeCommand = new DelegateCommand<object>(OnSeqTypeChange));
        #endregion

        #region 
        /// <summary>
        /// 构造函数
        /// </summary>
        public JobOperationViewModel()
        {
            LP1WaferAssociation = new WaferAssociationInfo();
            LP3WaferAssociation = new WaferAssociationInfo();
            LP2WaferAssociation = new WaferAssociationInfo();

            SequenceSelectedItemsSource1 = new ObservableCollection<string>();
            SequenceSelectedItemsSource2 = new ObservableCollection<string>();
            SequenceSelectedItemsSource3 = new ObservableCollection<string>();
            LP1WaferCount = 0;
            LP2WaferCount = 0;
            LP3WaferCount = 0;

            _LP1SequenceNameBuffer = null;
            _LP2SequenceNameBuffer = null;
            _LP3SequenceNameBuffer = null;

            LP1RecipeMode = true;
            LP2RecipeMode = true;
            LP3RecipeMode = true;
            addDataKeys();
        }
        #endregion

        #region 方法
        /// <summary>
        /// 加载数据
        /// </summary>
        public void LoadData(string systemName)
        {
            if (_timer == null)
            {
                _timer = new DispatcherTimer();
                _timer.Interval = TimeSpan.FromMilliseconds(100);
                _timer.Tick += Timer_Tick; ;
            }
            _timer.Start();
            LP1WaferAssociation.SequenceType = LP1RecipeMode ? "Production" : "Engineering";
            LP2WaferAssociation.SequenceType = LP2RecipeMode ? "Production" : "Engineering";
            LP3WaferAssociation.SequenceType = LP3RecipeMode ? "Production" : "Engineering";
            //获取Sequence列表
            var seqitems1 = RecipeClient.Instance.Service.GetSequenceList("seq", LP1WaferAssociation.SequenceType);
            SequenceSelectedItemsSource1.Clear();
            foreach (var seqitem in seqitems1)
            {
                SequenceSelectedItemsSource1.Add(seqitem);
            }
            var seqitems2 = RecipeClient.Instance.Service.GetSequenceList("seq", LP2WaferAssociation.SequenceType);
            SequenceSelectedItemsSource2.Clear();
            foreach (var seqitem in seqitems2)
            {
                SequenceSelectedItemsSource2.Add(seqitem);
            }
            var seqitems3 = RecipeClient.Instance.Service.GetSequenceList("seq", LP3WaferAssociation.SequenceType);
            SequenceSelectedItemsSource3.Clear();
            foreach (var seqitem in seqitems3)
            {
                SequenceSelectedItemsSource3.Add(seqitem);
            }
        }
        /// <summary>
        /// 隐藏
        /// </summary>
        public void Hide()
        {
            _timer.Stop();
        }
        /// <summary>
        /// 定时器执行
        /// </summary>
        private void Timer_Tick(object sender, EventArgs e)
        {
            LP1WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP1"];
            LP2WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP2"];
            LP3WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP3"];

            IsLP1Unable = !(bool)QueryDataClient.Instance.Service.GetConfig("EFEM.IsLoadPort1Unable") && ButtonIsEnableLP1;
            IsLP2Unable = !(bool)QueryDataClient.Instance.Service.GetConfig("EFEM.IsLoadPort2Unable") && ButtonIsEnableLP2;
            IsLP3Unable = !(bool)QueryDataClient.Instance.Service.GetConfig("EFEM.IsLoadPort3Unable") && ButtonIsEnableLP3;

            LP1Unable = (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.IsLoadPort1Unable");
            LP2Unable = (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.IsLoadPort2Unable");
            LP3Unable = (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.IsLoadPort3Unable");

            RtDataValues = QueryDataClient.Instance.Service.PollData(m_RtDataKeys);
            if (RtDataValues == null || RtDataValues.Count == 0)
            {
                return;
            }

            ControlJobInfo lp1Cj = CommonFunction.GetValue<ControlJobInfo>(RtDataValues, "LP1.CurrentControlJob");
            if (lp1Cj == null)
            {
                ButtonIsEnableLP1 = true;
                LP1WaferAssociation.JobStatus = "";
            }
            else
            {
                ButtonIsEnableLP1 = false;
                UPdateWaferAssociation(LP1WaferAssociation, lp1Cj);
            }
            ControlJobInfo lp2Cj = CommonFunction.GetValue<ControlJobInfo>(RtDataValues, "LP2.CurrentControlJob");
            if (lp2Cj == null)
            {
                ButtonIsEnableLP2 = true;
                LP2WaferAssociation.JobStatus = "";
            }
            else
            {
                ButtonIsEnableLP2 = false;
                UPdateWaferAssociation(LP2WaferAssociation, lp2Cj);
            }
            ControlJobInfo lp3Cj = CommonFunction.GetValue<ControlJobInfo>(RtDataValues, "LP3.CurrentControlJob");
            if (lp3Cj == null)
            {
                ButtonIsEnableLP3 = true;
                LP3WaferAssociation.JobStatus = "";
            }
            else
            {
                ButtonIsEnableLP3 = false;
                UPdateWaferAssociation(LP3WaferAssociation, lp3Cj);
            }

            LP1WaferCount = LP1WaferAssociation.ModuleData.WaferManager.Wafers.Where(x => x.WaferStatus != 0).Count();
            LP2WaferCount = LP2WaferAssociation.ModuleData.WaferManager.Wafers.Where(x => x.WaferStatus != 0).Count();
            LP3WaferCount = LP3WaferAssociation.ModuleData.WaferManager.Wafers.Where(x => x.WaferStatus != 0).Count();

            _isLP1Docked = CommonFunction.GetValue<bool>(RtDataValues, "LP1.IsDocked");
            if (!_isLP1Docked && LP1WaferCount == 0)
            {
                LP1WaferAssociation.SlotFrom = 1;
                LP1WaferAssociation.SlotTo = 25;
                LP1WaferAssociation.LotId = "";
                LP1WaferAssociation.JobID = "";
                LP1SequenceName = null;
                _LP1SequenceNameBuffer = null;
                LP1WaferAssociation.CycleNumber = 1;
                LP1WaferAssociation.IsEnableCycle = false;
                AssociateSequence(LP1WaferAssociation, false);

            }
            _isLP2Docked = CommonFunction.GetValue<bool>(RtDataValues, "LP2.IsDocked");
            if (!_isLP2Docked && LP2WaferCount == 0)
            {
                LP2WaferAssociation.SlotFrom = 1;
                LP2WaferAssociation.SlotTo = 25;
                LP2WaferAssociation.LotId = "";
                LP2WaferAssociation.JobID = "";
                LP2SequenceName = null;
                _LP2SequenceNameBuffer = null;
                LP2WaferAssociation.CycleNumber = 1;
                LP2WaferAssociation.IsEnableCycle = false;
                AssociateSequence(LP2WaferAssociation, false);

            }
            _isLP3Docked = CommonFunction.GetValue<bool>(RtDataValues, "LP3.IsDocked");
            if (!_isLP3Docked && LP3WaferCount == 0)
            {
                LP3WaferAssociation.SlotFrom = 1;
                LP3WaferAssociation.SlotTo = 25;
                LP3WaferAssociation.LotId = "";
                LP3WaferAssociation.JobID = "";
                LP3SequenceName = null;
                _LP3SequenceNameBuffer = null;
                LP3WaferAssociation.CycleNumber = 1;
                LP3WaferAssociation.IsEnableCycle = false;
                AssociateSequence(LP3WaferAssociation, false);

            }
            LP1WaferAssociation.SequenceType = LP1RecipeMode ? "Production" : "Engineering";
            LP2WaferAssociation.SequenceType = LP2RecipeMode ? "Production" : "Engineering";
            LP3WaferAssociation.SequenceType = LP3RecipeMode ? "Production" : "Engineering";


            if ("Executing".Equals(LP1WaferAssociation.JobStatus))
            {
                IsLP1AutoStoped = false;
                IsLP1AutoStarted = true;
            }
            else if ("WaitingForStart".Equals(LP1WaferAssociation.JobStatus))
            {
                IsLP1AutoStoped = true;
                IsLP1AutoStarted = false;
            }
            else if (string.IsNullOrEmpty(LP1WaferAssociation.JobStatus))
            {
                IsLP1AutoStoped = false;
                IsLP1AutoStarted = false;
            }

            if ("Executing".Equals(LP2WaferAssociation.JobStatus))
            {
                IsLP2AutoStoped = false;
                IsLP2AutoStarted = true;
            }
            else if ("WaitingForStart".Equals(LP2WaferAssociation.JobStatus))
            {
                IsLP2AutoStoped = true;
                IsLP2AutoStarted = false;
            }
            else if (string.IsNullOrEmpty(LP2WaferAssociation.JobStatus))
            {
                IsLP2AutoStoped = false;
                IsLP2AutoStarted = false;
            }


            if ("Executing".Equals(LP3WaferAssociation.JobStatus))
            {
                IsLP3AutoStoped = false;
                IsLP3AutoStarted = true;
            }
            else if ("WaitingForStart".Equals(LP3WaferAssociation.JobStatus))
            {
                IsLP3AutoStoped = true;
                IsLP3AutoStarted = false;
            }
            else if (string.IsNullOrEmpty(LP3WaferAssociation.JobStatus))
            {
                IsLP3AutoStoped = false;
                IsLP3AutoStarted = false;
            }


            if (string.IsNullOrEmpty(LP1WaferAssociation.JobStatus))
            {
                IsLP1CanCreatedJob = true;
            }
            else
            {
                IsLP1CanCreatedJob = false;
            }
            if (string.IsNullOrEmpty(LP2WaferAssociation.JobStatus))
            {
                IsLP2CanCreatedJob = true;
            }
            else
            {
                IsLP2CanCreatedJob = false;
            }
            if (string.IsNullOrEmpty(LP3WaferAssociation.JobStatus))
            {
                IsLP3CanCreatedJob = true;
            }
            else
            {
                IsLP3CanCreatedJob = false;
            }



        }
        /// <summary>
        /// 选择所有Wafer
        /// </summary>
        private void OnSelectAll(object obj)
        {
            var info = obj as WaferAssociationInfo;
            var module = info.ModuleData.ModuleID;

            if (CommonFunction.GetValue<bool>(RtDataValues, $"{module}.IsLoaded"))
            {
                info.SlotFrom = 1;
                info.SlotTo = 25;
                AssociateSequence(info, true);
            }

        }
        /// <summary>
        /// 取消选择所有Wafer
        /// </summary>
        private void OnUnSelectAll(object obj)
        {
            var info = obj as WaferAssociationInfo;
            var module = info.ModuleData.ModuleID;
            info.SlotFrom = 1;
            info.SlotTo = 25;
            AssociateSequence(info, false);
        }
        /// <summary>
        /// 创建任务
        /// </summary>
        private void OnCreateJob(object obj)
        {
            var info = obj as WaferAssociationInfo;
            List<string> slotSequence = new List<string>();

            info.ModuleData.WaferManager.Wafers.ForEach(key => { slotSequence.Insert(0, key.SequenceName); });
            if (info.LotId == "" && info.JobID != "") info.LotId = info.JobID;
            if (info.LotId != "" && info.JobID == "") info.JobID = info.LotId;
            info.LotIdSaved = true;

            Dictionary<string, object> param = new Dictionary<string, object>()
            {
                {"JobId", info.JobID},
                {"LotId", info.LotId},
                {"Module", info.ModuleData.ModuleID},
                {"SlotSequence", slotSequence.ToArray()},
                {"AutoStart", true},
                {"CycleNumber",info.CycleNumber},
                {"SequenceType", info.SequenceType}
            };
            if (info.JobID != "" || info.LotId != "")
            {

                InvokeClient.Instance.Service.DoOperation("System.CreateJob", param);
            }
        }
        /// <summary>
        /// 取消任务
        /// </summary>
        private void OnAbortJob(object obj)
        {
            InvokeClient.Instance.Service.DoOperation("System.AbortJob", obj.ToString());
        }
        /// <summary>
        /// 开始
        /// </summary>
        private void OnStart(object obj)
        {
            var info = obj as WaferAssociationInfo;
            InvokeClient.Instance.Service.DoOperation("System.StartJob", info.JobID);
            //LOG.Info("System,Start Job");

        }
        /// <summary>
        /// 停止
        /// </summary>
        private void OnStop(object obj)
        {
            var info = obj as WaferAssociationInfo;
            InvokeClient.Instance.Service.DoOperation("System.StopJob", info.JobID);
            //LOG.Info($"System,Stop Job{info.JobID}");
        }
        /// <summary>
        /// 取消
        /// </summary>
        private void OnAbort(object obj)
        {
            var info = obj as WaferAssociationInfo;
            InvokeClient.Instance.Service.DoOperation("System.AbortJob", info.JobID);
            //LOG.Info($"System,Stop Job{info.JobID}");

        }
        /// <summary>
        /// Sequence Combox的SelectionChanged事件
        /// </summary>
        private void OnSelectionChanged(object obj)
        {
            var moduleName = obj.ToString();
            switch (moduleName)
            {
                case "LP1":
                    if (!string.IsNullOrEmpty(_LP1SequenceNameBuffer) && LP1SequenceName == null) LP1SequenceName = _LP1SequenceNameBuffer;
                    _LP1SequenceNameBuffer = LP1SequenceName;
                    LP1WaferAssociation.SequenceName = LP1SequenceName;
                    break;

                case "LP2":
                    if (!string.IsNullOrEmpty(_LP2SequenceNameBuffer) && LP2SequenceName == null) LP2SequenceName = _LP2SequenceNameBuffer;
                    _LP2SequenceNameBuffer = LP2SequenceName;
                    LP2WaferAssociation.SequenceName = LP2SequenceName;
                    break;

                case "LP3":
                    if (!string.IsNullOrEmpty(_LP3SequenceNameBuffer) && LP3SequenceName == null) LP3SequenceName = _LP3SequenceNameBuffer;
                    _LP3SequenceNameBuffer = LP3SequenceName;
                    LP3WaferAssociation.SequenceName = LP3SequenceName;
                    break;

                default:
                    break;
            }

        }
        /// <summary>
        /// ListBox中设置单个Wafer的Sequence
        /// </summary>
        /// <param name="obj"></param>
        private void OnSetSequence(object obj)
        {
            var info = obj as WaferInfo;
            bool flag = info.SequenceName != "" ? false : true;
            if (info.ModuleID == "LP1" && (CommonFunction.GetValue<bool>(RtDataValues, "LP1.IsLoaded")))
            {
                AssociateSequence(LP1WaferAssociation, flag, info.SlotID);
            }
            else if (info.ModuleID == "LP2" && (CommonFunction.GetValue<bool>(RtDataValues, "LP2.IsLoaded")))
            {
                AssociateSequence(LP2WaferAssociation, flag, info.SlotID);
            }
            else if (info.ModuleID == "LP3" && (CommonFunction.GetValue<bool>(RtDataValues, "LP3.IsLoaded")))
            {
                AssociateSequence(LP3WaferAssociation, flag, info.SlotID);
            }
        }
        /// <summary>
        /// Sequence设置
        /// </summary>
        /// <param name="info"></param>
        /// <param name="flag"></param>
        /// <param name="slot"></param>
        private void AssociateSequence(WaferAssociationInfo info, bool flag, int slot = -1)
        {
            List<WaferInfo> wafers = info.ModuleData.WaferManager.Wafers;

            if (slot >= 0) //by wafer
            {
                int index = wafers.Count - slot - 1;
                if (index < wafers.Count)
                {
                    if (flag && HasWaferOnSlot(wafers, index))
                        wafers[index].SequenceName = info.SequenceName;
                    else
                        wafers[index].SequenceName = string.Empty;
                }
            }
            else //by from-to
            {
                for (int i = info.SlotFrom - 1; i < info.SlotTo; i++)
                {
                    int index = wafers.Count - i - 1;
                    if (index < wafers.Count)
                    {
                        if (flag && HasWaferOnSlot(wafers, index))
                            wafers[index].SequenceName = info.SequenceName;
                        else
                            wafers[index].SequenceName = string.Empty;
                    }
                }
            }

            switch (info.ModuleData.ModuleID)
            {
                case "LP1":
                    LP1WaferAssociation = info;
                    break;
                case "LP2":
                    LP2WaferAssociation = info;
                    break;
                case "LP3":
                    LP3WaferAssociation = info;
                    break;
            }
        }
        /// <summary>
        /// 检查Slot中的Wafer是否存在
        /// </summary>
        /// <param name="wafers"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private bool HasWaferOnSlot(List<WaferInfo> wafers, int index)
        {
            if (wafers[index].WaferStatus == 0)
                return false;

            return true;
        }
        /// <summary>
        /// 添加RT查询key
        /// </summary>
        private void addDataKeys()
        {
            m_RtDataKeys.Add("LP1.IsLoaded");
            m_RtDataKeys.Add("LP2.IsLoaded");
            m_RtDataKeys.Add("LP3.IsLoaded");
            m_RtDataKeys.Add("LP1.CassettePlaced");
            m_RtDataKeys.Add("LP2.CassettePlaced");
            m_RtDataKeys.Add("LP3.CassettePlaced");
            m_RtDataKeys.Add("LP1.CurrentControlJob");
            m_RtDataKeys.Add("LP2.CurrentControlJob");
            m_RtDataKeys.Add("LP3.CurrentControlJob");

            m_RtDataKeys.Add("System.IsAutoMode");
            m_RtDataKeys.Add("System.IsBusy");

            m_RtDataKeys.Add("LP1.CycledCount");
            m_RtDataKeys.Add("LP1.CycledWafer");
            m_RtDataKeys.Add("LP1.CycleSetPoint");
            m_RtDataKeys.Add("LP1.Throughput");

            m_RtDataKeys.Add("LP2.CycledCount");
            m_RtDataKeys.Add("LP2.CycledWafer");
            m_RtDataKeys.Add("LP2.CycleSetPoint");
            m_RtDataKeys.Add("LP2.Throughput");

            m_RtDataKeys.Add("LP3.CycledCount");
            m_RtDataKeys.Add("LP3.CycledWafer");
            m_RtDataKeys.Add("LP3.CycleSetPoint");
            m_RtDataKeys.Add("LP3.Throughput");

            m_RtDataKeys.Add("LP1.IsDocked");
            m_RtDataKeys.Add("LP2.IsDocked");
            m_RtDataKeys.Add("LP3.IsDocked");

            m_RtDataKeys.Add("LP1.WaferSize");
            m_RtDataKeys.Add("LP2.WaferSize");
            m_RtDataKeys.Add("LP3.WaferSize");

        }
        /// <summary>
        /// 更新Wafer情况
        /// </summary>
        /// <param name="info"></param>
        /// <param name="cjInfo"></param>
        private void UPdateWaferAssociation(WaferAssociationInfo info, ControlJobInfo cjInfo)
        {
            if (info == null)
            {
                return;
            }
            if (cjInfo != null)
            {
                info.LotId = cjInfo.LotName;
                info.JobID = cjInfo.Name;
                info.JobStatus = cjInfo.State.ToString();
                if (cjInfo.SequenceNameList != null)
                {
                    for (int i = 0; i < cjInfo.SequenceNameList.Length; i++)
                    {
                        info.ModuleData.WaferManager.Wafers[24 - i].SequenceName = cjInfo.SequenceNameList[i];
                    }
                }

            }
            else
            {
                if (!string.IsNullOrEmpty(info.JobID))
                {
                    info.LotId = "";
                    info.JobID = "";
                    info.JobStatus = "";
                    AssociateSequence(info, false);
                }
            }
        }
        private void OnLPMap(object obj)
        {
            InvokeClient.Instance.Service.DoOperation($"{obj.ToString()}.Map");

        }
        private void OnSeqTypeChange(object obj)
        {
            var info = obj as WaferAssociationInfo;
            //获取Sequence列表
            List<string> seqitems;

            switch (info.ModuleData.ModuleID)
            {
                case "LP1":
                    info.SequenceType = LP1RecipeMode ? "Production" : "Engineering";
                    seqitems = RecipeClient.Instance.Service.GetSequenceList("seq", info.SequenceType);
                    SequenceSelectedItemsSource1.Clear();
                    foreach (var seqitem in seqitems)
                    {
                        SequenceSelectedItemsSource1.Add(seqitem);
                    }

                    break;
                case "LP2":
                    info.SequenceType = LP2RecipeMode ? "Production" : "Engineering";
                    seqitems = RecipeClient.Instance.Service.GetSequenceList("seq", info.SequenceType);
                    SequenceSelectedItemsSource2.Clear();
                    foreach (var seqitem in seqitems)
                    {
                        SequenceSelectedItemsSource2.Add(seqitem);
                    }
                    break;
                case "LP3":
                    info.SequenceType = LP3RecipeMode ? "Production" : "Engineering";
                    seqitems = RecipeClient.Instance.Service.GetSequenceList("seq", info.SequenceType);
                    SequenceSelectedItemsSource3.Clear();
                    foreach (var seqitem in seqitems)
                    {
                        SequenceSelectedItemsSource3.Add(seqitem);
                    }
                    break;
                default:
                    break;
            }
        }
        #endregion
    }
}