using AIPractice.LabelEditor.Annotations; using AIPractice.Shared.Labels; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; namespace AIPractice.LabelEditor { public class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class LabelObjectViewModel : ViewModel { public string Id { get; } public virtual string Title { get; set; } public LabelObjectViewModel(string id, string title) { Id = id; Title = title; } public override string ToString() { return Title; } } public class ImageLabelViewModel : LabelObjectViewModel { private ImageLabelViewModel _linked; public RootLabelViewModel Root { get; set; } public ImageLabelViewModel Linked { get => _linked; set { if(_linked != value) { _linked = value; OnPropertyChanged(); } } } public ImageLabelViewModel(string id, string title) : base(id, title) { } } public class DescriptionLabelViewModel : ImageLabelViewModel { public override string Title { get { return Description.Title; } set { if (Description != null) { Description.Title = value; } } } public DescriptionLabel Description { get; } public DescriptionLabelViewModel(DescriptionLabel description) : base(description.Id, description.Title) { Description = description; } } public class ConclusionLabelViewModel : ImageLabelViewModel { public override string Title { get => Conclusion.Title; set { if (Conclusion != null) { Conclusion.Title = value; } } } public bool IsParts { get => Conclusion.IsParts; set { if (Conclusion.IsParts != value) { Conclusion.IsParts = value; OnPropertyChanged(); } } } public bool IsUnique { get => Conclusion.IsUnique; set { if (Conclusion.IsUnique != value) { Conclusion.IsUnique = value; OnPropertyChanged(); } } } public ConclusionLabel Conclusion { get; } public int Level { get => (int)Conclusion.Level; set { if (Conclusion != null) { Conclusion.Level = (MalignantLevel) value; } OnPropertyChanged(); } } public ConclusionLabelViewModel(ConclusionLabel conclusion) : base(conclusion.Id, conclusion.Title) { Conclusion = conclusion; } } public class LabelGroupViewModel : LabelObjectViewModel { private RootLabelViewModel _root; public RootLabelViewModel Root { get => _root; set { if (_root != value) { _root = value; foreach(var label in Labels) { label.Root = _root; } } } } public LabelGroup Group { get; } public override string Title { get => Group.Title; set { if (Group != null) { Group.Title = value; } } } public int Type { get { return (int)Group.Type; } set { Group.Type = (GroupType)value; } } public ObservableCollection Labels { get; protected set; } public LabelGroupViewModel(LabelGroup group) : base(group.Id, group.Title) { Group = group; Labels = new ObservableCollection(from x in Group.Labels select (x is DescriptionLabel) ? ((ImageLabelViewModel)new DescriptionLabelViewModel((DescriptionLabel)x)) : new ConclusionLabelViewModel((ConclusionLabel)x)); Labels.CollectionChanged += OnLabelsCollectionChanged; } private void OnLabelsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.OldItems != null) { foreach (var item in e.OldItems) { if (item is ImageLabelViewModel label) { var exists = Group.Labels.FirstOrDefault(x => x.Id == label.Id); if (exists != null) { Group.RemoveLabel(exists); } } } } if (e.NewItems != null) { foreach (var item in e.NewItems) { if (item is ImageLabelViewModel label) { var exists = Group.Labels.FirstOrDefault(x => x.Id == label.Id); if (exists == null) { if (label is DescriptionLabelViewModel description) { Group.AddLabel(description.Description); } else if (label is ConclusionLabelViewModel conclusion) { Group.AddLabel(conclusion.Conclusion); } } } } } } } public class MultiSelectionLabelGroupViewModel : LabelGroupViewModel { public MultiSelectionLabelGroupViewModel(MultiSelectionLabelGroup group) : base(group) { } } public class SingleSelectionLabelGroupViewModel : LabelGroupViewModel { public SingleSelectionLabelGroupViewModel(SingleSelectionLabelGroup group) : base(group) { } } public class RootLabelViewModel : LabelObjectViewModel { public override string Title { get => RootLabel.Title; set { if (RootLabel != null) { RootLabel.Title = value; } } } public bool NeedPartsConclusion { get => RootLabel.NeedPartsConclusion; set { if (RootLabel.NeedPartsConclusion != value) { RootLabel.NeedPartsConclusion = value; OnPropertyChanged(); } } } public RootLabel RootLabel { get; } public ObservableCollection Descriptions { get; } public ObservableCollection Conclusions { get; } public RootLabelViewModel(RootLabel rootLabel) : base(rootLabel.Id, rootLabel.Title) { RootLabel = rootLabel; Descriptions = new ObservableCollection(from x in RootLabel.Descriptions select (x is MultiSelectionLabelGroup) ? new MultiSelectionLabelGroupViewModel((MultiSelectionLabelGroup)x) { Root = this } : ((LabelGroupViewModel)new SingleSelectionLabelGroupViewModel((SingleSelectionLabelGroup)x) { Root = this })); Conclusions = new ObservableCollection(from x in RootLabel.Conclusions select (x is MultiSelectionLabelGroup) ? new MultiSelectionLabelGroupViewModel((MultiSelectionLabelGroup)x) { Root = this } : ((LabelGroupViewModel)new SingleSelectionLabelGroupViewModel((SingleSelectionLabelGroup)x) { Root = this })); Descriptions.CollectionChanged += OnDescriptionsCollectionChanged; Conclusions.CollectionChanged += OnConclusionsCollectionChanged; foreach(var descGroup in Descriptions) { foreach(var descLabel in descGroup.Labels) { var association = rootLabel.LabelAssociations.FirstOrDefault(x => x.Left.Id == descLabel.Id); if(association != null) { var conclusionId = association.Right.Id; foreach (var conGroup in Conclusions) { foreach (var conLabel in conGroup.Labels) { if(conLabel.Id == conclusionId) { descLabel.Linked = conLabel; } } } } } } } private void OnConclusionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.OldItems != null) { foreach (var item in e.OldItems) { if (item is LabelGroupViewModel group) { var exists = RootLabel.Conclusions.FirstOrDefault(x => x.Id == group.Id); if (exists != null) { RootLabel.RemoveConclusionGroup(exists); } } } } if (e.NewItems != null) { var index = e.NewStartingIndex; foreach (var item in e.NewItems) { if (item is LabelGroupViewModel group) { var exists = RootLabel.Conclusions.FirstOrDefault(x => x.Id == group.Id); if (exists == null) { RootLabel.InsertConclusionGroup(index, group.Group); } } index++; } } } private void OnDescriptionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.OldItems != null) { foreach (var item in e.OldItems) { if (item is LabelGroupViewModel group) { var exists = RootLabel.Descriptions.FirstOrDefault(x => x.Id == group.Id); if (exists != null) { RootLabel.RemoveDescriptionGroup(exists); } } } } if (e.NewItems != null) { var index = e.NewStartingIndex; foreach (var item in e.NewItems) { if (item is LabelGroupViewModel group) { var exists = RootLabel.Descriptions.FirstOrDefault(x => x.Id == group.Id); if (exists == null) { RootLabel.InsertDescriptionGroup(index,group.Group); } } index++; } } } } public class LabelContainerViewModel : ViewModel { private RootLabelViewModel _selectedRootLabel; public LabelContainer Container { get; } public RootLabelViewModel SelectedRootLabel { get => _selectedRootLabel; set { if (_selectedRootLabel != value) { _selectedRootLabel = value; OnPropertyChanged(); } } } public ObservableCollection Labels { get; } public LabelContainerViewModel(LabelContainer container) { Container = container; Labels = new ObservableCollection(from x in container.Labels select new RootLabelViewModel(x)); Labels.CollectionChanged += OnLabelsCollectionChanged; } private void OnLabelsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.OldItems != null) { foreach (var item in e.OldItems) { if (item is RootLabelViewModel label) { var exists = Container.Labels.FirstOrDefault(x => x.Id == label.Id); if (exists != null) { Container.Labels.Remove(exists); } } } } if (e.NewItems != null) { foreach (var item in e.NewItems) { if (item is RootLabelViewModel label) { var exists = Container.Labels.FirstOrDefault(x => x.Id == label.Id); if (exists == null) { Container.Labels.Add(label.RootLabel); } } } } } } }