using System;
using System.Collections;
using System.Collections.Generic;
using Swan.Configuration;
namespace Swan.Collections
{
///
/// Implements a collection of components.
/// Each component in the collection may be given a unique name for later retrieval.
///
/// The type of components in the collection.
///
public class ComponentCollection : ConfiguredObject, IComponentCollection
{
private readonly List _components = new List();
private readonly List<(string, T)> _componentsWithSafeNames = new List<(string, T)>();
private readonly Dictionary _namedComponents = new Dictionary();
///
public int Count => _components.Count;
///
public IReadOnlyDictionary Named => _namedComponents;
///
public IReadOnlyList<(string SafeName, T Component)> WithSafeNames => _componentsWithSafeNames;
///
public T this[int index] => _components[index];
///
public T this[string key] => _namedComponents[key];
///
public IEnumerator GetEnumerator() => _components.GetEnumerator();
///
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_components).GetEnumerator();
///
/// The collection is locked.
public void Add(string name, T component)
{
EnsureConfigurationNotLocked();
if (name != null)
{
if (name.Length == 0)
throw new ArgumentException("Component name is empty.", nameof(name));
if (_namedComponents.ContainsKey(name))
throw new ArgumentException("Duplicate component name.", nameof(name));
}
if (component == null)
throw new ArgumentNullException(nameof(component));
if (_components.Contains(component))
throw new ArgumentException("Component has already been added.", nameof(component));
_components.Add(component);
_componentsWithSafeNames.Add((name ?? $"<{component.GetType().Name}>", component));
if (name != null)
_namedComponents.Add(name, component);
}
///
/// Locks the collection, preventing further additions.
///
public void Lock() => LockConfiguration();
}
}