using System;
using System.Collections;
using System.Collections.Generic;
namespace MonoGame.Extended.Tilemaps
{
///
/// A collection of tilesets used by a tilemap.
///
public class TilemapTilesetCollection : IReadOnlyList
{
private readonly List _tilesets = new();
///
/// Gets the tileset at the specified index.
///
/// The zero-based index of the tileset to get.
/// The tileset at the specified index.
public TilemapTileset this[int index]
{
get
{
return _tilesets[index];
}
}
///
/// Gets the number of tilesets in the collection.
///
public int Count
{
get
{
return _tilesets.Count;
}
}
///
/// Adds a tileset to the collection.
///
/// The tileset to add.
///
/// This method is not thread-safe. If multiple threads are accessing the collection,
/// external synchronization is required.
///
public void Add(TilemapTileset tileset)
{
if (tileset == null)
throw new ArgumentNullException(nameof(tileset));
_tilesets.Add(tileset);
}
///
/// Removes a tileset from the collection.
///
/// The tileset to remove.
/// if the tileset was removed; otherwise, .
///
/// This is an O(n) operation. This method is not thread-safe.
///
public bool Remove(TilemapTileset tileset)
{
return _tilesets.Remove(tileset);
}
///
/// Removes all tilesets from the collection.
///
///
/// Warning: This operation cannot be undone and will remove all tileset references.
/// This method is not thread-safe.
///
public void Clear()
{
_tilesets.Clear();
}
///
/// Gets the tileset that contains the specified global tile ID.
///
/// The global tile ID.
/// The tileset containing the tile, or if not found.
public TilemapTileset GetTilesetForGid(int globalTileId)
{
// Tilesets are ordered by FirstGlobalId
// Find the tileset where: globalTileId >= FirstGlobalId
// and globalTileId < next tileset's FirstGlobalId
TilemapTileset result = null;
for (int i = 0; i < _tilesets.Count; i++)
{
var tileset = _tilesets[i];
// Check if this tile ID belongs to this tileset
if (globalTileId >= tileset.FirstGlobalId)
{
// Check if this GID is within the tileset's range
int localId = globalTileId - tileset.FirstGlobalId;
if(localId < tileset.TileCount)
{
result = tileset;
break;
}
}
}
return result;
}
///
/// Gets the local tile ID within a tileset from a global tile ID.
///
/// The global tile ID.
/// When this method returns, contains the tileset that owns the tile.
/// The local tile ID within the tileset.
/// No tileset contains the specified global tile ID.
public int GetLocalId(int globalTileId, out TilemapTileset tileset)
{
var foundTileset = GetTilesetForGid(globalTileId);
if (foundTileset == null)
{
throw new InvalidOperationException($"No tileset found for global tile ID {globalTileId}.");
}
tileset = foundTileset;
return globalTileId - foundTileset.FirstGlobalId;
}
public IEnumerator GetEnumerator()
{
return _tilesets.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}