001package fr.aumgn.dac2.game;
002
003import java.lang.reflect.Array;
004import java.util.Arrays;
005import java.util.LinkedList;
006import java.util.List;
007import java.util.Random;
008
009import fr.aumgn.bukkitutils.util.Util;
010
011public class GameParty<T extends GamePlayer> {
012
013    // Come on..
014    private final Class<T> clazz;
015    private final Game game;
016    private T[] players;
017    private int turn;
018
019    public GameParty(Game game, Class<T> clazz, List<T> list) {
020        this.clazz = (Class<T>) clazz;
021        this.game = game;
022        players = newArray(list.size());
023
024        LinkedList<T> roulette = new LinkedList<T>(list);
025        Random rand = Util.getRandom();
026        for (int i = 0; i< players.length; i++) {
027            int j = rand.nextInt(roulette.size());
028            T player = roulette.remove(j);
029            players[i] = player;
030            player.setIndex(i);
031        }
032
033        turn = -1;
034    }
035
036    @SuppressWarnings("unchecked")
037    private T[] newArray(int size) {
038        return (T[]) Array.newInstance(clazz, size);
039    }
040
041    public boolean isTurn(T player) {
042        return player.getIndex() == turn;
043    }
044
045    public boolean isLastTurn() {
046        return turn == players.length - 1;
047    }
048
049    public T getCurrent() {
050        return players[turn];
051    }
052
053    /**
054     * Returns the internal array used to store the players.
055     * This array is accessible for performance reason
056     * (and because Java doesn't permit polymorphic management of arrays)
057     * and should preferably not be used to modify the array in any way.
058     */
059    public T[] iterable() {
060        return players;
061    }
062
063    public int size() {
064        return players.length;
065    }
066
067    public T nextTurn() {
068        incrementTurn();
069        return players[turn];
070    }
071
072    private void incrementTurn() {
073        turn++;
074        if (turn >= players.length) {
075            turn = 0;
076            game.onNewTurn();
077        }
078    }
079
080    public void removePlayer(T player) {
081        int index = player.getIndex();
082
083        T[] newPlayers = newArray(players.length - 1);
084        System.arraycopy(players, 0, newPlayers, 0, index);
085        System.arraycopy(players, index + 1, newPlayers,
086                index, players.length - index - 1);
087
088        for (int i = index + 1; i < players.length; i++) {
089            players[i].setIndex(i - 1);
090        }
091
092        if (index <= turn) {
093            if (turn == 0) {
094                turn = players.length - 2;
095            } else {
096                turn--;
097            }
098        }
099
100        players = newPlayers;
101    }
102
103    public List<T> asList() {
104        return Arrays.asList(players);
105    }
106}