using HPJ.Simulation.Enums;
using HPJ.Simulation.Utilities;
using System.Linq;

namespace HPJ.Simulation.Map
{
    /// <summary>
    /// A Flattenned version of a map that changes every tile type into a 1 or 0. Is it traverable or is it not
    /// </summary>
    [System.Serializable]
    public class BytePointMap
    {
        private byte[,] _tiles;
        /// <summary>
        /// The Tiles for the Byte Map
        /// </summary>
        public byte[,] Tiles { get { return _tiles; } }
        private int _width;
        /// <summary>
        /// The Width of the Byte Map
        /// </summary>
        public int Width { get { return _width; } }

        private int _length;
        /// <summary>
        /// The Length of the Byte Map
        /// </summary>
        public int Length { get { return _length; } }

        private bool _cornerCutting;
        /// <summary>
        ///  Whether corner cuttins is enabled on this map
        /// </summary>
        public bool CornerCutting { get { return _cornerCutting; } set { _cornerCutting = value; } }

        private string _traversableKey;
        /// <summary>
        /// The Key used to flatten the map 
        /// </summary>
        public string TraversableKey { get { return _traversableKey; } }

        private TileTypes[] _traversable;
        /// <summary>
        /// The Tiles that are traversable on this map
        /// </summary>
        public TileTypes[] Traversable { get { return _traversable; } }

        public BytePointMap(byte[,] TileTypeMap, TileTypes[] TraversableTiles, int TileMapWidth, int TileMapLength, bool CornerCuttingEnabled)
        {
            _traversable = TraversableTiles;
            _traversableKey = TraversableTiles.TilesToString();
            _cornerCutting = CornerCuttingEnabled;
            _tiles = new byte[TileMapWidth, TileMapLength];
            _width = TileMapWidth;
            _length = TileMapLength;

            for (int x = 0; x < TileMapWidth; x++)
            {
                for (int y = 0; y < TileMapLength; y++)
                {
                    if (_traversable.Contains((TileTypes)TileTypeMap[x, y]))
                    {
                        _tiles[x, y] = 100;
                    }
                    else
                    {
                        _tiles[x, y] = 0;
                    }
                }
            }
        }

        /// <summary>
        /// Changes the tile of the byte map
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="newType"></param>
        public void ChangeTile(int x, int y, TileTypes newType)
        {
            if (_traversable.Contains(newType))
            {
                _tiles[x, y] = 100;
            }
            else
            {
                _tiles[x, y] = 0;
            }
        }

        /// <summary>
        /// Changes the tile of the byte map
        /// </summary>
        /// <param name="TileIndex"></param>
        /// <param name="newType"></param>
        public void ChangeTile(IntVector2 TileIndex, TileTypes newType)
        {
            if (_traversable.Contains(newType))
            {
                _tiles[TileIndex.x, TileIndex.y] = 100;
            }
            else
            {
                _tiles[TileIndex.x, TileIndex.y] = 0;
            }
        }

        /// <summary>
        /// Gets the speed of the tile
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public byte GetTileSpeed(int x, int y)
        {
            if (x < 0 || x >= _width)
            {
                return 0;
            }

            if (y < 0 || y >= _length)
            {
                return 0;
            }

            return _tiles[x, y];
        }
    }
}