using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using SkiaSharp; using Stylet; namespace Artemis.Core.Models.Profile { public abstract class ProfileElement : PropertyChangedBase { protected List _children; protected ProfileElement() { _children = new List(); } public Guid EntityId { get; internal set; } public Profile Profile { get; internal set; } public ProfileElement Parent { get; internal set; } /// /// The element's children /// public ReadOnlyCollection Children => _children.AsReadOnly(); /// /// The order in which this element appears in the update loop and editor /// public int Order { get; internal set; } /// /// The name which appears in the editor /// public string Name { get; set; } /// /// Updates the element /// /// public abstract void Update(double deltaTime); /// /// Renders the element /// public abstract void Render(double deltaTime, SKCanvas canvas); /// /// Applies the profile element's properties to the underlying storage entity /// internal abstract void ApplyToEntity(); public List GetAllFolders() { var folders = new List(); foreach (var childFolder in Children.Where(c => c is Folder).Cast()) { // Add all folders in this element folders.Add(childFolder); // Add all folders in folders inside this element folders.AddRange(childFolder.GetAllFolders()); } return folders; } public List GetAllLayers() { var layers = new List(); // Add all layers in this element layers.AddRange(Children.Where(c => c is Layer).Cast()); // Add all layers in folders inside this element foreach (var childFolder in Children.Where(c => c is Folder).Cast()) layers.AddRange(childFolder.GetAllLayers()); return layers; } /// /// Adds a profile element to the collection, optionally at the given position (1-based) /// /// The profile element to add /// The order where to place the child (1-based), defaults to the end of the collection public void AddChild(ProfileElement child, int? order = null) { lock (_children) { // Add to the end of the list if (order == null) { _children.Add(child); child.Order = _children.Count; return; } // Shift everything after the given order foreach (var profileElement in _children.Where(c => c.Order >= order).ToList()) profileElement.Order++; int targetIndex; if (order == 0) targetIndex = 0; else if (order > _children.Count) targetIndex = _children.Count; else targetIndex = _children.FindIndex(c => c.Order == order + 1); _children.Insert(targetIndex, child); child.Order = order.Value; child.Parent = this; } } /// /// Removes a profile element from the collection /// /// The profile element to remove public void RemoveChild(ProfileElement child) { lock (_children) { _children.Remove(child); // Shift everything after the given order foreach (var profileElement in _children.Where(c => c.Order > child.Order).ToList()) profileElement.Order--; child.Parent = null; } } } }