package chess4j.attack;

import java.util.List;

import chess4j.Color;
import chess4j.board.Board;
import chess4j.board.KingSquares;
import chess4j.board.KnightSquares;
import chess4j.board.Square;
import chess4j.board.directions.Direction;
import chess4j.board.directions.NorthEast;
import chess4j.board.directions.NorthWest;
import chess4j.board.directions.SouthEast;
import chess4j.board.directions.SouthWest;
import chess4j.pieces.Bishop;
import chess4j.pieces.King;
import chess4j.pieces.Knight;
import chess4j.pieces.Pawn;
import chess4j.pieces.Piece;
import chess4j.pieces.Queen;
import chess4j.pieces.Rook;


public class AttackImpl implements Attack {

	
	/**
	 * Is <sq> attacked by <player>?
	 * 
	 * @param board
	 * @param sq
	 * @param player
	 * @return
	 */
	public boolean attacked(Board board,Square sq,Color player) {
		return attackedByPawn(board,sq,player) 
			|| attackedByRook(board,sq,player)
			|| attackedByKnight(board,sq,player)
			|| attackedByBishop(board,sq,player)
			|| attackedByQueen(board,sq,player)
			|| attackedByKing(board,sq,player);
	}
	
	public boolean attackedByPawn(Board board,Square sq,Color player) {
		if (player.isWhite()) {
			Square pawnSq = SouthEast.getInstance().next(sq);
			if (pawnSq != null) {
				Piece p = board.getPiece(pawnSq);
				if (p instanceof Pawn && p.isWhite())
					return true;
			}
			pawnSq = SouthWest.getInstance().next(sq); 
			if (pawnSq != null) {
				Piece p = board.getPiece(pawnSq);
				if (p instanceof Pawn && p.isWhite())
					return true;
			}
		} else {
			Square pawnSq = NorthEast.getInstance().next(sq);
			if (pawnSq != null) {
				Piece p = board.getPiece(pawnSq);
				if (p instanceof Pawn && p.isBlack())
					return true;
			}
			pawnSq = NorthWest.getInstance().next(sq); 
			if (pawnSq != null) {
				Piece p = board.getPiece(pawnSq);
				if (p instanceof Pawn && p.isBlack())
					return true;
			}
		}
		return false;
	}
	
	public boolean attackedByRook(Board board,Square sq,Color player) {
		List<Direction> dirs = Rook.BLACK_ROOK.getDirections();
		for (Direction dir : dirs) {
			Piece p = getPiece(dir,board,sq);
			if (p instanceof Rook && p.getColor().equals(player))
				return true;
		}
		return false;
	}

	public boolean attackedByKnight(Board board,Square sq,Color player) {
		List<Square> knightSquares = KnightSquares.getSquares(sq);
		for (Square knightSquare : knightSquares) {
			Piece p = board.getPiece(knightSquare);
			if (p instanceof Knight && p.getColor().equals(player))
				return true;
		}
		return false;
	}

	public boolean attackedByBishop(Board board,Square sq,Color player) {
		List<Direction> dirs = Bishop.BLACK_BISHOP.getDirections();
		for (Direction dir : dirs) {
			Piece p = getPiece(dir,board,sq);
			if (p instanceof Bishop && p.getColor().equals(player))
				return true;
		}
		return false;
	}

	public boolean attackedByQueen(Board board,Square sq,Color player) {
		List<Direction> dirs = Queen.BLACK_QUEEN.getDirections();
		for (Direction dir : dirs) {
			Piece p = getPiece(dir,board,sq);
			if (p instanceof Queen && p.getColor().equals(player))
				return true;
		}
		return false;
	}

	public boolean attackedByKing(Board board,Square sq,Color player) {
		List<Square> kingSquares = KingSquares.getSquares(sq);
		for (Square kingSquare : kingSquares) {
			Piece p = board.getPiece(kingSquare);
			if (p instanceof King && p.getColor().equals(player))
				return true;
		}
		return false;
	}
	
	private Piece getPiece(Direction direction,Board board,Square sq) {
		Square nextSq = direction.next(sq);
		while (nextSq != null) {
			Piece p = board.getPiece(nextSq);
			if (p != null)
				return p;
			nextSq = direction.next(nextSq);
		}
		return null;
	}
}
