package core;

import exception.OutOfBoardException;

/**
 * Cette classe décrit un pion.
 */
public class Pawn {

	/**
	 * Le caractère qui représente le pion.
	 */
	private char c;

	/**
	 * Position du pion sur l'axe x.
	 */
	private int x;

	/**
	 * Position du pion sur l'axe y.
	 */
	private int y;

	/**
	 * Le plateau sur lequel le pion se trouve.
	 */
	private Board board;

	/**
	 * Le nombre de points de vie restant du pion.
	 */
	private int hitpoints;

	/**
	 * Le nombre de pièces d'or collectées du pion.
	 */
	private int gold;

	public char getLetter() {
		return this.c;
	}

	public int getX() {
		return this.x;
	}

	public int getY() {
		return this.y;
	}

	public int getHitpoints() {
		return this.hitpoints;
	}

	public int getGold() {
		return this.gold;
	}

	/**
	 * Crée un pion avec 2 points de vie et 0 pièce d'or.
	 * 
	 * @param c
	 *            Le caractère qui représente le pion.
	 * @param x
	 *            Position du pion sur l'axe x.
	 * @param y
	 *            Position du pion sur l'axe y.
	 * @param board
	 *            Le plateau surquel le pion se trouve.
	 */
	public Pawn(char c, int x, int y, Board board) {
		this.c = c;
		this.x = x;
		this.y = y;
		this.board = board;
		this.hitpoints = 2;
		this.gold = 0;
	}

	/**
	 * Détermine si le pion est mort ou non.
	 * 
	 * @return true si le point est mort, false sinon.
	 */
	public boolean isDead() {
		return this.hitpoints <= 0;
	}

	/**
	 * Déplace le pion dans une direction.
	 * 
	 * @param d
	 *            La direction pour déplacer le pion.
	 * @return Un message qui explique ce qui est arrivé durant le déplacement.
	 * @throws OutOfBoardException
	 *             si le pion essaie de sortir du plateau.
	 */
	public String move(Direction d) throws OutOfBoardException {
		String message = "";
		int newx = x;
		int newy = y;
		switch (d) {
		case HAUT:
			newy++;
			break;
		case BAS:
			newy--;
			break;
		case GAUCHE:
			newx--;
			break;
		case DROITE:
			newx++;
			break;
		}
		if (newx >= 0 && newy >= 0 && newx < this.board.getXSize()
				&& newy < this.board.getYSize()) {
			Pawn content = this.board.getSquareContent(newx, newy);
			if (content == null) {
				x = newx;
				y = newy;
			} else {
				message = this.attack(content);
			}
		} else {
			throw new OutOfBoardException(newx, newy);
		}
		return message;
	}

	/**
	 * Effectue l'attaque du pion sur un autre pion. Le pion ennemi subit 1
	 * point de dommage, ou 2 si le pion qui attaque est sur une case "bonus".
	 * 
	 * @param ennemy
	 *            Le pion attaqué.
	 * @return Un message qui explique ce qui est arrivé durant l'attaque.
	 */
	private String attack(Pawn enemy) {
		String message = "Le pion " + this.getLetter() + " attaque le pion "
				+ enemy.getLetter() + " !\n";
		if (this.board.isBonusSquare(x, y)) {
			message += enemy.suffer(2);
		} else {
			message += enemy.suffer(1);
		}
		if (enemy.isDead()) {
			this.gold++;
		}
		return message;
	}

	/**
	 * Effectue la perte des points de vie du pion. Si le pion n'a plus de point
	 * de vie, il est supprimé du plateau.
	 * 
	 * @param i
	 *            Le nombre de points de vie à perdre.
	 * @return Un mesage qui explique ce qui est arrivé durant la blessure.
	 */
	private String suffer(int i) {
		String message = "Le pion " + this.getLetter() + " perd " + i
				+ " points de vie.\n";
		this.hitpoints -= i;
		if (this.hitpoints <= 0) {
			this.board.removePawn(this);
			message += "Le pion " + this.getLetter() + " est mort.\n";
		}
		return message;
	}

}
