using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace WorldOfPeacecraft
{
	class Pathfinder
	{
		[StructLayout(LayoutKind.Sequential)]
		private struct PathNode
		{
			[MarshalAs(UnmanagedType.I4)]
			public int X;
			[MarshalAs(UnmanagedType.I4)]
			public int Y;
		}

		public static unsafe LinkedList<Coordinate> FindPath (Coordinate posFrom, Coordinate posTo, Map map)
		{
			PathNode nFrom;
			nFrom.X = posFrom.X;
			nFrom.Y = posFrom.Y;
			PathNode nTo;
			nTo.X = posTo.X;
			nTo.Y = posTo.Y;
			Tile[,] tiles = map.GetTiles();
			int mapWidth = tiles.GetLength (0);
			int mapHeight = tiles.GetLength (1);
			bool* boolMap = stackalloc bool[mapWidth * mapHeight];
			for (int y = 0; y < mapHeight; y++) {
				for (int x = 0; x < mapWidth; x++) {
					boolMap [x + y * mapWidth] = tiles [x, y].IsWalkable ();
				}
			}
			PathNode* result = stackalloc PathNode[mapHeight * mapWidth];
			int noSteps = findPath (nFrom, nTo, mapWidth, mapHeight, boolMap, result);
			LinkedList<Coordinate> mappedResult = new LinkedList<Coordinate>();
			for (int i = 0; i < noSteps; i++) {
				mappedResult.AddLast(new Coordinate(result[i].X, result[i].Y));
			}
			return mappedResult;
		}

		[DllImport("pathfinding")]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern unsafe int findPath(
			                               PathNode posFrom,
			                               PathNode posTo,
			[MarshalAs(UnmanagedType.I4)]  int mapWidth,
			[MarshalAs(UnmanagedType.I4)]  int mapHeight,
			                               bool* map,
			                               PathNode* result);
	}
}
