using System;
namespace Otter {
///
/// Counter in which the value can be moved in both an X and Y direction. Probably most useful
/// for making menus that are grids which the player can move around in.
///
public class GridCounter : Component {
#region Private Fields
int x, y;
#endregion
#region Public Fields
///
/// The width of the grid.
///
public int Width;
///
/// The height of the grid.
///
public int Height;
///
/// Determines if the GridCounter should wrap horizontally.
///
public bool WrapX;
///
/// Determines if the GridCounter should wrap vertically.
///
public bool WrapY;
#endregion
#region Public Properties
///
/// The 1d value of the counter on the grid.
///
public int Index {
get { return Util.OneDee(Width, X, Y); }
set {
X = Util.TwoDeeX(value, Width);
Y = Util.TwoDeeY(value, Width);
}
}
///
/// Set both WrapX and WrapY.
///
public bool Wrap {
set { WrapX = value; WrapY = value; }
}
///
/// The total number of grid spaces.
///
public int Count {
get { return Width * Height; }
}
///
/// Move the index left.
///
public void MoveLeft() {
X -= 1;
}
///
/// Move the index right.
///
public void MoveRight() {
X += 1;
}
///
/// Move the index up.
///
public void MoveUp() {
Y -= 1;
}
///
/// Move the index down.
///
public void MoveDown() {
Y += 1;
}
///
/// The X value of the counter.
///
public int X {
set {
if (WrapX) {
x = value;
while (x < 0) {
x += Width;
}
while (x > Width - 1) {
x -= Width;
}
}
else {
x = (int)Util.Clamp(value, Width - 1);
}
}
get { return x; }
}
///
/// The Y value of the counter.
///
public int Y {
set {
if (WrapY) {
y = value;
while (y < 0) {
y += Height;
}
while (y > Height - 1) {
y -= Height;
}
}
else {
y = (int)Util.Clamp(value, Height - 1);
}
}
get { return y; }
}
#endregion
#region Constructors
///
/// Create a new GridCounter.
///
/// The initial value of the GridCounter.
/// The width of the grid.
/// The height of the grid.
/// Determines if the counter should wrap horizontally.
/// Determines if the counter should wrap vertically.
public GridCounter(int value, int width = 1, int height = 1, bool wrapX = false, bool wrapY = false) {
if (width < 1) {
throw new ArgumentException("Width must be at least 1!");
}
if (height < 1) {
throw new ArgumentException("Height must be at least 1!");
}
Width = width;
Height = height;
WrapX = wrapX;
WrapY = wrapY;
X = Util.TwoDeeX(value, width);
Y = Util.TwoDeeY(value, width);
}
#endregion
#region Operators
public static implicit operator float(GridCounter counter) {
return counter.Index;
}
public static implicit operator int(GridCounter counter) {
return (int)counter.Index;
}
#endregion
}
}