﻿using Gamelogic.AbstractStrategy.Grids;
using Gamelogic.Grids;
using System.Collections.Generic;
using System.Linq;

namespace Gamelogic.AbstractStrategy.Examples
{

	public enum CellPosition
	{
		Even,
		Odd
	}

	public class CustomPieceRule : PieceRule<RectPoint, GridGamePieceSettings>
	{
		public bool useRestrictions = true;
		public CellPosition XPosition;
		public CellPosition YPosition;

		public override bool CanRemovePiece(IGameState<RectPoint, GridGamePieceSettings> state, IPieceProperties piece, RectPoint position)
		{
			return false;
		}

		public override RectPoint GetCapturePosition(IGameState<RectPoint, GridGamePieceSettings> state, IPieceProperties capturePiece, IPieceProperties capturedPiece, RectPoint initialPosition)
		{
			return default(RectPoint);
		}

		public override IEnumerable<RectPoint> GetValidAddPositions(IGameState<RectPoint, GridGamePieceSettings> state)
		{
			return Enumerable.Empty<RectPoint>();
		}

		public override IEnumerable<IPieceProperties> GetValidCapturePieces(IGameState<RectPoint, GridGamePieceSettings> state, IPieceProperties piece, RectPoint initialPosition)
		{
			return Enumerable.Empty<IPieceProperties>();
		}

		public override IEnumerable<RectPoint> GetValidDestinationPositions(IGameState<RectPoint, GridGamePieceSettings> state, IPieceProperties piece, RectPoint initialPosition)
		{
			// Search grid for all unoccupied cells
			foreach (var point in state.GetAllPoints())
			{
				if (point == initialPosition) continue;

				var cell = state.GetPiecesAtPoint(point);

				if (!cell.IsEmpty())
					continue;

				if (useRestrictions)
				{
					if (!ValidateCellNumber(point))
						continue;
				}

				yield return point;
			}
		}

		private bool ValidateCellNumber(RectPoint point)
		{
			bool xValidation = false;
			bool yValidation = false;

			switch (XPosition)
			{
				case CellPosition.Even:
					xValidation = point.X % 2 == 0;
					break;
				case CellPosition.Odd:
					xValidation = point.X % 2 != 0;
					break;
			}

			switch (YPosition)
			{
				case CellPosition.Even:
					yValidation = point.Y % 2 == 0;
					break;

				case CellPosition.Odd:
					yValidation = point.Y % 2 != 0;
					break;
			}

			return xValidation && yValidation;
		}
	}
}