using Aitex.Core.Util;
using Aitex.Sorter.Common;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using Caliburn.Micro;
using MECF.Framework.UI.Client.CenterViews.Operations.WaferAssociation;
using MECF.Framework.UI.Client.ClientBase;
using OpenSEMI.ClientBase;
using System;
using SicUI.Controls;
using System.Data;
using Aitex.Core.RT.Event;
using System.Dynamic;
using Caliburn.Micro.Core;
using MECF.Framework.Common.Account;
using MECF.Framework.Common.Account.Permissions;
using MECF.Framework.UI.Core.Accounts;

namespace SicUI.Models.Operations.Overviews
{
    public class JobListInfo : NotifiableItem
    {
        public int Index { get; set; }
        public string JobName { get; set; }
        public string WaferID { get; set; }
        public string LotName { get; set; }

        private string _status;
        public string Status
        {
            get { return _status; }
            set
            {
                _status = value;
                InvokePropertyChanged();
            }
        }

        private string _currentPosition;
        public string CurrentPosition
        {
            get { return _currentPosition; }
            set
            {
                _currentPosition = value;
                InvokePropertyChanged();
            }
        }
        public string CreateTime { get; set; }
        public string RecipeName { get; set; }
    }

    public class OverViewViewModel : SicUIViewModelBase, IHandle<ShowCloseMonitorWinEvent>, IHandle<UserMode>
    {
        private R_TRIG _manulAbort = new R_TRIG();
        private R_TRIG _loadLockJobDone = new R_TRIG();
        private R_TRIG _moduleOffLineTimeout = new R_TRIG();
        private int _scModuleOfflineTimeout = 60;
        private int _offlineTimes = 0;
        private bool _systemAbort = false;

        #region Property   
        public ObservableCollection<JobListInfo> JobListInfoData { get; set; }

        public WaferAssociationInfo LoadWaferAssociation { get; set; }

        public bool IsPM1Installed { get; set; }
        public bool IsPM2Installed { get; set; }
        public bool IsBufferInstalled { get; set; }
        public bool IsLoadLockInstalled { get; set; }
        public bool IsUnLoadInstalled { get; set; }
        public bool IsTMInstalled { get; set; }

        #region Mainframe
        [Subscription("LoadLock.JobDone")]
        public bool LoadLockJobDone { get; set; }

        [Subscription("TMRobot.RobotMoveInfo")]
        public RobotMoveInfo TmRobotMoveInfo
        {
            get;
            set;
        }

        public FoupDoorState PM1DoorState
        {
            get
            {
                if (PM1SlitValveOpenFeedback && !PM1SlitValveCloseFeedback) return FoupDoorState.Open;
                if (!PM1SlitValveOpenFeedback && PM1SlitValveCloseFeedback) return FoupDoorState.Close;

                return FoupDoorState.Unknown;
            }
        }

        public FoupDoorState PM2DoorState
        {
            get
            {
                if (PM2SlitValveOpenFeedback && !PM2SlitValveCloseFeedback) return FoupDoorState.Open;
                if (!PM2SlitValveOpenFeedback && PM2SlitValveCloseFeedback) return FoupDoorState.Close;

                return FoupDoorState.Unknown;
            }
        }

        public FoupDoorState LLDoorState
        {
            get
            {
                if (LLDoorOpenFeedback && !LLDoorCloseFeedback) return FoupDoorState.Open;
                if (!LLDoorOpenFeedback && LLDoorCloseFeedback) return FoupDoorState.Close;

                return FoupDoorState.Unknown;
            }
        }

        public FoupDoorState BufferDoorState
        {
            get
            {
                {
                    if (BufferDoorOpenFeedback && !BufferDoorCloseFeedback) return FoupDoorState.Open;
                    if (!BufferDoorOpenFeedback && BufferDoorCloseFeedback) return FoupDoorState.Close;
                }

                return FoupDoorState.Unknown;
            }
        }

        public bool IsLLDoorOpen => LLDoorState == FoupDoorState.Open ? true : false;
        public bool IsBufferDoorOpen => true;
        public bool IsPM1DoorOpen => PM1DoorState == FoupDoorState.Open ? true : false;
        public bool IsPM2DoorOpen => PM2DoorState == FoupDoorState.Open ? true : false;

        public Visibility IsPM1Water
        {
            get
            {
                if (PM1Wafer != null && JobListInfoData != null)
                {
                    for (int i = 0; i < JobListInfoData.Count; i++)
                    {
                        if (JobListInfoData[i].WaferID == PM1Wafer.WaferID)
                        {
                            JobListInfoData[i].Status = GetWaferStatue(PM1Wafer.WaferStatus);
                            JobListInfoData[i].CurrentPosition = "PM1";
                        }
                    }
                }
                return PM1Wafer == null ? Visibility.Hidden : PM1Wafer.IsVisibility;
            }
        }
        public Visibility IsPM2Water
        {
            get
            {
                if (PM2Wafer != null && JobListInfoData != null)
                {
                    for (int i = 0; i < JobListInfoData.Count; i++)
                    {
                        if (JobListInfoData[i].WaferID == PM2Wafer.WaferID)
                        {
                            JobListInfoData[i].Status = GetWaferStatue(PM2Wafer.WaferStatus);
                            JobListInfoData[i].CurrentPosition = "PM2";
                        }
                    }
                }
                return PM2Wafer == null ? Visibility.Hidden : PM2Wafer.IsVisibility;
            }
        }

        public Visibility IsLLWater
        {
            get
            {
                if (LoadLockWafer != null && JobListInfoData != null)
                {
                    for (int i = 0; i < JobListInfoData.Count; i++)
                    {
                        if (JobListInfoData[i].WaferID == LoadLockWafer.WaferID)
                        {
                            JobListInfoData[i].Status = GetWaferStatue(LoadLockWafer.WaferStatus);
                            JobListInfoData[i].CurrentPosition = "LoadLock";
                        }
                    }
                }
                return LoadLockWafer == null ? Visibility.Hidden : LoadLockWafer.IsVisibility;
            }
        }

        public Visibility IsBufferWater
        {
            get
            {
                if (BufferWafer != null && JobListInfoData != null)
                {
                    for (int i = 0; i < JobListInfoData.Count; i++)
                    {
                        if (JobListInfoData[i].WaferID == BufferWafer.WaferID)
                        {
                            JobListInfoData[i].Status = GetWaferStatue(BufferWafer.WaferStatus);
                            JobListInfoData[i].CurrentPosition = "Buffer";
                        }
                    }
                }
                return BufferWafer == null ? Visibility.Hidden : BufferWafer.IsVisibility;
            }
        }

        public Visibility IsArmWater
        {
            get
            {
                if (TMRobotWafer1 != null && JobListInfoData != null)
                {
                    for (int i = 0; i < JobListInfoData.Count; i++)
                    {
                        if (JobListInfoData[i].WaferID == TMRobotWafer1.WaferID)
                        {
                            //JobListInfoData[i].Status = MECF.Framework.Common.SubstrateTrackings.WaferManager.Instance.AllLocationWafers[MECF.Framework.Common.Equipment.ModuleName.TMRobot][0].ProcessState.ToString();
                            JobListInfoData[i].CurrentPosition = "TM";
                        }
                    }
                }
                return TMRobotWafer1 == null ? Visibility.Hidden : TMRobotWafer1.IsVisibility;
            }
        }
        public Visibility IsUnloadWater
        {
            get
            {
                if (UnLoadWafer != null && JobListInfoData != null)
                {
                    for (int i = 0; i < JobListInfoData.Count; i++)
                    {
                        if (JobListInfoData[i].WaferID == UnLoadWafer.WaferID)
                        {
                            JobListInfoData[i].CurrentPosition = "Unload";
                        }
                    }
                }
                return UnLoadWafer == null ? Visibility.Hidden : UnLoadWafer.IsVisibility;
            }
        }

        private string GetWaferStatue(int status)
        {
            if (status == 3)
            {
                return "InProcess";
            }
            else if (status == 7 || status == 4)
            {
                return "Completed";
            }
            else if (status == 3)
            {
                return "Wait";
            }
            else if (status == 5)
            {
                return "Failed";
            }
            else
            {
                return "Idle";
            }
        }

        [Subscription("TM.PM1Door.OpenFeedback")]
        public bool PM1SlitValveOpenFeedback { get; set; }

        [Subscription("TM.PM1Door.CloseFeedback")]
        public bool PM1SlitValveCloseFeedback { get; set; }

        [Subscription("TM.PM2Door.OpenFeedback")]
        public bool PM2SlitValveOpenFeedback { get; set; }

        [Subscription("TM.PM2Door.CloseFeedback")]
        public bool PM2SlitValveCloseFeedback { get; set; }

        [Subscription("TM.BufferDoor.OpenFeedback")]
        public bool BufferDoorOpenFeedback { get; set; }

        [Subscription("TM.BufferDoor.CloseFeedback")]
        public bool BufferDoorCloseFeedback { get; set; }

        [Subscription("TM.LoadLockDoor.OpenFeedback")]
        public bool LLDoorOpenFeedback { get; set; }

        [Subscription("TM.LoadLockDoor.CloseFeedback")]
        public bool LLDoorCloseFeedback { get; set; }


        [Subscription("TM.TMPressure.Value")]
        public float TMPressure { get; set; }

        [Subscription("TM.LLPressure.Value")]
        public double LLPressure { get; set; }

        [Subscription("Buffer.BufferTemp.FeedBack")]
        public float BufferTemp { get; set; }


        [Subscription("LoadLock.LLLidClosed.Value")]
        public bool LLLidClosed { get; set; }

        [Subscription("TM.UnLoadPressure.Value")]
        public double UnLoadPressure { get; set; }

        //public bool IsEnableJobLP1
        //{
        //    get { return IsAuto; }
        //}

        public bool IsEnableJobLP1
        {
            get { return true; }
        }
        #endregion

        #region PM1

        [Subscription("PM1.Status")]
        public string PM1Status { get; set; }
        public string PM1StatusBackground
        {
            get { return ModuleStatusBackground.GetStatusBackground(PM1Status); }
        }

        public string PM1SelectedRecipe { get; set; }
        private string PM1SelectedRecipePath { get; set; }


        [Subscription("PM1.RecipeTotalElapseTime")]
        public int PM1RecipeTotalElapseTime { get; set; }

        public string ElapseTimePM1 => PM1Wafer != null && PM1Wafer.WaferStatus == 3 ? PM1RecipeTotalElapseTime.ToString() : "--";

        [Subscription("PM1.RecipeTotalTime")]
        public int PM1RecipeTotalTime { get; set; }
        public string TotalTimePM1 => PM1Wafer != null && PM1Wafer.WaferStatus == 3 ? PM1RecipeTotalTime.ToString() : "--";

        [Subscription("PM1.PT1.FeedBack")]
        public double PM1Pressure { get; set; }


        [Subscription("PM1.IsOnline")]
        public bool PM1IsOnline { get; set; }

        public bool PM1IsOffline
        {
            get { return !PM1IsOnline; }
        }

        [Subscription("TM.IsOnline")]
        public bool TMIsOnline { get; set; }

        [Subscription("Buffer.IsOnline")]
        public bool BufferIsOnline { get; set; }

        [Subscription("LoadLock.IsOnline")]
        public bool LoadLockIsOnline { get; set; }


        [Subscription("PM1.ConfinementRing.RingUpSensor")]
        public bool PM1ConfinementRingUpSensor { get; set; }

        [Subscription("PM1.ConfinementRing.RingDownSensor")]
        public bool PM1ConfinementRingDwonSensor { get; set; }

        public string PM1ConfinementState
        {
            get
            {
                if (PM1ConfinementRingUpSensor && !PM1ConfinementRingDwonSensor)
                {
                    return "Up";
                }
                else if (!PM1ConfinementRingUpSensor && PM1ConfinementRingDwonSensor)
                {
                    return "Down";
                }
                else
                {
                    return "Unknown";
                }
            }
        }
        #endregion

        #region PM2

        [Subscription("PM2.Status")]
        public string PM2Status { get; set; }
        public string PM2StatusBackground
        {
            get { return ModuleStatusBackground.GetStatusBackground(PM2Status); }
        }

        public string PM2SelectedRecipe { get; set; }
        private string PM2SelectedRecipePath { get; set; }


        [Subscription("PM2.RecipeTotalElapseTime")]
        public int PM2RecipeTotalElapseTime { get; set; }

        public string ElapseTimePM2 => PM2Wafer != null && PM2Wafer.WaferStatus == 3 ? PM2RecipeTotalElapseTime.ToString() : "--";

        [Subscription("PM2.RecipeTotalTime")]
        public int PM2RecipeTotalTime { get; set; }
        public string TotalTimePM2 => PM2Wafer != null && PM2Wafer.WaferStatus == 3 ? PM2RecipeTotalTime.ToString() : "--";

        [Subscription("PM2.PT1.FeedBack")]
        public double PM2Pressure { get; set; }


        [Subscription("PM2.IsOnline")]
        public bool PM2IsOnline { get; set; }

        public bool PM2IsOffline
        {
            get { return !PM2IsOnline; }
        }

        [Subscription("PM2.ConfinementRing.RingUpSensor")]
        public bool PM2ConfinementRingUpSensor { get; set; }

        [Subscription("PM2.ConfinementRing.RingDownSensor")]
        public bool PM2ConfinementRingDwonSensor { get; set; }

        public string PM2ConfinementState
        {
            get
            {
                if (PM2ConfinementRingUpSensor && !PM2ConfinementRingDwonSensor)
                {
                    return "Up";
                }
                else if (!PM2ConfinementRingUpSensor && PM2ConfinementRingDwonSensor)
                {
                    return "Down";
                }
                else
                {
                    return "Unknown";
                }
            }
        }
        #endregion

        #region Scheduler

        public bool IsRtInitialized
        {
            get
            {
                return RtStatus != "Init" && RtStatus != "Initializing";
            }
        }

        public bool IsRtRunning
        {
            get
            {
                return RtStatus != "Init" && RtStatus != "Idle";
            }
        }

        public bool IsAuto
        {
            get { return RtStatus == "AutoRunning" || RtStatus == "AutoIdle"; }
        }

        public string RunningMode => IsAuto ? "Auto" : "Manual";

        [Subscription("Rt.Status")]
        public string RtStatus { get; set; }

        [Subscription("Scheduler.IsCycleMode")]
        public bool IsCycleMode { get; set; }

        [Subscription("Scheduler.CycledCount")]
        public int CycledCount { get; set; }  //当前次数

        public int CurrentCycle
        {
            get
            {
                if (CycleSetPoint <= 0)
                {
                    return 0;
                }
                else if (CycledCount + 1 > CycleSetPoint)
                {
                    return CycleSetPoint;
                }
                else
                {
                    return CycledCount + 1;
                }
            }
        }

        [Subscription("Scheduler.CycleSetPoint")]
        public int CycleSetPoint { get; set; }  //总次数

        [Subscription("LoadLock.LocalJobName")]
        public string LoadLockJobName { get; set; }

        [Subscription("LoadLock.LocalJobStatus")]
        public string LoadLockJobStatus { get; set; }
        #endregion

        #region Buffer
        [Subscription("Scheduler.TimeBuffer1")]
        public double TimeBuffer1 { get; set; }

        [Subscription("Scheduler.TimeBuffer2")]
        public double TimeBuffer2 { get; set; }

        [Subscription("Scheduler.TimeBuffer3")]
        public double TimeBuffer3 { get; set; }

        [Subscription("LoadLock.IsOnline")]
        public bool LoadIsOnline { get; set; }

        [Subscription("UnLoad.IsOnline")]
        public bool UnLoadIsOnline { get; set; }

        private string _gemPPID;
        [Subscription("GEM.PPID")]
        public string GEM_PPID
        {
            get
            {
                return _gemPPID;
            }
            set
            {
                if (_gemPPID != value)
                {
                    LoadWaferAssociation.SequenceName = value;
                }

                _gemPPID = value;
            }
        }

        private string _gemLotID;
        [Subscription("GEM.LotID")]
        public string GEM_LotID
        {
            get
            {
                return _gemLotID;
            }
            set
            {
                if (_gemLotID != value)
                {
                    LoadWaferAssociation.LotId = value;
                }

                _gemLotID = value;
            }
        }

        #endregion

        #region Button Logic



        public bool PM1EnableWaferClick => !PM1IsOnline || RtStatus == "Idle";

        public bool PM2EnableWaferClick => !PM2IsOnline || RtStatus == "Idle";

        public bool LLEnableWaferClick => !LoadIsOnline || RtStatus == "Idle";

        public bool UnLoadEnableWaferClick => !UnLoadIsOnline || RtStatus == "Idle";

        public bool BufferEnableWaferClick => !BufferIsOnline || RtStatus == "Idle";

        public bool TMEnableWaferClick => !TMIsOnline || RtStatus == "Idle";

        public bool EnableWaferClick => RtStatus == "Idle";


        public bool IsEnableAbort
        {
            get
            {
                //if (IsAuto)
                //    return !string.IsNullOrEmpty(LoadLockJobStatus);

                return IsRtRunning;
            }
        }

        public bool IsEnableAuto
        {
            get { return !IsAuto && IsRtInitialized; }
        }

        public bool IsEnableManual
        {
            get { return IsAuto && IsRtInitialized; }
        }

        public bool IsEnableInitialize
        {
            get { return !IsAuto && !IsRtRunning; }
        }


        public bool IsEnableReturnAll
        {
            get { return !IsAuto && IsRtInitialized && RtStatus == "Idle"; }
        }

        #endregion

        #endregion

        public OverViewViewModel()
        {
            this.DisplayName = "OverViewViewModel";
            ActiveUpdateData = true;
        }

        protected override void OnInitialize()
        {
            base.OnInitialize();

            InitLL();
            InitTM();
            InitPM();

            LoadWaferAssociation = new WaferAssociationInfo();
            LoadWaferAssociation.ModuleData = ModuleManager.ModuleInfos["LoadLock"];

            IsPM1Installed = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsPM1Installed");
            IsPM2Installed = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsPM2Installed");
            IsBufferInstalled = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsBufferInstalled");
            IsLoadLockInstalled = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsLoadLockInstalled");
            IsTMInstalled = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsTMInstalled");
            //IsUnLoadInstalled = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.IsUnLoadInstalled");
            IsUnLoadInstalled = true;
        }
        public Visibility ProcessMonitorButtonVisibility { get; private set; }
        protected override void OnActivate()
        {
            var roleID = BaseApp.Instance.UserContext.Role.RoleId;
            var allowProcessMonitorWin = RoleAccountProvider.Instance.GetMenuPermission(roleID, "Operation.Overview.ProcessMonitorWindow") != (int)MenuPermissionEnum.MP_NONE;
            ProcessMonitorButtonVisibility = allowProcessMonitorWin ? Visibility.Visible : Visibility.Collapsed;

            base.OnActivate();
        }

        protected override void Poll()
        {
            base.Poll();
            PM1SelectedRecipePath = (string)QueryDataClient.Instance.Service.GetConfig($"PM.PM1.LastRecipeName");
            PM2SelectedRecipePath = (string)QueryDataClient.Instance.Service.GetConfig($"PM.PM2.LastRecipeName");

            if (!string.IsNullOrEmpty(PM1SelectedRecipePath))
            {
                var array = PM1SelectedRecipePath.Split(new char[] { '\\' });

                if (PM1SelectedRecipe != array[array.Length - 1])
                {
                    PM1SelectedRecipe = array[array.Length - 1];
                }
            }

            if (!string.IsNullOrEmpty(PM2SelectedRecipePath))
            {
                var array = PM2SelectedRecipePath.Split(new char[] { '\\' });

                if (PM2SelectedRecipe != array[array.Length - 1])
                {
                    PM2SelectedRecipe = array[array.Length - 1];
                }
            }
        }

        public void ReturnAllWafer()
        {
            InvokeClient.Instance.Service.DoOperation("System.ReturnAllWafer");
        }

        protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
        {
            if (LoadWaferAssociation == null)
            {
                LoadWaferAssociation = new WaferAssociationInfo();
                LoadWaferAssociation.ModuleData = ModuleManager.ModuleInfos["LoadLock"];
            }

            LoadWaferAssociation.JobID = LoadLockJobName;
            LoadWaferAssociation.JobStatus = LoadLockJobStatus;

            GetJobList();

            _loadLockJobDone.CLK = LoadLockJobDone && (!IsCycleMode || (IsCycleMode && CycledCount >= CycleSetPoint));
            if (_loadLockJobDone.Q)
            {
                EV.PostInfoLog("System", "Process completed.Please take away the wafer.");

                //Buzzer,报警次数，每次间隔，每次持续时间
                //SwitchOffBuzzerEx("3", "1500", "2000");
            }

            _manulAbort.CLK = _systemAbort;
            if (_manulAbort.Q)
            {
                EV.PostWarningLog("System", "Process aborted.Please take away the wafer.");
                _systemAbort = false;
            }

            if (RtStatus == "AutoRunning")
            {
                if (!TMIsOnline || !BufferIsOnline || !LoadLockIsOnline)
                {
                    _offlineTimes++;
                }
                else
                {
                    _offlineTimes = 0;
                }

                _moduleOffLineTimeout.CLK = _offlineTimes > _scModuleOfflineTimeout && _offlineTimes < _scModuleOfflineTimeout + 5;
                if (_moduleOffLineTimeout.Q)
                {
                    EV.PostWarningLog("System", $"Module is in offline status over {_scModuleOfflineTimeout} seconds.");
                }
            }
        }

        #region OverView Operation

        public void HomeAll()
        {
            WindowManager wm = new WindowManager();

            var workenable = (bool)QueryDataClient.Instance.Service.GetConfig("System.MultiProcessMode");
            if (workenable)
            {
                var isConnect = (bool)QueryDataClient.Instance.Service.GetData("MultiProcessClient.IsConnected");
                if (!isConnect)
                {
                    var infos = "MultiProcessClient Disconnected";
                    ChooseDialogBoxViewModel dialog2 = new ChooseDialogBoxViewModel();
                    dialog2.DisplayName = "MultiProcess Info";
                    dialog2.InfoStr = infos;
                    wm.ShowDialog(dialog2);
                    return;
                }
                else
                {
                    var infos = (string)QueryDataClient.Instance.Service.GetData("MultiProcessClient.ServiceInfo");
                    ChooseDialogBoxViewModel dialog2 = new ChooseDialogBoxViewModel();
                    dialog2.DisplayName = "MultiProcess Info";
                    dialog2.InfoStr = infos;
                    bool? bret = wm.ShowDialog(dialog2);
                    if (!bret.HasValue || !bret.Value)
                    {
                        return;
                    }
                }
            }
                
            InvokeClient.Instance.Service.DoOperation("System.HomeAll");
        }

        public void Abort()
        {
            if (RtStatus == "AutoRunning")
            {
                _systemAbort = true;
            }
            InvokeClient.Instance.Service.DoOperation("System.Abort");
        }

        public void Auto()
        {
            ChooseDialogBoxViewModel dialog = new ChooseDialogBoxViewModel();
            dialog.DisplayName = "Tips";
            dialog.InfoStr = "Please Check All Gas  Ready Before Start Process!";

            WindowManager wm = new WindowManager();
            bool? bret = wm.ShowDialog(dialog);
            if (!bret.HasValue || !bret.Value)
            {
                return;
            }

            var workenable = (bool)QueryDataClient.Instance.Service.GetConfig("System.MultiProcessMode");
            if (workenable)
            {
                var isConnect = (bool)QueryDataClient.Instance.Service.GetData("MultiProcessClient.IsConnected");
                if (!isConnect)
                {
                    var infos = "MultiProcessClient Disconnected";
                    ChooseDialogBoxViewModel dialog2 = new ChooseDialogBoxViewModel();
                    dialog2.DisplayName = "MultiProcess Info";
                    dialog2.InfoStr = infos;
                    wm.ShowDialog(dialog2);
                    return;
                }
                else
                {
                    var infos = (string)QueryDataClient.Instance.Service.GetData("MultiProcessClient.ServiceInfo");
                    ChooseDialogBoxViewModel dialog2 = new ChooseDialogBoxViewModel();
                    dialog2.DisplayName = "MultiProcess Info";
                    dialog2.InfoStr = infos;
                    bret = wm.ShowDialog(dialog2);
                    if (!bret.HasValue || !bret.Value)
                    {
                        return;
                    }
                }
            }
                

            //传入SequenceName
            InvokeClient.Instance.Service.DoOperation("System.SetAutoMode");

            JobListInfoData = new ObservableCollection<JobListInfo>();
        }

        public void Manual()
        {
            InvokeClient.Instance.Service.DoOperation("System.SetManualMode");
        }

        #endregion

        #region Wafer association
        #region Sequence operation
        public void SelectSequence(WaferAssociationInfo info)
        {
            SequenceDialogViewModel dialog = new SequenceDialogViewModel();
            dialog.DisplayName = "Select Sequence";

            dialog.Files = new ObservableCollection<FileNode>(RecipeSequenceTreeBuilder.GetFiles("",
                RecipeClient.Instance.Service.GetSequenceNameList()
            ));

            WindowManager wm = new WindowManager();
            bool? bret = wm.ShowDialog(dialog);
            if ((bool)bret)
            {
                info.SequenceName = dialog.DialogResult;
            }
        }

        public void SetSlot(WaferAssociationInfo info)
        {
            if (InputSlotCheck(info.SlotFrom, info.SlotTo))
                AssociateSequence(info, true);
        }

        public void SkipSlot(WaferAssociationInfo info)
        {
            if (InputSlotCheck(info.SlotFrom, info.SlotTo))
                AssociateSequence(info, false);
        }

        public void SetAll(WaferAssociationInfo info)
        {
            info.SlotFrom = 1;
            info.SlotTo = 25;
            AssociateSequence(info, true);
        }

        public void DeselectAll(WaferAssociationInfo info)
        {
            info.SlotFrom = 1;
            info.SlotTo = 25;
            AssociateSequence(info, false);
        }

        public void SetSequence(WaferAssociationInfo info, int slotIndex, string seqName)
        {
            bool flag = string.IsNullOrEmpty(seqName);
            AssociateSequence(info, flag, slotIndex - 1);
        }

        private bool InputSlotCheck(int from, int to)
        {
            if (from > to)
            {
                DialogBox.ShowInfo("This index of from slot should be large than the index of to slot.");
                return false;
            }
            if (from < 1 || to > 25)
            {
                DialogBox.ShowInfo("This input value for from should be between 1 and 25.");
                return false;
            }
            return true;
        }

        private void AssociateSequence(WaferAssociationInfo info, bool flag, int slot = -1)
        {
            ObservableCollection<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.ToList(), 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.ToList(), index))
                            wafers[index].SequenceName = info.SequenceName;
                        else
                            wafers[index].SequenceName = string.Empty;
                    }
                }
            }
        }

        private bool HasWaferOnSlot(List<WaferInfo> wafers, int index)
        {
            if (wafers[index].WaferStatus == 0)
                return false;

            return true;
        }
        #endregion

        #region Job operation
        private int _jobRefreashTime = 5;
        private void GetJobList()
        {
            _jobRefreashTime++;
            if (_jobRefreashTime < 5)
            {
                return;
            }
            if (_jobRefreashTime > 5)
            {
                _jobRefreashTime = 0;
            }

            if (JobListInfoData == null)
            {
                JobListInfoData = new ObservableCollection<JobListInfo>();
            }

            string sql = $"SELECT guid, wafer_guid, start_time, end_time, recipe_name, lot_name, current_position, status FROM public.autojob_data where start_time>'" + DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd HH:mm:ss") + "' order by start_time asc;";
            DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
            if (dbData != null && dbData.Rows.Count > 0)
            {
                JobListInfoData = new ObservableCollection<JobListInfo>();

                for (int i = 0; i < dbData.Rows.Count; i++)
                {
                    JobListInfo item = new JobListInfo()
                    {
                        Index = i + 1,
                        RecipeName = dbData.Rows[i]["recipe_name"].ToString(),
                        LotName = dbData.Rows[i]["lot_name"].ToString(),
                        Status = dbData.Rows[i]["status"].ToString(),
                        CurrentPosition = dbData.Rows[i]["current_position"].ToString(),
                        CreateTime = dbData.Rows[i]["start_time"].ToString(),
                        WaferID = dbData.Rows[i]["wafer_guid"].ToString(),
                        JobName = dbData.Rows[i]["guid"].ToString(),
                    };

                    bool haveInfo = false;
                    foreach (var info in JobListInfoData)
                    {
                        if (info.WaferID == item.WaferID && info.CreateTime == item.CreateTime)
                        {
                            haveInfo = true;
                            break;
                        }
                    }

                    if (!haveInfo)
                    {
                        JobListInfoData.Insert(0, item);
                    }
                }
            }
        }

        private bool JobCheck(string jobID)
        {
            if (jobID.Length == 0)
            {
                DialogBox.ShowWarning("Please create job first.");
                return false;
            }

            return true;
        }

        public void CreateJob(WaferAssociationInfo info, out string jobID)
        {
            jobID = "";

            if (LoadWaferAssociation.LotId == "")
            {
                LoadWaferAssociation.LotId = "LoadLock.01";
            }

            List<string> slotSequence = new List<string>();
            foreach (var wafer in info.ModuleData.WaferManager.Wafers)
            {
                if (wafer.WaferStatus == 1)
                {
                    wafer.SequenceName = LoadWaferAssociation.SequenceName;
                    wafer.LotID = LoadWaferAssociation.LotId;
                    slotSequence.Insert(0, wafer.SequenceName);
                }
            }

            if (slotSequence.Count > 0)
            {
                if (string.IsNullOrEmpty(jobID))
                {
                    jobID = "CJ_Local_Load_" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                }
                   
                info.LotIdSaved = true;
                WaferAssociationProvider.Instance.CreateJob(jobID, info.ModuleData.ModuleID, slotSequence, LoadWaferAssociation.LotId, true);
            }
        }

        public void AbortSingleJob(string jobName,string waferID)
        {
            if (!string.IsNullOrEmpty(jobName) && !string.IsNullOrEmpty(waferID))
                WaferAssociationProvider.Instance.AbortSingleJob(jobName, waferID);
        }

        public void Start(string jobID)
        {
            var selection = DialogBox.ShowDialog(DialogButton.OK | DialogButton.Cancel, DialogType.CONFIRM,
               "Make sure that the LL creates a wafer \r\nMake sure that the LL is in the Online state");
            if (selection == DialogButton.Cancel)
            {
                return;
            }

            WindowManager wm = new WindowManager();
            var workenable = (bool)QueryDataClient.Instance.Service.GetConfig("System.MultiProcessMode");
            if (workenable)
            {
                var isConnect = (bool)QueryDataClient.Instance.Service.GetData("MultiProcessClient.IsConnected");
                if (!isConnect)
                {
                    var infos = "MultiProcessClient Disconnected";
                    ChooseDialogBoxViewModel dialog2 = new ChooseDialogBoxViewModel();
                    dialog2.DisplayName = "MultiProcess Info";
                    dialog2.InfoStr = infos;
                    wm.ShowDialog(dialog2);
                    return;
                }
                else
                {
                    var infos = (string)QueryDataClient.Instance.Service.GetData("MultiProcessClient.ServiceInfo");
                    ChooseDialogBoxViewModel dialog2 = new ChooseDialogBoxViewModel();
                    dialog2.DisplayName = "MultiProcess Info";
                    dialog2.InfoStr = infos;
                    bool? bret = wm.ShowDialog(dialog2);
                    if (!bret.HasValue || !bret.Value)
                    {
                        return;
                    }
                }
            }

            CreateJob(LoadWaferAssociation, out jobID);

            if (JobCheck(jobID))
            {
                _systemAbort = false;
                WaferAssociationProvider.Instance.Start(jobID);
            }
        }

        public void Pause(string jobID)
        {
            if (JobCheck(jobID))
                WaferAssociationProvider.Instance.Pause(jobID);
        }

        public void Resume(string jobID)
        {
            if (JobCheck(jobID))
                WaferAssociationProvider.Instance.Resume(jobID);
        }

        public void Stop(string jobID)
        {
            if (JobCheck(jobID))
                WaferAssociationProvider.Instance.Stop(jobID);
        }

        #endregion Job operation

        #region Cassette Operation
        public void CreateWafer(string cassName, string startSlotStr, string endSlotStr)
        {
            int startSlot = 0;
            int endSlot = 0;
            if (Int32.TryParse(startSlotStr, out startSlot) && Int32.TryParse(endSlotStr, out endSlot))
            {
                InvokeClient.Instance.Service.DoOperation($"{cassName}.CreateAll", startSlot, endSlot);
            }
        }

        public void DeleteWafer(string cassName, string startSlotStr, string endSlotStr)
        {
            int startSlot = 0;
            int endSlot = 0;
            if (Int32.TryParse(startSlotStr, out startSlot) && Int32.TryParse(endSlotStr, out endSlot))
            {
                InvokeClient.Instance.Service.DoOperation($"{cassName}.DeleteAll", startSlot, endSlot);
            }
        }

        public void MapWafer(string cassName)
        {
            InvokeClient.Instance.Service.DoOperation($"EFEM.MapWafer", cassName);
        }

        public void MapTray(string cassName)
        {
            InvokeClient.Instance.Service.DoOperation($"EFEM.MapTray", cassName);
        }

        #endregion
        #endregion

        #region Signal Tower Buzzer Switch

        public void SwitchOffBuzzerEx(string sCount, string sInterval, string sRemainTime)
        {
            if (sCount.Trim().Length == 0)
            {
                return;
            }
            if (sInterval.Trim().Length == 0)
            {
                InvokeClient.Instance.Service.DoOperation("PM1.SignalTower.SwitchOffBuzzerEx", sCount);
            }
            else
            {
                if (sRemainTime.Trim().Length == 0)
                {
                    InvokeClient.Instance.Service.DoOperation("PM1.SignalTower.SwitchOffBuzzerEx", sCount, sInterval);
                }
                else
                {
                    InvokeClient.Instance.Service.DoOperation("PM1.SignalTower.SwitchOffBuzzerEx", sCount, sInterval, sRemainTime);
                }
            }
        }
        #endregion

        [Subscription("Scheduler.TimeLoad")]
        public double LoadCoolingTime { get; set; }

        #region Monitor Window


        /// <summary>
        /// 打开 Process Monitor
        /// </summary>
        public void ShowProcessMonitorWindow()
        {
            // 如果已经打开，则激活窗口
            var wins = Application.Current.Windows.OfType<ProcessMonitorView>().ToArray();
           
            if (wins.Any())
            {
                foreach (var w in wins)
                {
                    w.Activate();
                }
            }
            else
            {
                var wm = new WindowManager();
                var model = new ProcessMonitorViewModel();
                dynamic settings = new ExpandoObject();
                settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                settings.Title = "Process Data Monitor";
                wm.ShowWindow(model, null, settings);

            }
        }

        /// <summary>
        /// 关闭 Process Monitor
        /// </summary>
        public void CloseProcessMonitorWindow()
        {
            var wins = Application.Current.Windows.OfType<ProcessMonitorView>().ToArray();
            if (!wins.Any())
                return;

            foreach (var w in wins)
            {
                w.Close();
            }
        }
        /// <summary>
        /// Aggregated Event。
        /// </summary>
        /// <param name="message"></param>
        public void Handle(ShowCloseMonitorWinEvent message)
        {
            if (message.IsShow)
                // 显示Process监控窗口
                ShowProcessMonitorWindow();
            else
                CloseProcessMonitorWindow();
        }

        public void Handle(UserMode message)
        {
            switch (message)
            {
                case UserMode.None:
                    break;
                case UserMode.Normal:
                    break;
                case UserMode.Lock:
                case UserMode.Logoff:
                case UserMode.Exit:
                case UserMode.Shutdown:
                case UserMode.Breakdown:
                    CloseProcessMonitorWindow();
                    break;

                default:
                    // ignore
                    break;
            }
        }

        #endregion


    }
}
