using System;
using System.Diagnostics.CodeAnalysis;
namespace NHSE.Core;
///
/// Basic configuration of a narrow view for interacting with the larger manipulatable tile grid.
///
/// Viewable amount of viewable tiles wide
/// Viewable amount of viewable tiles high
/// Columns of view available
/// Rows of view available
public readonly record struct TileGridViewport([ConstantExpected] byte ViewWidth, [ConstantExpected] byte ViewHeight, byte Columns, byte Rows)
{
///
/// Total width of the entire grid (including the view).
///
public int TotalWidth => Columns * ViewWidth;
///
/// Total height of the entire grid (including the view).
///
public int TotalHeight => Rows * ViewHeight;
///
/// Amount of tiles present in the grid.
///
public int ViewCount => ViewWidth * ViewHeight;
///
/// Amount of ALL tiles present in the entire grid (including the grid).
///
public int TotalCount => TotalWidth * TotalHeight;
///
/// Gets the dimensions of the viewable area (an acre-worth).
///
public (int X, int Y) DimAcre => (ViewWidth, ViewHeight);
///
/// Gets the total dimensions of the entire grid (including the view).
///
public (int X, int Y) DimTotal => (TotalWidth, TotalHeight);
///
/// Gets the absolute index of the absolute tile in the grid based on the x/y coordinates.
///
/// Relative X-coordinate of the tile in the grid
/// Relative Y-coordinate of the tile in the grid
/// Absolute index of the tile in the grid
public int GetTileIndex(in int relX, in int relY) => (TotalHeight * relX) + relY;
///
/// Clamps the specified relative X and Y coordinates so that they remain within the valid bounds of the area.
///
///
/// Use this method to prevent coordinates from exceeding the valid area,
/// which may help avoid out-of-bounds errors when working with grid-based data or images.
///
/// The relative X coordinate to clamp.
/// The relative Y coordinate to clamp.
public void ClampInside(ref int relX, ref int relY)
=> ClampCoordinatesTo(ref relX, ref relY, TotalWidth - 1, TotalHeight - 1);
private static void ClampCoordinatesTo(ref int relX, ref int relY, int maxX, int maxY)
{
relX = Math.Clamp(relX, 0, maxX);
relY = Math.Clamp(relY, 0, maxY);
}
///
/// Determines whether the specified relative coordinates are within the bounds of the area.
///
/// The horizontal coordinate, relative to the left edge of the area.
/// The vertical coordinate, relative to the top edge of the area.
/// if the specified coordinates are within the bounds; otherwise, .
public bool Contains(int relX, int relY) => !((uint)relX >= TotalWidth || (uint)relY >= TotalHeight);
}