using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Svg { /// /// Represents a collection of s. /// public sealed class SvgElementCollection : IList { private List _elements; private SvgElement _owner; private bool _mock; /// /// Initialises a new instance of an class. /// /// The owner of the collection. internal SvgElementCollection(SvgElement owner) : this(owner, false) { } internal SvgElementCollection(SvgElement owner, bool mock) { if (owner == null) { throw new ArgumentNullException("owner"); } this._elements = new List(); this._owner = owner; this._mock = mock; } /// /// Returns the index of the specified in the collection. /// /// The to search for. /// The index of the element if it is present; otherwise -1. public int IndexOf(SvgElement item) { return this._elements.IndexOf(item); } /// /// Inserts the given to the collection at the specified index. /// /// The index that the should be added at. /// The to be added. public void Insert(int index, SvgElement item) { InsertAndForceUniqueID(index, item, false, false); } public void InsertAndForceUniqueID(int index, SvgElement item, bool autoForceUniqueID = true, bool autoFixChildrenID = true, Action logElementOldIDNewID = null) { AddToIdManager(item, this._elements[index], autoForceUniqueID, autoFixChildrenID, logElementOldIDNewID); this._elements.Insert(index, item); item._parent.OnElementAdded(item, index); } public void RemoveAt(int index) { SvgElement element = this[index]; if (element != null) { this.Remove(element); } } public SvgElement this[int index] { get { return this._elements[index]; } set { this._elements[index] = value; } } public void Add(SvgElement item) { this.AddAndForceUniqueID(item, false, false); } public void AddAndForceUniqueID(SvgElement item, bool autoForceUniqueID = true, bool autoFixChildrenID = true, Action logElementOldIDNewID = null) { AddToIdManager(item, null, autoForceUniqueID, autoFixChildrenID, logElementOldIDNewID); this._elements.Add(item); item._parent.OnElementAdded(item, this.Count - 1); } private void AddToIdManager(SvgElement item, SvgElement sibling, bool autoForceUniqueID = true, bool autoFixChildrenID = true, Action logElementOldIDNewID = null) { if (!this._mock) { if (this._owner.OwnerDocument != null) { this._owner.OwnerDocument.IdManager.AddAndForceUniqueID(item, sibling, autoForceUniqueID, logElementOldIDNewID); if (!(item is SvgDocument)) //don't add subtree of a document to parent document { foreach (var child in item.Children) { child.ApplyRecursive(e => this._owner.OwnerDocument.IdManager.AddAndForceUniqueID(e, null, autoFixChildrenID, logElementOldIDNewID)); } } } //if all checked, set parent item._parent = this._owner; } } public void Clear() { while (this.Count > 0) { SvgElement element = this[0]; this.Remove(element); } } public bool Contains(SvgElement item) { return this._elements.Contains(item); } public void CopyTo(SvgElement[] array, int arrayIndex) { this._elements.CopyTo(array, arrayIndex); } public int Count { get { return this._elements.Count; } } public bool IsReadOnly { get { return false; } } public bool Remove(SvgElement item) { bool removed = this._elements.Remove(item); if (removed) { this._owner.OnElementRemoved(item); if (!this._mock) { item._parent = null; if (this._owner.OwnerDocument != null) { item.ApplyRecursiveDepthFirst(this._owner.OwnerDocument.IdManager.Remove); } } } return removed; } /// /// expensive recursive search for nodes of type T /// /// /// public IEnumerable FindSvgElementsOf() where T : SvgElement { return _elements.Where(x => x is T).Select(x => x as T).Concat(_elements.SelectMany(x => x.Children.FindSvgElementsOf())); } /// /// expensive recursive search for first node of type T /// /// /// public T FindSvgElementOf() where T : SvgElement { return _elements.OfType().FirstOrDefault() ?? _elements.Select(x => x.Children.FindSvgElementOf()).FirstOrDefault(x => x != null); } public T GetSvgElementOf() where T : SvgElement { return _elements.FirstOrDefault(x => x is T) as T; } public IEnumerator GetEnumerator() { return this._elements.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this._elements.GetEnumerator(); } } }