using System.Collections;
using System.Collections.Generic;
using System.Text;
using JetBrains.Annotations;
using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute;
namespace SharpNBT
{
///
/// Base class for tags that contain a collection of values and can be enumerated.
///
/// The type of the item the tag contains.
[PublicAPI]
public abstract class EnumerableTag : Tag, IList
{
///
/// Internal list implementation.
///
private readonly List list;
///
/// Initializes a new instance of the .
///
/// A constant describing the NBT type for this tag.
/// The name of the tag, or if tag has no name.
protected EnumerableTag(TagType type, [CanBeNull] string name) : base(type, name)
{
list = new List();
}
///
/// Initializes a new instance of the with the specified .
///
/// A constant describing the NBT type for this tag.
/// The name of the tag, or if tag has no name.
/// A collection of values to include in this tag.
protected EnumerableTag(TagType type, [CanBeNull] string name, [NotNull] IEnumerable values) : base(type, name)
{
list = new List(values);
}
/// Returns an enumerator that iterates through the collection.
/// An enumerator that can be used to iterate through the collection.
///
public IEnumerator GetEnumerator() => list.GetEnumerator();
/// Returns an enumerator that iterates through a collection.
/// An object that can be used to iterate through the collection.
///
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)list).GetEnumerator();
/// Adds an item to the .
/// The object to add to the .
/// The is read-only.
///
[SuppressMessage("ReSharper", "AnnotationConflictInHierarchy")]
public void Add([NotNull] T item)
{
if (item is Tag child)
child.Parent = this;
list.Add(item);
}
///
/// Adds the elements of the specified collection to the .
///
/// A collection containing the items to add.
public void AddRange([NotNull] [ItemNotNull] IEnumerable items)
{
foreach (var item in items)
Add(item);
}
/// Inserts an item to the at the specified index.
/// The zero-based index at which should be inserted.
/// The object to insert into the .
///
/// is not a valid index in the .
/// The is read-only.
///
[SuppressMessage("ReSharper", "AnnotationConflictInHierarchy")]
public void Insert(int index, [NotNull] T item)
{
if (item is Tag child)
child.Parent = this;
list.Insert(index, item);
}
/// Gets or sets the element at the specified index.
/// The zero-based index of the element to get or set.
///
/// is not a valid index in the .
/// The property is set and the is read-only.
/// The element at the specified index.
///
[NotNull]
public T this[int index]
{
get => list[index];
set
{
if (value is Tag child)
child.Parent = this;
list[index] = value;
}
}
/// Removes all items from the .
/// The is read-only.
///
public void Clear()
{
foreach (var item in list)
{
if (item is Tag child)
child.Parent = null;
}
list.Clear();
}
/// Determines whether the contains a specific value.
/// The object to locate in the .
///
/// if is found in the ; otherwise, .
///
public bool Contains(T item) => list.Contains(item);
/// Copies the elements of the to an , starting at a particular index.
/// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing.
/// The zero-based index in at which copying begins.
///
/// is .
///
/// is less than 0.
/// The number of elements in the source is greater than the available space from to the end of the destination .
///
public void CopyTo(T[] array, int arrayIndex) => list.CopyTo(array, arrayIndex);
/// Removes the first occurrence of a specific object from the .
/// The object to remove from the .
/// The is read-only.
///
/// if was successfully removed from the ; otherwise, . This method also returns if is not found in the original .
///
public bool Remove(T item)
{
if (list.Remove(item))
{
if (item is Tag child)
child.Parent = null;
return true;
}
return false;
}
/// Gets the number of elements contained in the .
/// The number of elements contained in the .
///
public int Count => list.Count;
/// Gets a value indicating whether the is read-only.
///
/// if the is read-only; otherwise, .
///
public bool IsReadOnly => false;
/// Determines the index of a specific item in the .
/// The object to locate in the .
/// The index of if found in the list; otherwise, -1.
///
public int IndexOf(T item) => list.IndexOf(item);
/// Removes the item at the specified index.
/// The zero-based index of the item to remove.
///
/// is not a valid index in the .
/// The is read-only.
///
public void RemoveAt(int index)
{
if (list[index] is Tag child)
child.Parent = null;
list.RemoveAt(index);
}
protected internal override void PrettyPrinted(StringBuilder buffer, int level, string indent)
{
for (var i = 0; i < level; i++)
buffer.Append(indent);
buffer.AppendLine(ToString());
}
}
}