using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace SharpGLTF.Memory
{
///
/// Special accessor to wrap over a base accessor and a sparse accessor
///
/// An unmanage structure type.
[System.Diagnostics.DebuggerDisplay("Sparse {typeof(T).Name} Accessor {Count}")]
public struct SparseArray : IList, IReadOnlyList
where T : unmanaged
{
#region lifecycle
public SparseArray(IList bottom, IList top, IntegerArray topMapping)
{
_BottomItems = bottom;
_TopItems = top;
_Mapping = new Dictionary();
for (int val = 0; val < topMapping.Count; ++val)
{
var key = (int)topMapping[val];
_Mapping[key] = val;
}
}
#endregion
#region data
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private readonly IList _BottomItems;
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private readonly IList _TopItems;
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
private readonly Dictionary _Mapping;
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
private T[] _DebugItems => this.ToArray();
#endregion
#region API
[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
public int Count => _BottomItems.Count;
public bool IsReadOnly => true;
public T this[int index]
{
get => _Mapping.TryGetValue(index, out int topIndex) ? _TopItems[topIndex] : _BottomItems[index];
set => throw new NotSupportedException("Collection is read only.");
}
public IEnumerator GetEnumerator() { return new EncodedArrayEnumerator(this); }
IEnumerator IEnumerable.GetEnumerator() { return new EncodedArrayEnumerator(this); }
public bool Contains(T item) { return IndexOf(item) >= 0; }
public int IndexOf(T item) { return this._FirstIndexOf(item); }
public void CopyTo(T[] array, int arrayIndex) { this._CopyTo(array, arrayIndex); }
void IList.Insert(int index, T item) { throw new NotSupportedException(); }
void IList.RemoveAt(int index) { throw new NotSupportedException(); }
void ICollection.Add(T item) { throw new NotSupportedException(); }
void ICollection.Clear() { throw new NotSupportedException(); }
bool ICollection.Remove(T item) { throw new NotSupportedException(); }
#endregion
}
}