using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Aitex.Core.Common;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.DBCore;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Utilities;

namespace MECF.Framework.Common.SubstrateTrackings
{
	public class WaferManager : Singleton<WaferManager>, ISerializable
	{
        #region Variables

        private readonly object _lockerWaferList = new();

        private PeriodicJob _thread;
        private bool _needSerialize;

        #endregion

        #region Constructors

        public WaferManager()
        {
            AllLocationWafers = new SerializableDictionary<ModuleName, Dictionary<int, WaferInfoRt>>();
        }

        #endregion


		#region Properties
        public Dictionary<ModuleName, Dictionary<int, WaferInfoRt>> AllLocationWafers { get; private set; }

		#endregion


        #region Methods

		public bool Serialize()
		{
			if (!_needSerialize)
			{
				return true;
			}
			_needSerialize = false;
			try
			{
				if (AllLocationWafers != null)
				{
					BinarySerializer<Dictionary<ModuleName, Dictionary<int, WaferInfoRt>>>.ToStream(AllLocationWafers, "WaferManager");
				}
			}
			catch (Exception ex)
			{
				LOG.Write(ex);
			}
			return true;
		}

		public void Deserialize()
		{
			try
			{
				var dictionary = BinarySerializer<Dictionary<ModuleName, Dictionary<int, WaferInfoRt>>>.FromStream("WaferManager");
				if (dictionary == null)
				{
					return;
				}
				
				AllLocationWafers = dictionary;
			}
			catch (Exception ex)
			{
				LOG.Write(ex);
			}
		}

        public void Initialize()
		{
			Deserialize();
			_thread = new PeriodicJob(1000, Serialize, "SerializeMonitorHandler", isStartNow: true);
		}

		public void SubscribeLocation(string module, int slotNumber)
		{
			if (Enum.TryParse<ModuleName>(module, out var result))
			{
				SubscribeLocation(result, slotNumber);
			}
			else
			{
				LOG.Write($"Failed SubscribeLocation, module name invalid, {module} ");
			}
		}

		public void SubscribeLocation(ModuleName module, int slotNumber)
		{
			if (!AllLocationWafers.ContainsKey(module))
			{
				AllLocationWafers[module] = new Dictionary<int, WaferInfoRt>();
				for (var i = 0; i < slotNumber; i++)
				{
					AllLocationWafers[module][i] = new WaferInfoRt();
				}
			}

			DATA.Subscribe(module.ToString(), "ModuleWaferList", () => AllLocationWafers[module].Values.ToArray());
		}

		public void WaferMoved(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo)
		{
			UpdateWaferHistory(moduleFrom, slotFrom, SubstAccessType.Left);

			//if (AllLocationWafers[moduleFrom][slotFrom].IsWaferEmpty)
			//{
			//	LOG.Write($"Invalid wafer move, no wafer at source, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
			//	return;
			//}

			//if (!AllLocationWafers[moduleTo][slotTo].IsWaferEmpty)
			//{
			//	LOG.Write($"Invalid wafer move, destination has wafer, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
			//	return;
			//}

			LOG.Write($"WaferMoved From {moduleFrom} {slotFrom} to {moduleTo} {slotTo} [{AllLocationWafers[moduleFrom][slotFrom].WaferID}_{AllLocationWafers[moduleFrom][slotFrom].LotId}_{AllLocationWafers[moduleFrom][slotFrom].WaferStatus}]-->[{AllLocationWafers[moduleTo][slotTo].WaferID}_{AllLocationWafers[moduleTo][slotTo].LotId}_{AllLocationWafers[moduleTo][slotTo].WaferStatus}]");

            AllLocationWafers[moduleTo][slotTo].MoveWafer(AllLocationWafers[moduleFrom][slotFrom]);

            UpdateWaferHistory(moduleTo, slotTo, SubstAccessType.Arrive);

			EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferMoved, AllLocationWafers[moduleFrom][slotFrom].WaferOriginStation, moduleFrom.ToString(), slotFrom + 1, moduleTo.ToString(), slotTo + 1);

            if (!string.IsNullOrEmpty(AllLocationWafers[moduleFrom][slotFrom].WaferID))
			{
                WaferMoveHistoryRecorder.WaferMoved(AllLocationWafers[moduleFrom][slotFrom].WaferID.ToString(), moduleTo.ToString(), slotTo, AllLocationWafers[moduleFrom][slotFrom].WaferStatus.ToString());
            }

			AllLocationWafers[moduleFrom][slotFrom].SetWaferEmpty();

            _needSerialize = true;
		}

		public void TrayMoved(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo)
		{
			UpdateWaferHistory(moduleFrom, slotFrom, SubstAccessType.Left);

			//if (AllLocationWafers[moduleFrom][slotFrom].IsTrayEmpty)
			//{
			//	LOG.Write($"Invalid tray move, no tray at source, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
			//	return;
			//}

   //         if (!AllLocationWafers[moduleTo][slotTo].IsTrayEmpty)
   //         {
			//	LOG.Write($"Invalid tray move, destination has tray, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
			//	return;
			//}

            LOG.Write($"TrayMoved From {moduleFrom} {slotFrom} to {moduleTo} {slotTo} [{AllLocationWafers[moduleFrom][slotFrom].TrayInnerID}_{AllLocationWafers[moduleFrom][slotFrom].TrayBelongTo}_{AllLocationWafers[moduleFrom][slotFrom].TrayStatus}_{AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount}]-->[{AllLocationWafers[moduleTo][slotTo].TrayInnerID}_{AllLocationWafers[moduleTo][slotTo].TrayBelongTo}_{AllLocationWafers[moduleTo][slotTo].TrayStatus}_{AllLocationWafers[moduleTo][slotTo].TrayProcessCount}]");

            AllLocationWafers[moduleTo][slotTo].MoveTray(AllLocationWafers[moduleFrom][slotFrom]);

            AllLocationWafers[moduleFrom][slotFrom].SetTrayEmpty();

            _needSerialize = true;
        }

        public void WaferTrayMoved(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo)
        {
            UpdateWaferHistory(moduleFrom, slotFrom, SubstAccessType.Left);

            //if (AllLocationWafers[moduleFrom][slotFrom].IsWaferEmpty)
            //{
            //    LOG.Write($"Invalid wafer move, no wafer at source, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
            //    return;
            //}

            //if (!AllLocationWafers[moduleTo][slotTo].IsWaferEmpty)
            //{
            //    LOG.Write($"Invalid wafer move, destination has wafer, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
            //    return;
            //}

            //if (AllLocationWafers[moduleFrom][slotFrom].IsTrayEmpty)
            //{
            //    LOG.Write($"Invalid tray move, no tray at source, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
            //    return;
            //}

            //if (!AllLocationWafers[moduleTo][slotTo].IsTrayEmpty)
            //{
            //    LOG.Write($"Invalid tray move, destination has tray, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
            //    return;
            //}

            LOG.Write($"WaferMoved From {moduleFrom} {slotFrom} to {moduleTo} {slotTo} [{AllLocationWafers[moduleFrom][slotFrom].WaferID}_{AllLocationWafers[moduleFrom][slotFrom].LotId}_{AllLocationWafers[moduleFrom][slotFrom].WaferStatus}]-->[{AllLocationWafers[moduleTo][slotTo].WaferID}_{AllLocationWafers[moduleTo][slotTo].LotId}_{AllLocationWafers[moduleTo][slotTo].WaferStatus}]");

            LOG.Write($"TrayMoved From {moduleFrom} {slotFrom} to {moduleTo} {slotTo} [{AllLocationWafers[moduleFrom][slotFrom].TrayInnerID}_{AllLocationWafers[moduleFrom][slotFrom].TrayBelongTo}_{AllLocationWafers[moduleFrom][slotFrom].TrayStatus}_{AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount}]-->[{AllLocationWafers[moduleTo][slotTo].TrayInnerID}_{AllLocationWafers[moduleTo][slotTo].TrayBelongTo}_{AllLocationWafers[moduleTo][slotTo].TrayStatus}_{AllLocationWafers[moduleTo][slotTo].TrayProcessCount}]");

            AllLocationWafers[moduleTo][slotTo].MoveWaferTray(AllLocationWafers[moduleFrom][slotFrom]);

            UpdateWaferHistory(moduleTo, slotTo, SubstAccessType.Arrive);

            EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferMoved, AllLocationWafers[moduleFrom][slotFrom].WaferOriginStation, moduleFrom.ToString(), slotFrom + 1, moduleTo.ToString(), slotTo + 1);

			if(!string.IsNullOrEmpty(AllLocationWafers[moduleFrom][slotFrom].WaferID))
			{
                WaferMoveHistoryRecorder.WaferMoved(AllLocationWafers[moduleFrom][slotFrom].WaferID, moduleTo.ToString(), slotTo, AllLocationWafers[moduleFrom][slotFrom].WaferStatus.ToString());
            }

            AllLocationWafers[moduleFrom][slotFrom].SetWaferTrayEmpty();

            _needSerialize = true;
        }

		private string GetCarrierID(ModuleName module)
		{
			if (!ModuleHelper.IsLoadPort(module))
			{
				return "";
			}
			return DATA.Poll(module.ToString() + ".CarrierId").ToString();
		}

		public bool IsWaferSlotLocationValid(ModuleName module, int slot)
		{
			return AllLocationWafers.ContainsKey(module) && AllLocationWafers[module].ContainsKey(slot);
		}

		public WaferInfoRt[] GetWafers(ModuleName module)
		{
			if (!AllLocationWafers.ContainsKey(module))
			{
				return null;
			}
			return AllLocationWafers[module].Values.ToArray();
		}

		public WaferInfoRt[] GetWaferByProcessJob(string jobName)
		{
			var list = new List<WaferInfoRt>();
			foreach (var locationWafer in AllLocationWafers)
			{
				foreach (var item in locationWafer.Value)
				{
					if (item.Value != null && !item.Value.IsWaferEmpty && item.Value.ProcessJob != null && item.Value.ProcessJob.Name == jobName)
					{
						list.Add(item.Value);
					}
				}
			}
			return list.ToArray();
		}
		
		public WaferInfoRt[] GetWafer(string waferID)
		{
			var list = new List<WaferInfoRt>();
			foreach (var locationWafer in AllLocationWafers)
			{
				foreach (var item in locationWafer.Value)
				{
					if (item.Value.WaferID == waferID)
					{
						list.Add(item.Value);
					}
				}
			}
			return list.ToArray();
		}

		public WaferInfoRt GetWafer(ModuleName module, int slot)
		{
			if (!AllLocationWafers.ContainsKey(module))
			{
				return null;
			}
			if (!AllLocationWafers[module].ContainsKey(slot))
			{
				return null;
			}
			return AllLocationWafers[module][slot];
		}

		public WaferInfoRt[] GetWafers(string Originalcarrier, int Originalslot)
		{
			var list = new List<WaferInfoRt>();
			foreach (var locationWafer in AllLocationWafers)
			{
				foreach (var item in locationWafer.Value)
				{
					if (item.Value.OriginCarrierID == Originalcarrier && item.Value.WaferOriginSlot == Originalslot)
					{
						list.Add(item.Value);
					}
				}
			}
			return list.ToArray();
		}

		public string GetWaferID(ModuleName module, int slot)
		{
			return IsWaferSlotLocationValid(module, slot) ? AllLocationWafers[module][slot].WaferID : "";
		}

		public WaferSize GetWaferSize(ModuleName module, int slot)
		{
			return IsWaferSlotLocationValid(module, slot) ? AllLocationWafers[module][slot].Size : WaferSize.WS0;
		}

		public bool CheckNoWafer(ModuleName module, int slot)
		{
			return IsWaferSlotLocationValid(module, slot) && AllLocationWafers[module][slot].IsWaferEmpty;
		}

		public bool CheckNoWafer(string module, int slot)
		{
			return CheckNoWafer((ModuleName)Enum.Parse(typeof(ModuleName), module), slot);
		}

		public bool CheckHasWafer(ModuleName module, int slot)
		{
			return IsWaferSlotLocationValid(module, slot) && !AllLocationWafers[module][slot].IsWaferEmpty;
		}

		public bool CheckWaferIsDummy(ModuleName module, int slot)
		{
			return IsWaferSlotLocationValid(module, slot) && !AllLocationWafers[module][slot].IsWaferEmpty && AllLocationWafers[module][slot].WaferStatus == WaferStatus.Dummy;
		}

		public bool CheckHasWafer(string module, int slot)
		{
			return CheckHasWafer((ModuleName)Enum.Parse(typeof(ModuleName), module), slot);
		}

		public bool CheckNoTray(ModuleName module, int slot)
		{
			return IsWaferSlotLocationValid(module, slot) && AllLocationWafers[module][slot].IsTrayEmpty;
		}

		public bool CheckHasTray(ModuleName module, int slot)
		{
			return IsWaferSlotLocationValid(module, slot) && !AllLocationWafers[module][slot].IsTrayEmpty;
		}

		public bool CheckWaferFull(ModuleName module)
		{
			var dictionary = AllLocationWafers[module];
			foreach (var item in dictionary)
			{
				if (item.Value.IsWaferEmpty)
				{
					return false;
				}
			}
			return true;
		}

		public bool CheckWaferEmpty(ModuleName module)
		{
			var dictionary = AllLocationWafers[module];
			foreach (var item in dictionary)
			{
				if (!item.Value.IsWaferEmpty)
				{
					return false;
				}
			}
			return true;
		}

		public bool CheckWafer(ModuleName module, int slot, WaferStatus state)
		{
			return IsWaferSlotLocationValid(module, slot) && AllLocationWafers[module][slot].WaferStatus == state;
		}

		public WaferInfoRt CreateWafer(ModuleName module, int slot, WaferStatus status = WaferStatus.Normal)
		{
			if (!IsWaferSlotLocationValid(module, slot))
			{
				LOG.Write($"Invalid wafer create, invalid parameter, {module}, {slot + 1}");
				return null;
			}

			var carrierGuid = "";
			var text = string.Empty;
			if (ModuleHelper.IsLoadPort(module) || ModuleHelper.IsCassette(module))
			{
				var carrier = Singleton<CarrierManager>.Instance.GetCarrier(module.ToString());
				if (carrier == null)
				{
					EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, $"No carrier at {module}, can not create wafer");
					return null;
				}
				carrierGuid = carrier.InnerId.ToString();
				text = carrier.CarrierId;
			}

			lock (_lockerWaferList)
			{
                AllLocationWafers[module][slot].Station = (int)module;
                AllLocationWafers[module][slot].Slot = slot;

                AllLocationWafers[module][slot].WaferID = GenerateWaferId(module, slot, text);
				AllLocationWafers[module][slot].WaferInnerID = Guid.NewGuid();
				AllLocationWafers[module][slot].LotId = string.Empty;
				AllLocationWafers[module][slot].ProcessJob = null;
				AllLocationWafers[module][slot].NextSequenceStep = 0;
				AllLocationWafers[module][slot].WaferOriginStation = module.ToString();
				AllLocationWafers[module][slot].WaferOriginSlot = slot;
                AllLocationWafers[module][slot].WaferOrigin = GenerateOrigin(module, slot);
                AllLocationWafers[module][slot].Size = WaferSize.WS6;
				AllLocationWafers[module][slot].HasWarning = false;
				AllLocationWafers[module][slot].PPID = string.Empty;
				AllLocationWafers[module][slot].TransFlag = string.Empty;
				AllLocationWafers[module][slot].ProcessJobID = string.Empty;
				AllLocationWafers[module][slot].ControlJobID = string.Empty;
				AllLocationWafers[module][slot].WaferStatus = status;
				AllLocationWafers[module][slot].IsChecked = false;
				AllLocationWafers[module][slot].ProcessState = WaferProcessStatus.Idle;
				AllLocationWafers[module][slot].SubstTransStatus = SubstrateTransportStatus.None;
				AllLocationWafers[module][slot].SubstE90Status = EnumE90Status.NeedProcessing;
				AllLocationWafers[module][slot].SubstHists = null;

				var substHistory = new SubstHistory(module.ToString(), slot, DateTime.Now, SubstAccessType.Create);
				AllLocationWafers[module][slot].SubstHists = new SubstHistory[1] { substHistory };
			}

			UpdateWaferTransportState(AllLocationWafers[module][slot].WaferID, SubstrateTransportStatus.AtSource);

			WaferDataRecorder.CreateWafer(AllLocationWafers[module][slot].WaferInnerID.ToString(), carrierGuid, module.ToString(), slot, AllLocationWafers[module][slot].WaferID, AllLocationWafers[module][slot].ProcessState.ToString());

			_needSerialize = true;
			return AllLocationWafers[module][slot];
		}

		public WaferInfoRt CreateWafer(ModuleName module, int slot, WaferStatus status, WaferSize wz)
		{
            if (!IsWaferSlotLocationValid(module, slot))
            {
                LOG.Write($"Invalid wafer create, invalid parameter, {module}, {slot + 1}");
                return null;
            }

            var carrierGuid = "";
            var text = string.Empty;
            if (ModuleHelper.IsLoadPort(module) || ModuleHelper.IsCassette(module))
            {
                var carrier = Singleton<CarrierManager>.Instance.GetCarrier(module.ToString());
                if (carrier == null)
                {
                    EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, $"No carrier at {module}, can not create wafer");
                    return null;
                }
                carrierGuid = carrier.InnerId.ToString();
                text = carrier.CarrierId;
            }

            lock (_lockerWaferList)
            {
                AllLocationWafers[module][slot].Station = (int)module;
                AllLocationWafers[module][slot].Slot = slot;

                AllLocationWafers[module][slot].WaferID = GenerateWaferId(module, slot, text);
                AllLocationWafers[module][slot].WaferInnerID = Guid.NewGuid();
                AllLocationWafers[module][slot].LotId = string.Empty;
                AllLocationWafers[module][slot].ProcessJob = null;
                AllLocationWafers[module][slot].NextSequenceStep = 0;
                AllLocationWafers[module][slot].WaferOriginStation = module.ToString();
                AllLocationWafers[module][slot].WaferOriginSlot = slot;
                AllLocationWafers[module][slot].WaferOrigin = GenerateOrigin(module, slot);
                AllLocationWafers[module][slot].Size = wz;
                AllLocationWafers[module][slot].HasWarning = false;
                AllLocationWafers[module][slot].PPID = string.Empty;
                AllLocationWafers[module][slot].TransFlag = string.Empty;
                AllLocationWafers[module][slot].ProcessJobID = string.Empty;
                AllLocationWafers[module][slot].ControlJobID = string.Empty;
                AllLocationWafers[module][slot].WaferStatus = status;
                AllLocationWafers[module][slot].IsChecked = false;
                AllLocationWafers[module][slot].ProcessState = WaferProcessStatus.Idle;
                AllLocationWafers[module][slot].SubstTransStatus = SubstrateTransportStatus.None;
                AllLocationWafers[module][slot].SubstE90Status = EnumE90Status.NeedProcessing;
                AllLocationWafers[module][slot].SubstHists = null;

                var substHistory = new SubstHistory(module.ToString(), slot, DateTime.Now, SubstAccessType.Create);
                AllLocationWafers[module][slot].SubstHists = new SubstHistory[1] { substHistory };
            }

            UpdateWaferTransportState(AllLocationWafers[module][slot].WaferID, SubstrateTransportStatus.AtSource);

            WaferDataRecorder.CreateWafer(AllLocationWafers[module][slot].WaferInnerID.ToString(), carrierGuid, module.ToString(), slot, AllLocationWafers[module][slot].WaferID, AllLocationWafers[module][slot].ProcessState.ToString());

            _needSerialize = true;
            return AllLocationWafers[module][slot];
        }

		public WaferInfoRt CreateTray(ModuleName module, int slot, TrayStatus status = TrayStatus.Normal)
		{
			if (!IsWaferSlotLocationValid(module, slot))
			{
				LOG.Write($"Invalid wafer create, invalid parameter, {module}, {slot + 1}");
				return null;
			}

			var carrierGuid = "";
			var text = string.Empty;
			if (ModuleHelper.IsLoadPort(module) || ModuleHelper.IsCassette(module))
			{
				var carrier = Singleton<CarrierManager>.Instance.GetCarrier(module.ToString());
				if (carrier == null)
				{
					EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, $"No carrier at {module}, can not create wafer");
					return null;
				}
				carrierGuid = carrier.InnerId.ToString();
				text = carrier.CarrierId;
            }
            lock (_lockerWaferList)
            {
                AllLocationWafers[module][slot].Station = (int)module;
                AllLocationWafers[module][slot].Slot = slot;

                AllLocationWafers[module][slot].TrayInnerID = Guid.NewGuid();
                AllLocationWafers[module][slot].TrayProcessCount = SC.ContainsItem("System.DefaultTrayProcessCount") ? SC.GetValue<int>("System.DefaultTrayProcessCount") : 10;
                AllLocationWafers[module][slot].TrayUsedForWhichPM = 0;
                AllLocationWafers[module][slot].TrayBelongTo = "System";
                AllLocationWafers[module][slot].TrayOriginStation = module.ToString();
                AllLocationWafers[module][slot].TrayOriginSlot = slot;
                AllLocationWafers[module][slot].TrayStatus = status;

				var substHistory = new SubstHistory(module.ToString(), slot, DateTime.Now, SubstAccessType.Create);
				AllLocationWafers[module][slot].SubstHists = new SubstHistory[1] { substHistory };
			}

			//UpdateWaferTransportState(AllLocationWafers[module][slot].WaferID, SubstrateTransportStatus.AtSource);

			_needSerialize = true;
			return AllLocationWafers[module][slot];
		}

        public void DeleteWafer(ModuleName module, int slotFrom, int count = 1)
		{
			lock (_lockerWaferList)
			{
				for (var i = 0; i < count; i++)
				{
					var num = slotFrom + i;
					if (!IsWaferSlotLocationValid(module, num))
					{
						LOG.Write($"Invalid wafer delete, invalid parameter, {module}, {num + 1}");
						continue;
					}

					UpdateWaferTransportState(AllLocationWafers[module][num].WaferID, SubstrateTransportStatus.None);
					WaferDataRecorder.DeleteWafer(AllLocationWafers[module][num].WaferInnerID.ToString());

					AllLocationWafers[module][num].SetWaferEmpty();
                }
			}
			_needSerialize = true;
		}

		public void DeleteTray(ModuleName module, int slotFrom, int count = 1)
		{
			lock (_lockerWaferList)
			{
				for (var i = 0; i < count; i++)
				{
					var num = slotFrom + i;
					if (!IsWaferSlotLocationValid(module, num))
					{
						LOG.Write($"Invalid wafer delete, invalid parameter, {module}, {num + 1}");
						continue;
					}

                    AllLocationWafers[module][num].SetTrayEmpty();
                }
			}
			_needSerialize = true;
		}

		public void UpdateWaferProcessStatus(ModuleName module, int slot, WaferProcessStatus status)
		{
			if (!IsWaferSlotLocationValid(module, slot))
			{
				LOG.Write($"Failed UpdateWaferProcessStatus, invalid parameter, {module}, {slot + 1}");
				return;
			}

			lock (_lockerWaferList)
			{
				AllLocationWafers[module][slot].ProcessState = status;
				WaferDataRecorder.SetWaferStatus(AllLocationWafers[module][slot].WaferInnerID.ToString(), status.ToString());
			}
			_needSerialize = true;
		}

		public void UpdateWaferProcessStatus(ModuleName module, int slot, ProcessStatus status)
		{
			switch (status)
			{
			case ProcessStatus.Busy:
				UpdateWaferProcessStatus(module, slot, WaferProcessStatus.InProcess);
				break;
			case ProcessStatus.Completed:
				UpdateWaferProcessStatus(module, slot, WaferProcessStatus.Completed);
				break;
			case ProcessStatus.Failed:
			case ProcessStatus.Abort:
				UpdateWaferProcessStatus(module, slot, WaferProcessStatus.Failed);
				break;
			case ProcessStatus.Idle:
				UpdateWaferProcessStatus(module, slot, WaferProcessStatus.Idle);
				break;
			case ProcessStatus.Wait:
				UpdateWaferProcessStatus(module, slot, WaferProcessStatus.InProcess);
				break;
			}
		}

		public void UpdateWaferProcessStatus(string waferID, ProcessStatus status)
		{
			switch (status)
			{
			case ProcessStatus.Busy:
				UpdateWaferProcessStatus(waferID, WaferProcessStatus.InProcess);
				break;
			case ProcessStatus.Completed:
				UpdateWaferProcessStatus(waferID, WaferProcessStatus.Completed);
				break;
			case ProcessStatus.Failed:
				UpdateWaferProcessStatus(waferID, WaferProcessStatus.Failed);
				break;
			case ProcessStatus.Idle:
				UpdateWaferProcessStatus(waferID, WaferProcessStatus.Idle);
				break;
			case ProcessStatus.Wait:
				UpdateWaferProcessStatus(waferID, WaferProcessStatus.InProcess);
				break;
			}
		}

		public void UpdateWaferTransportState(string waferid, SubstrateTransportStatus ststate)
		{
			if (string.IsNullOrEmpty(waferid))
			{
				return;
			}
			var wafer = GetWafer(waferid);
			lock (_lockerWaferList)
			{
				var array = wafer;
				foreach (var waferInfo in array)
				{
					waferInfo.SubstTransStatus = ststate;
					var dvid = new SerializableDictionary<string, object>
					{
						{ "SubstID", waferInfo.WaferID },
						{ "LotID", waferInfo.LotId },
						{
							"SubstMtrlStatus",
							(int)waferInfo.ProcessState
						},
						{
							"SubstDestination",
							((ModuleName)waferInfo.DestinationStation).ToString()
						},
						{ "SubstHistory", waferInfo.SubstHists },
						{
							"SubstLocID",
							((ModuleName)waferInfo.Station).ToString()
						},
						{
							"SubstProcState",
							(int)waferInfo.SubstE90Status
						},
						{
							"SubstSource",
							waferInfo.WaferOriginStation
						},
						{
							"SubstState",
							(int)waferInfo.SubstTransStatus
						}
					};
					if (ststate == SubstrateTransportStatus.AtWork)
					{
						EV.Notify("STS_ATWORK", dvid);
					}
					if (ststate == SubstrateTransportStatus.AtDestination)
					{
						EV.Notify("STS_ATDESTINATION", dvid);
					}
					if (ststate == SubstrateTransportStatus.AtSource)
					{
						EV.Notify("STS_ATSOURCE", dvid);
					}
					if (ststate == SubstrateTransportStatus.None)
					{
						EV.Notify("STS_DELETED", dvid);
					}
				}
			}
			_needSerialize = true;
			_needSerialize = true;
		}

		

		public void UpdatTrayBelongTo(ModuleName module,int slot,string trayBelongTo)
		{
            AllLocationWafers[module][slot].TrayBelongTo = trayBelongTo;
            UpdateWaferHistory(module, slot, SubstAccessType.Left);//属性信息设置后，不发生移动属性数据不保存，所以此处执行保存属性数据功能
        }

		public void UpdateWaferHistory(ModuleName module, int slot, SubstAccessType accesstype)
		{
			if (!IsWaferSlotLocationValid(module, slot))
			{
				LOG.Write($"Failed UpdateWaferHistory, invalid parameter, {module}, {slot + 1}");
				return;
			}
			lock (_lockerWaferList)
			{
				var substHistory = new SubstHistory(module.ToString(), slot, DateTime.Now, accesstype);
				if (AllLocationWafers[module][slot].SubstHists == null)
				{
					AllLocationWafers[module][slot].SubstHists = new SubstHistory[1] { substHistory };
				}
				else
				{
					AllLocationWafers[module][slot].SubstHists = AllLocationWafers[module][slot].SubstHists.Concat(new SubstHistory[1] { substHistory }).ToArray();
				}
			}
			_needSerialize = true;
		}

		public void UpdateWaferLotId(ModuleName module, int slot, string lotId)
		{
			if (!IsWaferSlotLocationValid(module, slot))
			{
				LOG.Write($"Failed UpdateWaferLotId, invalid parameter, {module}, {slot + 1}");
				return;
			}
			lock (_lockerWaferList)
			{
				AllLocationWafers[module][slot].LotId = lotId;
				WaferDataRecorder.SetWaferLotId(AllLocationWafers[module][slot].WaferInnerID.ToString(), lotId);
				Singleton<CarrierManager>.Instance.UpdateCarrierLot(module.ToString(), lotId);
			}
			_needSerialize = true;
		}

		public void UpdateWaferProcessStatus(string waferID, WaferProcessStatus status)
		{
			var wafer = GetWafer(waferID);
			lock (_lockerWaferList)
			{
				var array = wafer;
				foreach (var waferInfo in array)
				{
					waferInfo.ProcessState = status;
				}
			}
			_needSerialize = true;
		}

		public void UpdateWaferProcess(string waferID, string processId)
		{
			var wafer = GetWafer(waferID);
			lock (_lockerWaferList)
			{
				var array = wafer;
				foreach (var waferInfo in array)
				{
					WaferDataRecorder.SetProcessInfo(waferInfo.WaferInnerID.ToString(), processId);
				}
			}
			_needSerialize = true;
		}

		public bool UpdateWaferSize(ModuleName module, int slot, WaferSize size)
		{
			if (!IsWaferSlotLocationValid(module, slot))
			{
				LOG.Write($"Failed UpdateWaferSize, invalid parameter, {module}, {slot + 1}");
				return false;
			}
			lock (_lockerWaferList)
			{
				AllLocationWafers[module][slot].Size = size;
			}
			_needSerialize = true;
			Serialize();
			return true;
		}

		private string GenerateWaferId(ModuleName module, int slot, string carrierID)
		{
            var text = ((!string.IsNullOrEmpty(carrierID)) ? carrierID : (module.ToString() + DateTime.Now.ToString("yyyyMMddHHmmssff")));
			return string.Format(text + "." + (slot + 1).ToString("00"));
		}

		private string GenerateOrigin(ModuleName module, int slot)
		{
			return $"{ModuleHelper.GetAbbr(module)}.{slot + 1:D2}";
		}

		public void UpdateWaferTrayStatus(string waferid, TrayStatus state)
		{
			if (string.IsNullOrEmpty(waferid))
			{
				return;
			}
			var wafer = GetWafer(waferid);
			lock (_lockerWaferList)
			{
				foreach (var waferInfo in wafer)
				{
					if (waferInfo.TrayStatus != state)
					{
						waferInfo.TrayStatus = state;
					}
				}
			}
		}

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            throw new NotImplementedException();
        }

        public void DelectGuid(ModuleName module, int slotFrom)
        {
            AllLocationWafers[module][0].WaferInnerID = Guid.Empty;
        }

        #endregion
    }
}
