using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
namespace Robust.Shared.Map
{
///
/// This is a collection of tiles in a grid format.
///
[PublicAPI]
public interface IMapGrid
{
///
/// The integer ID of the map this grid is currently located within.
///
MapId ParentMapId { get; set; }
///
/// The entity this grid is represented by in the ECS system.
///
EntityUid GridEntityId { get; }
///
/// The identifier of this grid.
///
GridId Index { get; }
///
/// The length of the side of a square tile in world units.
///
ushort TileSize { get; }
///
/// The bounding box of the grid in world coordinates.
///
Box2 WorldBounds { get; }
///
/// The bounding box of the grid in local coordinates.
///
Box2 LocalBounds { get; }
///
/// The length of a side of the square chunk in number of tiles.
///
ushort ChunkSize { get; }
///
/// The origin of the grid in world coordinates. Make sure to set this!
///
Vector2 WorldPosition { get; set; }
///
/// The rotation of the grid in world terms.
///
Angle WorldRotation { get; set; }
Matrix3 WorldMatrix { get; }
Matrix3 InvWorldMatrix { get; }
#region TileAccess
///
/// Gets a tile a the given world coordinates. This will not create a new chunk.
///
/// The location of the tile in coordinates.
/// The tile at the world coordinates.
TileRef GetTileRef(MapCoordinates coords);
///
/// Gets a tile a the given world coordinates. This will not create a new chunk.
///
/// The location of the tile in coordinates.
/// The tile at the world coordinates.
TileRef GetTileRef(EntityCoordinates coords);
///
/// Gets a tile a the given grid indices. This will not create a new chunk.
///
/// The location of the tile in coordinates.
/// The tile at the tile coordinates.
TileRef GetTileRef(Vector2i tileCoordinates);
///
/// Returns all tiles in the grid, in row-major order [xTileIndex, yTileIndex].
///
/// All tiles in the chunk.
IEnumerable GetAllTiles(bool ignoreSpace = true);
///
/// Replaces a single tile inside of the grid.
///
///
/// The tile to insert at the coordinates.
void SetTile(EntityCoordinates coords, Tile tile);
///
/// Modifies a single tile inside of the chunk.
///
///
/// The tile to insert at the coordinates.
void SetTile(Vector2i gridIndices, Tile tile);
///
/// Modifies many tiles inside of a chunk. Avoids regenerating collision until the end.
///
///
void SetTiles(List<(Vector2i GridIndices, Tile Tile)> tiles);
IEnumerable GetTilesIntersecting(Box2Rotated worldArea, bool ignoreEmpty = true, Predicate? predicate = null);
///
/// Returns all tiles inside the area that match the predicate.
///
/// An area in the world to search for tiles.
/// Will empty tiles be returned?
/// Optional predicate to filter the files.
///
IEnumerable GetTilesIntersecting(Box2 worldArea, bool ignoreEmpty = true, Predicate? predicate = null);
IEnumerable GetTilesIntersecting(Circle worldArea, bool ignoreEmpty = true, Predicate? predicate = null);
#endregion TileAccess
#region SnapGridAccess
IEnumerable GetAnchoredEntities(MapCoordinates coords);
IEnumerable GetAnchoredEntities(EntityCoordinates coords);
IEnumerable GetAnchoredEntities(Vector2i pos);
IEnumerable GetAnchoredEntities(Box2 worldAABB);
IEnumerable GetAnchoredEntities(Box2Rotated worldBounds);
// Struct enumerators
AnchoredEntitiesEnumerator GetAnchoredEntitiesEnumerator(Vector2i pos);
Vector2i TileIndicesFor(EntityCoordinates coords) => CoordinatesToTile(coords);
Vector2i TileIndicesFor(MapCoordinates worldPos) => CoordinatesToTile(MapToGrid(worldPos));
Vector2i TileIndicesFor(Vector2 worldPos) => WorldToTile(worldPos);
bool AddToSnapGridCell(Vector2i pos, EntityUid euid);
bool AddToSnapGridCell(EntityCoordinates coords, EntityUid euid);
void RemoveFromSnapGridCell(Vector2i pos, EntityUid euid);
void RemoveFromSnapGridCell(EntityCoordinates coords, EntityUid euid);
///
/// Returns an enumerable over all the entities which are one tile over in a certain direction.
///
IEnumerable GetInDir(EntityCoordinates position, Direction dir);
IEnumerable GetOffset(EntityCoordinates coords, Vector2i offset);
IEnumerable GetLocal(EntityCoordinates coords);
EntityCoordinates DirectionToGrid(EntityCoordinates coords, Direction direction);
IEnumerable GetCardinalNeighborCells(EntityCoordinates coords);
IEnumerable GetCellsInSquareArea(EntityCoordinates coords, int n);
#endregion SnapGridAccess
#region Transforms
///
/// Transforms EntityCoordinates to a local tile location.
///
///
///
Vector2i CoordinatesToTile(EntityCoordinates coords);
///
/// Transforms world-space coordinates from the global origin to the grid local origin.
///
/// The world-space coordinates with global origin.
/// The world-space coordinates with local origin.
Vector2 WorldToLocal(Vector2 posWorld);
///
/// Transforms map coordinates to grid coordinates.
///
EntityCoordinates MapToGrid(MapCoordinates posWorld);
///
/// Transforms local vectors into world space vectors
///
/// The local vector with this grid as origin.
/// The world-space vector with global origin.
Vector2 LocalToWorld(Vector2 posLocal);
///
/// Transforms World position into grid tile indices.
///
/// Position in the world.
/// Indices of a tile on the grid.
Vector2i WorldToTile(Vector2 posWorld);
///
/// Transforms grid-space tile indices to local coordinates.
/// The resulting coordinates are centered on the tile.
///
///
///
EntityCoordinates GridTileToLocal(Vector2i gridTile);
///
/// Transforms grid-space tile indices to map coordinate position.
/// The resulting coordinates are centered on the tile.
///
Vector2 GridTileToWorldPos(Vector2i gridTile);
///
/// Transforms grid-space tile indices to map coordinates.
/// The resulting coordinates are centered on the tile.
///
MapCoordinates GridTileToWorld(Vector2i gridTile);
///
/// Transforms grid indices into a tile reference, returns false if no tile is found.
///
/// The Grid Tile indices.
///
///
bool TryGetTileRef(Vector2i indices, out TileRef tile);
///
/// Transforms coordinates into a tile reference, returns false if no tile is found.
///
/// The coordinates.
///
///
bool TryGetTileRef(EntityCoordinates coords, out TileRef tile);
///
/// Transforms a world position into a tile reference, returns false if no tile is found.
///
bool TryGetTileRef(Vector2 worldPos, out TileRef tile);
///
/// Transforms grid tile indices to chunk indices.
///
Vector2i GridTileToChunkIndices(Vector2i gridTile);
///
/// Transforms EntityCoordinates to chunk indices relative to grid origin.
///
Vector2i LocalToChunkIndices(EntityCoordinates gridPos);
Vector2 LocalToGrid(EntityCoordinates position);
#endregion Transforms
#region Collision
bool CollidesWithGrid(Vector2i indices);
#endregion
}
}