001package fr.aumgn.dac2.stage.join;
002
003import java.util.HashSet;
004import java.util.List;
005import java.util.Set;
006
007import org.bukkit.command.CommandSender;
008import org.bukkit.entity.Player;
009import org.bukkit.event.Listener;
010
011import fr.aumgn.bukkitutils.localization.PluginMessages;
012import fr.aumgn.bukkitutils.playerref.PlayerRef;
013import fr.aumgn.bukkitutils.playerref.map.PlayersRefHashMap;
014import fr.aumgn.bukkitutils.playerref.map.PlayersRefMap;
015import fr.aumgn.bukkitutils.playerref.set.PlayersRefHashSet;
016import fr.aumgn.bukkitutils.playerref.set.PlayersRefSet;
017import fr.aumgn.bukkitutils.util.Util;
018import fr.aumgn.dac2.DAC;
019import fr.aumgn.dac2.arena.Arena;
020import fr.aumgn.dac2.config.Color;
021import fr.aumgn.dac2.exceptions.TooManyPlayers;
022import fr.aumgn.dac2.game.start.GameStartData;
023import fr.aumgn.dac2.game.start.PlayerStartData;
024import fr.aumgn.dac2.game.start.SimplePlayerStartData;
025import fr.aumgn.dac2.stage.Stage;
026
027public class JoinStage implements Stage, Listener, GameStartData {
028
029    private final DAC dac;
030    private final Arena arena;
031    private final Set<String> colorsTaken;
032    private final PlayersRefMap<PlayerStartData> players;
033    private final PlayersRefSet spectators;
034
035    public JoinStage(DAC dac, Arena arena) {
036        this.dac = dac;
037        this.arena = arena;
038        this.colorsTaken = new HashSet<String>();
039        this.players = new PlayersRefHashMap<PlayerStartData>();
040        this.spectators = new PlayersRefHashSet();
041    }
042
043    @Override
044    public Arena getArena() {
045        return arena;
046    }
047
048    @Override
049    public void start() {
050        PluginMessages messages = dac.getMessages();
051        Util.broadcast("dac2.spectator.watch", 
052                messages.get("joinstage.start1", arena.getName()));
053        Util.broadcast("dac2.spectator.watch",
054                messages.get("joinstage.start2"));
055    }
056
057    @Override
058    public void stop(boolean force) {
059        if (force) {
060            sendMessage(dac.getMessages().get("joinstage.stopped"));
061        }
062    }
063
064    @Override
065    public Listener[] getListeners() {
066        return new Listener[0];
067    }
068
069    @Override
070    public boolean contains(Player player) {
071        return players.containsKey(player);
072    }
073
074    @Override
075    public void sendMessage(String message) {
076        for (Player player : players.playersSet()) {
077            player.sendMessage(message);
078        }
079
080        String spectatorMessage = dac.getConfig().getSpectatorsMsg()
081                .format(new String[] { arena.getName(), message });
082        for (Player spectator : spectators.players()) {
083            spectator.sendMessage(spectatorMessage);
084        }
085    }
086
087    public void addPlayer(Player player, List<Color> colors) {
088        Color finalColor = null;
089        for (Color color : colors) {
090            if (!colorsTaken.contains(color.name)) {
091                finalColor = color;
092                break;
093            }
094        }
095
096        addPlayer(player, finalColor);
097    }
098
099    public void addPlayer(Player player, Color color) {
100        if (players.size() >= dac.getColors().size()) {
101            throw new TooManyPlayers(dac.getMessages()
102                    .get("joinstage.toomanyplayers"));
103        }
104
105        if (color == null || colorsTaken.contains(color.name)) {
106            color = getFirstColorAvailable();
107        }
108
109        PluginMessages msgs = dac.getMessages();
110        String playerName = color.chat + player.getDisplayName();
111        sendMessage(msgs.get("joinstage.join", playerName));
112
113        players.put(player, new SimplePlayerStartData(color, player));
114        colorsTaken.add(color.name);
115
116        list(player);
117    }
118
119    private Color getFirstColorAvailable() {
120        List<Color> colors = dac.getColors().asList();
121        for (Color color : colors) {
122            if (!colorsTaken.contains(color.name)) {
123                return color;
124            }
125        }
126
127        throw new Error("A unexpected error occured ! Please reoprt this to"
128                + " the plugin author.");
129    }
130
131    @Override
132    public boolean isSpectator(Player player) {
133        return spectators.contains(player);
134    }
135
136    @Override
137    public void addSpectator(Player player) {
138        spectators.add(player);
139    }
140
141    @Override
142    public void removeSpectator(Player player) {
143        spectators.remove(player);
144    }
145
146    public int size() {
147        return players.size();
148    }
149
150    @Override
151    public PlayersRefMap<PlayerStartData> getPlayersData() {
152        return players;
153    }
154
155    @Override
156    public PlayersRefSet getSpectators() {
157        return spectators;
158    }
159
160    @Override
161    public void list(CommandSender sender) {
162        PluginMessages messages = dac.getMessages();
163
164        sender.sendMessage(messages.get("joinstage.playerslist"));
165        for (PlayerRef player : players.keySet()) {
166            sender.sendMessage(messages.get("joinstage.playerentry", 
167                    player.getDisplayName()));
168        }
169    }
170
171    @Override
172    public void onQuit(Player player) {
173        PlayerStartData data = players.remove(player);
174        colorsTaken.remove(data.getColor().name);
175
176        String message = dac.getMessages().get("joinstage.quit",
177                data.getColor().chat + player.getDisplayName());
178        sendMessage(message);
179        player.sendMessage(message);
180    }
181}