using Aitex.Core.Common; using Aitex.Core.RT.SCCore; using Aitex.Core.UI.MVVM; using Aitex.Core.Util; using Aitex.Core.Utilities; using Aitex.Sorter.Common; using Aitex.Sorter.UI.Controls; using Aitex.Sorter.UI.Views; using MECF.Framework.Common.OperationCenter; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Input; using MECF.Framework.Common.Equipment; using System; using System.Globalization; using MECF.Framework.Common.RecipeCenter; namespace Aitex.Sorter.UI.ViewModel { public class RecipeViewBaseModel : FoupListViewModelBase { private RecipeTarget[] SourceTargets; private RecipeTarget[] DestinationTargets; public bool IsShowAllPlaceModel { get; set; } = false; public RecipeViewBaseModel(int foupCount,bool isShowAllPlaceModel=false) : base("Recipe", foupCount) { IsShowAllPlaceModel = isShowAllPlaceModel; WaferTransferCommand = new DelegateCommand(OnTransfer); WaferTransferOptionCommand = new DelegateCommand(BeforeTransfer); RemoveResultCommand = new DelegateCommand(RemoveResult); SourceDestinationCommand = new DelegateCommand(SourceDestinationChanged); RecipeCommand = new DelegateCommand(DoRecipeCommand); } private void DoRecipeCommand(string cmd) { if (!PerformInvokeFunctionCheck(new string[] { "RecipeCommand", cmd })) return; switch (cmd) { case "Add": var inputName = new RecipeNameDialog(); if (inputName.ShowDialog() == true) { AddNewRecipe(inputName.RecipeName); } break; case "Save": SaveRecipe(); break; case "Delete": if ((CurrentRecipe != null && MessageBox.Show(string.Format("Are you sure you want to delete recipe [{0}]?", CurrentRecipe.Name), "Delete Recipe", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)) { DeleteRecipe(); } break; case "Cancel": LoadRecipe(CurrentRecipe.Name); break; case "Rename": if (CurrentRecipe != null) { var recipeNameDialog = new RecipeNameDialog(CurrentRecipe.Name); if (recipeNameDialog.ShowDialog() == true) { RenameRecipe(recipeNameDialog.RecipeName); } } break; case "Copy": if (CurrentRecipe != null) { var newName = string.Format("Copy of {0}", CurrentRecipe.Name); var renameDialog = new RecipeNameDialog(newName); if (renameDialog.ShowDialog() == true) { CopyRecipe(renameDialog.RecipeName); } } break; default: break; } } public void ResetTarget() { foreach (var item in Sources) { item.IsChecked = false; } foreach (var item in Destinations) { item.IsChecked = false; } } public void AddNewRecipe(string name) { ResetTarget(); CurrentRecipe = new SorterRecipeXml(name); UIRecipeManager.Instance.SaveRecipe(name, CurrentRecipe.GetContent()); Refresh(); } public void LoadRecipe(string name) { ResetTarget(); if (name != null) { CurrentRecipe = new SorterRecipeXml(UIRecipeManager.Instance.LoadRecipe(name), name); if (CurrentRecipe.Source != null) { foreach (var item in CurrentRecipe.Source) { var lp = Sources.FirstOrDefault(x => x.Value == item); if (lp != null) lp.IsChecked = true; } } if (CurrentRecipe.Destination != null) { foreach (var item in CurrentRecipe.Destination) { var lp = Destinations.FirstOrDefault(x => x.Value == item); if (lp != null) lp.IsChecked = true; } } } else { CurrentRecipe = null; } } public void SaveRecipe() { if (CurrentRecipe != null) { CurrentRecipe.Source = new ObservableCollection(Sources.Where(x => x.IsChecked).Select(x => x.Value)); CurrentRecipe.Destination = new ObservableCollection(Destinations.Where(x => x.IsChecked).Select(x => x.Value)); if (CurrentRecipe.Source.Count == 0 && CurrentRecipe.RecipeType != SorterRecipeType.TransferNToN) { MessageBox.Show(string.Format("Source can not be empty")); return; } if (CurrentRecipe.Destination.Count == 0 && (CurrentRecipe.RecipeType == SorterRecipeType.Transfer1To1 || CurrentRecipe.RecipeType == SorterRecipeType.TransferNTo1)) { MessageBox.Show(string.Format("Destination can not be empty")); return; } if (CurrentRecipe.RecipeType == SorterRecipeType.TransferNTo1 && CurrentRecipe.Destination.Count != 1) { MessageBox.Show(string.Format("Only one can be chosen from Destination")); return; } CurrentRecipe.SaveContent(); UIRecipeManager.Instance.SaveRecipe(CurrentRecipe.Name, CurrentRecipe.GetContent()); } } public void SaveHostUsageRecipe() { if (CurrentRecipe != null) { CurrentRecipe.Source = null; CurrentRecipe.Destination = null; CurrentRecipe.SaveContent(); UIRecipeManager.Instance.SaveRecipe(CurrentRecipe.Name, CurrentRecipe.GetContent()); } } public void DeleteRecipe() { if (CurrentRecipe != null) { UIRecipeManager.Instance.DeleteRecipe(CurrentRecipe.Name); CurrentRecipe = null; Refresh(); } } public void RenameRecipe(string newName) { if (CurrentRecipe != null) { UIRecipeManager.Instance.RenameRecipe(CurrentRecipe.Name, newName); LoadRecipe(newName); Refresh(); } } public void CopyRecipe(string newName) { if (CurrentRecipe != null) { UIRecipeManager.Instance.SaveAsRecipe(newName, CurrentRecipe.GetContent()); LoadRecipe(newName); Refresh(); } } public void Refresh() { RecipeList = UIRecipeManager.Instance.GetRecipes(); HostRecipeList = new ObservableCollection(RecipeClient.Instance.Service.GetRecipes(ModuleName.Host, false)); if (SourceTargets == null) { DestinationTargets = (Application.Current.Resources["RecipeDestinationTarget"] as ArrayList).Cast().ToArray(); SourceTargets = (Application.Current.Resources["RecipeSourceTarget"] as ArrayList).Cast().ToArray(); Sources = SourceTargets.Select(x => (RecipeTarget)x.Clone()).ToArray(); Destinations = DestinationTargets.Select(x => (RecipeTarget)x.Clone()).ToArray(); } } private void OnTransfer(SorterRecipeTransferTableItem transferItem) { if (CurrentRecipe.RecipeType == SorterRecipeType.TransferNToN) { if (CurrentRecipe.TransferItems.Any(x => (x.SourceStation == transferItem.SourceStation && x.SourceSlot == transferItem.SourceSlot) || (x.DestinationStation == transferItem.DestinationStation && x.DestinationSlot == transferItem.DestinationSlot))) { return; } CurrentRecipe.TransferItems.Add(transferItem); } } protected virtual void BeforeTransfer(WaferTransferOption option) { if (currentRecipe != null && currentRecipe.RecipeType == SorterRecipeType.TransferNToN) { option.Align = currentRecipe.IsAlign; option.TurnOver = currentRecipe.IsTurnOver; option.ReadLaserMarker = currentRecipe.IsReadLaserMarker; option.ReadT7Code = currentRecipe.IsReadT7Code; option.AlignerAngle = currentRecipe.AlignAngle; } } private void RemoveResult(SorterRecipeTransferTableItem item) { CurrentRecipe.TransferItems.Remove(item); } private void SourceDestinationChanged(string param) { if (currentRecipe != null && currentRecipe.RecipeType == SorterRecipeType.Transfer1To1) { if (param == "1") { //currentRecipe.Destination = (currentRecipe.Source == ModuleName.LP1 ? ModuleName.LP2 : ModuleName.LP1); } else { //currentRecipe.Source = (currentRecipe.Destination == ModuleName.LP1 ? ModuleName.LP2 : ModuleName.LP1); } } } private IEnumerable recipeList; [IgnorePropertyChange] public IEnumerable RecipeList { get { return recipeList; } set { recipeList = value; InvokePropertyChanged("RecipeList"); } } private IEnumerable hostRecipeList; [IgnorePropertyChange] public IEnumerable HostRecipeList { get { return hostRecipeList; } set { hostRecipeList = value; InvokePropertyChanged("HostRecipeList"); } } public ICommand WaferTransferCommand { get; set; } public ICommand WaferTransferOptionCommand { get; set; } public ICommand RecipeCommand { get; set; } private SorterRecipeXml currentRecipe; [IgnorePropertyChange] public SorterRecipeXml CurrentRecipe { get { return currentRecipe; } set { currentRecipe = value; InvokePropertyChanged("CurrentRecipe"); } } public virtual IDictionary PlaceMode1To1 { get { if (!IsShowAllPlaceModel) { var placeModel = EnumHelper.ToDictionary(); //placeModel.Remove(SorterRecipePlaceModeTransfer1To1.OddFromBotton); //placeModel.Remove(SorterRecipePlaceModeTransfer1To1.OddFromTop); //placeModel.Remove(SorterRecipePlaceModeTransfer1To1.EvenFromBotton); //placeModel.Remove(SorterRecipePlaceModeTransfer1To1.EvenFromTop); placeModel.Remove(SorterRecipePlaceModeTransfer1To1.IdentifySlotByLaserMark); placeModel.Remove(SorterRecipePlaceModeTransfer1To1.ToFixedSlot); return placeModel;// EnumHelper.ToDictionary(); } else { return EnumHelper.ToDictionary(); } } } public virtual IDictionary PickMode { get { return EnumHelper.ToDictionary(); } } public virtual IDictionary PlaceModePack { get { return EnumHelper.ToDictionary(); } } public IDictionary PlaceModeOrder { get { return EnumHelper.ToDictionary(); } } public virtual IDictionary RecipeType { get { return EnumHelper.ToDictionary(); } } public ICommand RemoveResultCommand { get; set; } public ICommand SourceDestinationCommand { get; set; } private RecipeTarget[] sources; public RecipeTarget[] Sources { get => sources; set { sources = value; InvokePropertyChanged("Sources"); } } private RecipeTarget[] destinations; public RecipeTarget[] Destinations { get => destinations; set { destinations = value; InvokePropertyChanged("Destinations"); } } private string selectedRecipe; public string SelectedRecipe { get => selectedRecipe; set { selectedRecipe = value; InvokePropertyChanged("SelectedRecipe"); LoadRecipe(selectedRecipe); } } private string selectedHostRecipe; public string SelectedHostRecipe { get => selectedHostRecipe; set { selectedHostRecipe = value; InvokePropertyChanged("SelectedHostRecipe"); } } private void UpdateTransferState(WaferInfo wafer, ModuleName station, int slot) { if (CurrentRecipe != null && currentRecipe.TransferItems != null) { var sourceItem = currentRecipe.TransferItems.FirstOrDefault(x => x.SourceStation == station && x.SourceSlot == slot); if (sourceItem != null) { wafer.IsSource = true; } var destinationItem = currentRecipe.TransferItems.FirstOrDefault(x => x.DestinationStation == station && x.DestinationSlot == slot); if (destinationItem != null) { wafer.IsDestination = true; } } } protected override WaferInfo[] UpdateWaferInfo(WaferInfo[] waferInfos) { foreach (var waferInfo in waferInfos) { if (waferInfo.Status != WaferStatus.Empty) { waferInfo.Status = WaferStatus.Dummy; } } return waferInfos; } } }