using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace OpenVIII
{
///
/// List of KeyValuePairs
/// TKey cannot be int use a List
///
///
///
public sealed class OrderedDictionary : IDictionary
{
#region Fields
private List> _list;
#endregion Fields
#region Constructors
public OrderedDictionary(int capacity = 0) => _list = new List>(capacity);
public OrderedDictionary(IDictionary copy) : this(copy.Count)
{
foreach (KeyValuePair pair in copy)
{
Add(new KeyValuePair(pair.Key, pair.Value));
}
}
#endregion Constructors
#region Properties
public bool IsFixedSize => false;
public bool IsReadOnly => false;
public bool IsSynchronized => false;
public IReadOnlyList Keys => _list.Select(kvp => kvp.Key).ToList();
public IReadOnlyList Values => _list.Select(kvp => kvp.Value).ToList();
public int Count => _list.Count;
ICollection IDictionary.Keys => _list.Select(kvp => kvp.Key).ToArray();
ICollection IDictionary.Values => _list.Select(kvp => kvp.Value).ToArray();
#endregion Properties
#region Indexers
public KeyValuePair this[int index]
{
get
{
if (TryGetKVPByIndex(index, out KeyValuePair kvp))
return kvp;
throw new KeyNotFoundException($"{this}::Index:{index} - Not Found!");
}
}
public TValue this[TKey key]
{
get
{
if (TryGetByKey(key, out TValue value))
return value;
throw new KeyNotFoundException($"{this}::Key:{key} - Not Found!");
}
set
{
int index = _list.FindIndex(kvp => kvp.Key.Equals(key));
if (index >= 0)
_list[index] = new KeyValuePair(key, value);
else
throw new KeyNotFoundException($"{this}::Key:{key} - Not Found!");
}
}
TValue IDictionary.this[TKey key]
{
get => this[key];
set => this[key] = value;
}
#endregion Indexers
#region Methods
public void Add(TKey key, TValue value)
{
if (!TryAdd(key, value)) throw new ArgumentException($"{this}::Key:{key} - Already Exists!");
}
public void Add(KeyValuePair item) => Add(item.Key, item.Value);
public void Clear() => _list.Clear();
public bool Contains(KeyValuePair item) => _list.Contains(item);
public Boolean ContainsIndex(Int32 index) => index < _list.Count;
public Boolean ContainsKey(TKey key) => _list.Any(kvp => kvp.Key.Equals(key));
public Boolean ContainsValue(TValue value) => _list.Any(kvp => kvp.Value.Equals(value));
public void CopyTo(KeyValuePair[] array, int arrayIndex)
{
if (Count <= array.Length + arrayIndex)
{
foreach (KeyValuePair i in _list)
{
array[arrayIndex++] = i;
}
return;
}
throw new OverflowException($"{this}::Count:{Count} > array.Length:{array.Length} + arrayIndex:{arrayIndex}");
}
public IEnumerator GetEnumerator() => _list.GetEnumerator();
public bool Remove(TKey key)
{
KeyValuePair kvp = _list.First(_kvp => _kvp.Key.Equals(key));
return _list.Remove(kvp);
}
public bool Remove(KeyValuePair item) => _list.Remove(item);
public bool TryAdd(TKey key, TValue value)
{
if (!ContainsKey(key))
{
_list.Add(new KeyValuePair(key, value));
return true;
}
return false;
}
public Boolean TryGetByIndex(Int32 index, out TValue value)
{
if (ContainsIndex(index))
{
value = _list[index].Value;
return true;
}
value = default;
return false;
}
public Boolean TryGetByKey(TKey key, out TValue value)
{
if (ContainsKey(key))
{
value = _list.First(kvp => kvp.Key.Equals(key)).Value;
return true;
}
value = default;
return false;
}
public Boolean TryGetIndexByKey(TKey key, out int value)
{
if (ContainsKey(key))
{
value = _list.FindIndex(kvp => kvp.Key.Equals(key));
return true;
}
value = -1;
return false;
}
public Boolean TryGetKeyByIndex(Int32 index, out TKey value)
{
if (ContainsIndex(index))
{
value = _list[index].Key;
return true;
}
value = default;
return false;
}
public Boolean TryGetKVPByIndex(Int32 index, out KeyValuePair value)
{
if (ContainsIndex(index))
{
value = _list[index];
return true;
}
value = default;
return false;
}
public bool TryGetValue(TKey key, out TValue value) => TryGetByKey(key, out value);
public OrderedDictionary Clone() => new OrderedDictionary(this);
IEnumerator> IEnumerable>.GetEnumerator() => _list.GetEnumerator();
#endregion Methods
}
}