using System;

namespace Grid {
    public readonly struct GridPosition : IEquatable<GridPosition> {
        public int XPosition { get; }
        public int ZPosition { get; }
        public int Floor { get; }

        public GridPosition(int xPosition, int zPosition, int floor) {
            XPosition = xPosition;
            ZPosition = zPosition;
            Floor = floor;
        }

        public override string ToString() => $"X: {XPosition}; Z: {ZPosition}; Floor: {Floor}";
        public static bool operator ==(GridPosition a, GridPosition b) => a.XPosition == b.XPosition && a.ZPosition == b.ZPosition && a.Floor == b.Floor;
        public static bool operator !=(GridPosition a, GridPosition b) => a.XPosition != b.XPosition || a.ZPosition != b.ZPosition || a.Floor != b.Floor;
        public override bool Equals(object gridPositionObject) => gridPositionObject is GridPosition gridPosition && Equals(gridPosition);
        public override int GetHashCode() => HashCode.Combine(XPosition, ZPosition, Floor);
        public bool Equals(GridPosition gridPosition) => XPosition == gridPosition.XPosition && ZPosition == gridPosition.ZPosition && Floor == gridPosition.Floor;
        public static GridPosition operator +(GridPosition a, GridPosition b) => new(a.XPosition + b.XPosition, a.ZPosition + b.ZPosition, a.Floor + b.Floor);
        public static GridPosition operator -(GridPosition a, GridPosition b) => new(a.XPosition - b.XPosition, a.ZPosition - b.ZPosition, a.Floor - b.Floor);
    }
}