package game.goals;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import game.Game;
import game.Goal;
import game.Player;
import game.map.Castle;

/**
 * Derjenige Spieler gewinnt, der nach einer bestimmten Anzahl an
 * Runden die meisten Burgen besitzt.
 * @author dennis
 *
 */
public class TimeGoal extends Goal {

	int maxRounds;
	boolean isDraw;
	
	/**
	 * Creates a new time goal with the default limit
	 */
	public TimeGoal() {
		this(6);
	}
	
	/**
	 * Creates a new time goal with the specified limit
	 * @param maxRounds The limit of rounds
	 */
	public TimeGoal(int maxRounds) {
		super("Countdown", "Derjenige Spieler gewinnt, der nach " + maxRounds + " Runden die meisten Burgen besitzt.");
		this.maxRounds = maxRounds;
		isDraw = false;
	}
	
	@Override
	public boolean isCompleted() {
	    // Call getWinner to set isDraw if needed
    	getWinner();
        return isDraw || this.getWinner() != null;
	}

	@Override
	public Player getWinner() {
		
		Game game = this.getGame();
		
		// If a player conquers all castles before the time limit is over, the game should obviously end there.
		if(game.getRound() < maxRounds) {
			
			// Copy-pasted from ConquerGoal.java
	        if(game.getRound() < 2)
	            return null;

	        Player p = null;
	        for(Castle c : game.getMap().getCastles()) {
	            if(c.getOwner() == null)
	                return null;
	            else if(p == null)
	                p = c.getOwner();
	            else if(p != c.getOwner())
	                return null;
	        }

	        return p;
		}
		
		List<Player> playerList = game.getPlayers();
		Comparator<Player> comp = new Comparator<Player>() {
			
			public int compare(Player p1, Player p2) {
				
				return Integer.compare(p1.getNumRegions(game), p2.getNumRegions(game));
				
			}
			
		};
		Collections.sort(playerList, comp);
        // Edge Case: Mind. Zwei spieler haben die gleiche Anzahl an Burgen
		if(playerList.get(0).getNumRegions(game) == playerList.get(1).getNumRegions(game)) {
			isDraw = true;
			return null;
		}
		
		return Collections.max(playerList, comp);
	}

	@Override
	public boolean hasLost(Player player) {
		
		if(getGame().getRound() < 2)
	            return false;

	    return player.getNumRegions(getGame()) == 0 || (this.isCompleted() && !player.equals(this.getWinner()));
	}
}
