Files
BeWoPlaner/BeWo/View/Detail/MassnahmenTreeTrimmer.cs
2023-06-07 14:15:49 +02:00

343 lines
13 KiB
C#

using BeWo.Core;
using BeWo.ViewModel;
using BeWo.ViewModel.ListViewModel;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.ClientPartials;
using System;
using System.Collections.Generic;
using System.Linq;
using static BeWo.View.Detail.MassnahmenHistoryRecord;
namespace BeWo.View.Detail
{
public class MassnahmenTreeTrimmer
{
public Dictionary<Type, Tuple<Action<MassnahmenHistoryRecord>, Action<MassnahmenHistoryRecord>>> Type2Actions { get; set; }
public MassnahmenTreeViewView View { get; set; }
public GenericValueListEntryListVM ViewModel => View.ViewModel;
public ObservableSortCollection<SupportConceptGoalTreeItem> GoalTree => View.GoalTree;
public MassnahmenTreeTrimmer(MassnahmenTreeViewView view)
{
View = view;
Type2Actions = new Dictionary<Type, Tuple<Action<MassnahmenHistoryRecord>, Action<MassnahmenHistoryRecord>>>
{
{ typeof(MassnahmenHistoryRecordAdd), GetTuple<MassnahmenHistoryRecordAdd>(UndoAddAction, RedoAddAction) },
{ typeof(MassnahmenHistoryRecordCopy), GetTuple<MassnahmenHistoryRecordCopy>(UndoCopyAction, RedoCopyAction) },
{ typeof(MassnahmenHistoryRecordDelete), GetTuple<MassnahmenHistoryRecordDelete>(UndoDeleteAction, RedoDeleteAction) },
{ typeof(MassnahmenHistoryRecordImport), GetTuple<MassnahmenHistoryRecordImport>(UndoImportAction, RedoImportAction) },
{ typeof(MassnahmenHistoryRecordMove), GetTuple<MassnahmenHistoryRecordMove>(UndoMoveAction, RedoMoveAction) },
{ typeof(MassnahmenHistoryRecordEdit), GetTuple<MassnahmenHistoryRecordEdit>(UndoEditAction, RedoEditAction) },
};
}
public void UndoAction(MassnahmenHistoryRecord action)
{
Type2Actions[action.GetType()].Item1(action);
}
public void RedoAction(MassnahmenHistoryRecord action)
{
Type2Actions[action.GetType()].Item2(action);
}
public NodeRelation DoAddAction(SupportConceptGoalTreeItem parent, ValueListEntryType valueListEntryType,
string description, string abbreviation, string notice)
{
if (!valueListEntryType.HasFlag(ValueListEntryType.SupportConceptGoalCategoryType) &&
!valueListEntryType.HasFlag(ValueListEntryType.SupportConceptGoalType))
throw new ArgumentOutOfRangeException();
var vm = ViewModel.NewVM;
vm.Type = valueListEntryType;
if (description is object) vm.Description = description;
if (abbreviation is object) vm.Abbreviation = abbreviation;
if (notice is object) vm.Notice = notice;
var newItem = new SupportConceptGoalTreeItem
{
GoalEntryVM = vm,
GoalEntryDC = vm.CommitToDataContract(),
ParentGoal = parent
};
var rtn = new NodeRelation(newItem, parent);
ViewModel.AddNewVMToList();
if (parent == null)
{
GoalTree.Add(newItem);
return rtn;
}
vm.ParentEntry = parent.GoalEntryDC ?? parent.GoalEntryVM.CommitToDataContract();
parent.Items.Add(newItem);
parent.IsExpanded = true;
return rtn;
}
private void UndoAddAction(MassnahmenHistoryRecordAdd record)
{
DeactivateNode(record.Parameter);
}
private void RedoAddAction(MassnahmenHistoryRecordAdd param) => RedoAddAction(param.Parameter);
private void RedoAddAction(NodeRelation addParam)
{
ActivateNode(addParam);
}
public List<NodeRelation> DoCopyAction(SupportConceptGoalTreeItem parent, SupportConceptGoalTreeItem source,
MassnahmenTreeCopyType copyType, bool force_deep_copy,
out NodeRelation current, Stack<NodeRelation> records = null)
{
if (records is null)
records = new Stack<NodeRelation>();
if (source == null || parent == null)
throw new NotImplementedException("#43298467891364987");
var wm = source.GoalEntryVM;
var childs = source.Items.ToList();
var param = DoAddAction(parent, wm.Type, wm.Description, wm.Abbreviation, wm.Notice);
var node = param.Current;
var parameter = new NodeRelation(node, parent);
current = parameter;
records.Push(parameter);
if (copyType == MassnahmenTreeCopyType.Subtree || force_deep_copy)
{
foreach (var child in childs)
{
DoCopyAction(node, child, copyType, force_deep_copy, out var item, records);
}
}
return records.ToList();
}
private void UndoCopyAction(MassnahmenHistoryRecordCopy record)
{
DeactivateSubtree(record.CurrentNode, record.Parameters);
}
private void RedoCopyAction(MassnahmenHistoryRecordCopy record)
{
ActivateSubtree(record.CurrentNode, record.Parameters);
}
public MassnahmenHistoryRecordDelete DoDeleteAction(NodeRelation param)
{
// Delete Full Subtree
var stack = new Stack<NodeRelation>();
var queue = new Queue<NodeRelation>();
DoDeleteActionRec(param.Current, ref stack, ref queue);
// Queue löschen
DeactivateSubtree(param, queue);
//var list = stack.Select(x => new MassnahmenHistoryNodeParameter(x, View.GetParent(x))).ToList();
var node = new NodeRelation(param.Current, param.Parent);
return new MassnahmenHistoryRecordDelete(node, stack.ToList());
}
public void DoDeleteActionRec(SupportConceptGoalTreeItem item, ref Stack<NodeRelation> stack, ref Queue<NodeRelation> queue)
{
foreach (var child in item.Items)
{
DoDeleteActionRec(child, ref stack, ref queue);
}
var param = new NodeRelation(item);
stack.Push(param);
queue.Enqueue(param);
}
private void UndoDeleteAction(MassnahmenHistoryRecordDelete param)
{
ActivateSubtree(param.ExNode, param.Parameters);
}
private void RedoDeleteAction(MassnahmenHistoryRecordDelete param)
{
DeactivateSubtree(param.ExNode, param.Parameters);
}
public List<NodeRelation> DoImportAction(SupportConceptGoalDC goal, List<NodeRelation> records = null)
{
if (goal == null)
return null;
if (records == null)
records = new List<NodeRelation>();
goal.Children?.ForEach(x => DoImportAction(x, records));
if (goal.IsChecked)
AddIcf(goal, records);
return records;
}
private void UndoImportAction(MassnahmenHistoryRecordImport param)
{
foreach (var item in param.ParametersReversed)
{
DeactivateNode(item);
}
}
private void RedoImportAction(MassnahmenHistoryRecordImport param)
{
foreach (var item in param.Parameters)
{
ActivateNode(item);
}
}
public MassnahmenHistoryRecordMove DoMoveAction(SupportConceptGoalTreeItem child, SupportConceptGoalTreeItem ex_parent, SupportConceptGoalTreeItem parent)
{
// Entferne child aus Ex-Parent
if (ex_parent is object)
ex_parent.Items.Remove(child);
else
GoalTree.Remove(child);
// Füge child parent hinzu
if (parent is object)
parent.Items.Add(child);
else
GoalTree.Add(child);
// Setze child Parent Entry
child.GoalEntryVM.ParentEntry = parent?.GoalEntryDC;
child.ParentGoal = parent;
return new MassnahmenHistoryRecordMove(child, ex_parent, parent);
}
private void UndoMoveAction(MassnahmenHistoryRecordMove move)
{
DoMoveAction(move.Child, move.Parent, move.ExParent);
}
private void RedoMoveAction(MassnahmenHistoryRecordMove move)
{
DoMoveAction(move.Child, move.ExParent, move.Parent);
}
public MassnahmenHistoryRecordEdit DoEditAction(ValueListEntryDC b, ValueListEntryVM a)
{
var before = new NodeEditInformation { Abbreviation = b.Abbreviation, Description = b.TypeDescription, Notice = b.Notice };
var after = new NodeEditInformation { Abbreviation = a.Abbreviation, Description = a.Description, Notice = a.Notice };
return new MassnahmenHistoryRecordEdit(a, before, after);
}
private void UndoEditAction(MassnahmenHistoryRecordEdit edit)
{
edit.SetVM(edit.Before);
}
private void RedoEditAction(MassnahmenHistoryRecordEdit edit)
{
edit.SetVM(edit.After);
}
private Tuple<Action<MassnahmenHistoryRecord>, Action<MassnahmenHistoryRecord>> GetTuple<T1>(Action<T1> a, Action<T1> b) where T1 : MassnahmenHistoryRecord
=> new Tuple<Action<MassnahmenHistoryRecord>, Action<MassnahmenHistoryRecord>>(x => a(x as T1), x => b(x as T1));
private SupportConceptGoalTreeItem AddIcf(SupportConceptGoalDC goal, List<NodeRelation> records)
{
if (goal == null) return null;
// Schaut, ob das Child bereits existiert
var similarGoal = GoalTree.FirstOrDefault(x => MassnahmenTreeViewView.SearchGoalTreeItem(x, goal.GoalEntryDC.TypeDescription, goal.GoalEntryDC.Abbreviation, goal.GoalEntryDC.Notice) != null);
if (similarGoal != null)
return similarGoal;
// Schaut, ob das Goal ein Parent hat
if (goal.ParentGoal == null)
{
// Ist Root Element
var record = DoAddAction(null, ValueListEntryType.SupportConceptGoalCategoryType,
goal.GoalEntryDC.TypeDescription, goal.GoalEntryDC.Abbreviation, goal.GoalEntryDC.Notice);
records.Add(record);
//GoalTree.Sort((x, y) => x.GoalEntryVM?.DisplayName?.CompareTo(y.GoalEntryVM?.DisplayName) ?? string.Compare(string.Empty, y.GoalEntryVM?.DisplayName, StringComparison.Ordinal));
return record.Current;
}
// Schaut, ob das ParentGoal bereits existiert
foreach (var goalTreeItem in GoalTree)
{
var similarParentGoal = MassnahmenTreeViewView.SearchGoalTreeItem(goalTreeItem, goal.ParentGoal.GoalEntryDC.TypeDescription, goal.ParentGoal.GoalEntryDC.Abbreviation, goal.ParentGoal.GoalEntryDC.Notice);
if (similarParentGoal == null)
continue;
var record = DoAddAction(similarParentGoal, ValueListEntryType.SupportConceptGoalCategoryType, goal.GoalEntryDC.TypeDescription, goal.GoalEntryDC.Abbreviation, goal.GoalEntryDC.Notice);
records.Add(record);
return record.Current;
}
// Fügt den Parent hinzu
var parent = AddIcf(goal.ParentGoal, records);
var record2 = DoAddAction(parent, ValueListEntryType.SupportConceptGoalCategoryType,
goal.GoalEntryDC.TypeDescription, goal.GoalEntryDC.Abbreviation, goal.GoalEntryDC.Notice);
records.Add(record2);
return record2.Current;
}
private void ActivateSubtree(NodeRelation currentNode, List<NodeRelation> param)
{
foreach (var item in param)
{
ViewModel.VMList.Add(item.Current.GoalEntryVM);
}
if (currentNode.Parent is object)
currentNode.Parent.Items.Add(currentNode.Current);
else
GoalTree.Add(currentNode.Current);
}
private void ActivateNode(NodeRelation currentNode)
{
var newItem = currentNode.Current;
var parent = currentNode.Parent;
ViewModel.VMList.Add(newItem.GoalEntryVM);
if (parent != null)
parent.Items.Add(newItem);
else
GoalTree.Add(newItem);
}
private void DeactivateSubtree(NodeRelation currentNode, IEnumerable<NodeRelation> param)
{
foreach (var item in param)
{
ViewModel.VMList.Remove(item.Current.GoalEntryVM);
}
if (currentNode.Parent is object)
currentNode.Parent.Items.Remove(currentNode.Current);
else
GoalTree.Remove(currentNode.Current);
}
private void DeactivateNode(NodeRelation currentNode)
{
var newItem = currentNode.Current;
var parent = currentNode.Parent;
ViewModel.VMList.Remove(newItem.GoalEntryVM);
if (parent != null)
parent.Items.Remove(newItem);
else
GoalTree.Remove(newItem);
}
}
}