using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using Pf2e.Common; using Pf2e.Database; using Pf2e.Scrapper.Helpers; using Pf2e.Scrapper.WPF.EntityViewer.EntityViewStructure; using Pf2e.Scrapper.WPF.EntityViewer.Stores; using Pf2e.WPF.EntityViewer.EntityViewStructure; using Pf2e.WPF.EntityViewer.Stores; namespace Pf2e.WPF.EntityViewer.ViewModel; internal class ViewViewModel : ViewModelBase { public Pf2eDbContext Context { get; } public SelectedEntityStore SelectedEntityStore { get; } public FullEntity? CurrentEntityView { get => _currentEntityView; set { _currentEntityView = value; OnPropertyChanged(); } } private FullEntity? _currentEntityView; public ObservableCollection Rows { get => _rows; set { _rows = value; OnPropertyChanged(); } } private ObservableCollection _rows = []; private readonly List _fields = []; private readonly List _allRows = []; public ViewViewModel(Pf2eDbContext context, SelectedEntityStore selectedEntityStore) { Context = context; SelectedEntityStore = selectedEntityStore; SelectedEntityStore.SelectedEntityChanged += SelectedEntityStore_SelectedEntityTypeChanged; } ~ViewViewModel() { SelectedEntityStore.SelectedEntityChanged -= SelectedEntityStore_SelectedEntityTypeChanged; } private void SelectedEntityStore_SelectedEntityTypeChanged(Database.Model.Base.Entity? entity) { if (entity is null) { CurrentEntityView = null; return; } CurrentEntityView = new(Context, entity.Type, entity.Id); if (CurrentEntityView.Entity is null) { CurrentEntityView = null; return; } StructureBuilder builder = new(); _fields.Clear(); _fields.Add(builder.Create("Entity", CurrentEntityView.Entity)); if (CurrentEntityView.SubEntity is not null) { string typeName = CurrentEntityView.SubEntity.GetType().Name; _fields.Add(builder.Create(typeName, CurrentEntityView.SubEntity)); } _allRows.Clear(); _allRows.AddRange( _fields.SelectMany(field => field.GetRows(structureField => new StructureRow(structureField)) ) ); Rows.Clear(); foreach (StructureRow row in _allRows) { Rows.Add(row); row.OnChange += Row_OnChange; } BuildLadder(); OnPropertyChanged(nameof(Rows)); } private void Row_OnChange(StructureRow row, StructureField field) { OnPropertyChanged(nameof(Rows)); } /// /// Построение лестницы для строк полей структуры. /// private void BuildLadder() { List lastLadder = []; for (int i = Rows.Count - 1; i >= 0; i--) { StructureRow row = Rows[i]; List ladder; if (row.Depth == 0) { ladder = []; } else if (row.Depth < lastLadder.Count) { ladder = [ .. lastLadder[..(row.Depth - 1)], lastLadder[row.Depth - 1] == LadderType.Empty ? LadderType.Last : LadderType.Through, ]; } else if (row.Depth == lastLadder.Count) { ladder = lastLadder; } else { ladder = [ .. lastLadder, .. Enumerable.Repeat(LadderType.Empty, row.Depth - lastLadder.Count - 1), LadderType.Last, ]; } row.Ladder = ladder; lastLadder = ladder.Select(l => l == LadderType.Last ? LadderType.Through : l).ToList(); } } }