package beans;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * Class that represents a point ("tento") of the game.
 * @author Lucas Pinheiro @lucaspin
 * @author Bruno Vedovetto @bleandro
 * @author Dalton Lima @daltonbr
 */
public class Point {
    private boolean ended = false;
    private List<Round> rounds = new ArrayList<>();
    private Player dealer;
    private Player winner;
    private PointValue pointValue;

    /**
     * Constructor of the class
     */
    public Point(List<Player> playersInOrder) {
        this.setDealer(playersInOrder.get(0));
        this.setPointValue(PointValue.ONE);
        this.initPoint(playersInOrder);
    }

    /**
     * Init a point flow
     * @param playersInOrder {List<Player>}
     */
    private void initPoint(List<Player> playersInOrder) {
        this.createRounds();

        while (!this.isEnded()) {
            ListIterator<Round> it = this.rounds.listIterator();

            // TODO: add logic to treat tie cases and others
            while (it.hasNext() && !this.isEnded()) {
                /* We order the players in the order they should play in the next round.
                   In order to do this, we must get the winner from the last round,
                   and set it as the first one of the list. For the first round, we just
                   pass the players as they come. Also, we just do this reordering if the round
                   is not the first one.
                 */
                if (it.nextIndex() != 0) {
                    int previousIndex = it.previousIndex();
                    Round previousRound = this.rounds.get(previousIndex);
                    playersInOrder = this.orderPlayers(playersInOrder, previousRound.getWinner());
                }

                Round nextRound = it.next();
                nextRound.setPlayersInOrder(playersInOrder);
                nextRound.initRound();

                Player nextRoundWinner = nextRound.getWinner();

                /* Check if some player's has won this point by
                   winning two rounds in a row */
                if (nextRoundWinner.getRoundScore() == GameController.EARLY_WIN_ROUND_SCORE) {
                    nextRoundWinner.increaseGameScore(this.pointValue.getValue());
                    this.setWinner(nextRoundWinner);
                    this.setEnded(true);
                }
            }

            // We end the point when all round has been played
            this.setEnded(true);
        }
    }

    /**
     * Order the players setting the last round winner as the
     * start player of the next round.
     * @param players {List<Player>}
     * @param firstPlayer {Player}
     * @return {List<Player>}
     */
    private List<Player> orderPlayers(List<Player> players, Player firstPlayer) {
        List<Player> newPlayers = new ArrayList<>();
        newPlayers.add(firstPlayer);
        ListIterator<Player> it = players.listIterator();

        if (it.hasNext()) {
            Player nextPlayer = it.next();
            if (nextPlayer.getName().equals(firstPlayer.getName())) {
                it.remove();
            } else {
                newPlayers.add(nextPlayer);
            }
        }

        return newPlayers;
    }

    /**
     * Create the rounds of this point
     */
    private void createRounds() {
        for (int i = 0; i < 3; i++) {
            Round round = new Round();
            this.rounds.add(round);
        }
    }

    /**
     * Get the ended status of the point
     * @return {Boolean}
     */
    public boolean isEnded() {
        return this.ended;
    }

    /**
     * Set the ended status of the point
     * @param _ended {Boolean}
     */
    public void setEnded(boolean _ended) {
        this.ended = _ended;
    }

    /**
     * Get the round of the point
     * @return {List<Round>}
     */
    public List<Round> getRounds() {
        return this.rounds;
    }

    /**
     * Set the rounds for the point
     * @param _rounds {List<Round>}
     */
    public void setRounds(List<Round> _rounds) {
        this.rounds = _rounds;
    }

    /**
     * Get the dealer of the point
     * @return {Player}
     */
    public Player getDealer() {
        return this.dealer;
    }

    /**
     * Set the dealer of the point
     * @param _dealer {Player}
     */
    public void setDealer(Player _dealer) {
        this.dealer = _dealer;
    }

    /**
     * Get the winner of the point
     * @return {Player}
     */
    public Player getWinner() {
        return this.winner;
    }

    /**
     * Set the winner of the point
     * @param _winner {Player}
     */
    public void setWinner(Player _winner) {
        this.winner = _winner;
    }

    /**
     * Get the real value of the point
     * @return {PointValue}
     */
    public PointValue getPointValue() {
        return this.pointValue;
    }

    /**
     * Set the new real value of the point
     * @param _value {PointValue}
     */
    public void setPointValue(PointValue _value) {
        this.pointValue = _value;
    }
}

@@ -2957,24 +2957,25 @@
 layer);%0A
+%0A
         
 ListIter
@@ -2970,129 +2970,39 @@
     
-ListIterator%3CPlayer%3E it = players.listIterator();%0A%0A        if (it.hasNext()) %7B%0A            Player nextPlayer = it.next();
+for (Player player : players) %7B
 %0A   
@@ -3014,21 +3014,18 @@
     if (
-nextP
+!p
 layer.ge
@@ -3069,58 +3069,8 @@
 ) %7B%0A
-                it.remove();%0A            %7D else %7B%0A
     
@@ -3100,13 +3100,9 @@
 add(
-nextP
+p
 laye

Fix ordering of players before start another round