package com.esir.sr.sweetsnake.view;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.esir.sr.sweetsnake.component.ImagePanel;
import com.esir.sr.sweetsnake.constants.ClientGuiConstants;
import com.esir.sr.sweetsnake.constants.GameConstants;
import com.esir.sr.sweetsnake.dto.PlayerDTO;
/**
*
* @author Herminaël Rougier
* @author Damien Jouanno
*
*/
@Component
public class LobbyView extends AbstractView
{
/**********************************************************************************************
* [BLOCK] STATIC FIELDS
**********************************************************************************************/
/** The serial version UID */
private static final long serialVersionUID = 7442409526614747493L;
/** The logger */
private static final Logger log = LoggerFactory.getLogger(LobbyView.class);
/**********************************************************************************************
* [BLOCK] FIELDS
**********************************************************************************************/
/** The view title panel */
private ImagePanel lobbyIPL;
/** The top panel */
private JPanel topPL;
/** The center panel */
private JPanel centerPL;
/** The players panels */
private PlayerPanel[] playersPL;
/** The bottom panel */
private JPanel bottomPL;
/** The quit button */
private JButton quitBTN;
/** The ready button */
private JButton readyBTN;
/** The start button */
private JButton startBTN;
/** The waiting label */
private JLabel waitLB;
/** The current player's number */
private int playerNb;
/** The players list */
private List<PlayerDTO> players;
/**********************************************************************************************
* [BLOCK] CONSTRUCTOR & INIT
**********************************************************************************************/
/**
*
*/
protected LobbyView() {
super();
}
/*
* (non-Javadoc)
*
* @see com.esir.sr.sweetsnake.view.SweetSnakeAbstractView#init()
*/
@Override
@PostConstruct
protected void init() {
super.init();
log.info("Initializing the Lobby View");
}
/**********************************************************************************************
* [BLOCK] PUBLIC METHODS
**********************************************************************************************/
/*
* (non-Javadoc)
*
* @see com.esir.sr.sweetsnake.view.SweetSnakeAbstractView#buildImpl()
*/
@Override
public void buildImpl() {
setLayout(new BorderLayout());
// top panel
initTopPL();
add(topPL, BorderLayout.NORTH);
initLobbyIPL();
topPL.add(lobbyIPL);
// center panel
initCenterPL();
add(centerPL, BorderLayout.CENTER);
initPlayersPL();
for (final JPanel panel : playersPL) {
centerPL.add(panel);
}
players = new LinkedList<PlayerDTO>();
// bottom panel
initBottomPL();
add(bottomPL, BorderLayout.SOUTH);
final GridBagConstraints gbc = new GridBagConstraints();
initQuitBTN();
gbc.gridwidth = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.insets = new Insets(5, 0, 0, 0);
bottomPL.add(quitBTN, gbc);
initReadyBTN();
gbc.gridx = 1;
bottomPL.add(readyBTN, gbc);
}
/**
*
*/
public void refreshPlayers() {
for (final PlayerPanel panel : playersPL) {
panel.removePlayer();
}
for (final PlayerDTO player : players) {
final PlayerPanel playerPL = playersPL[player.getNumber() - 1];
playerPL.refreshPlayer(player);
}
}
/**
*
* @param allReady
* @param isStarted
*/
// FIXME readyBTN can bug
public void refreshButtons(final boolean allReady, final boolean isStarted) {
final GridBagConstraints gbc = new GridBagConstraints();
if (isStarted) {
readyBTN.setEnabled(false);
} else if (allReady) {
bottomPL.remove(readyBTN);
if (waitLB != null) {
bottomPL.remove(waitLB);
waitLB = null;
}
gbc.gridx = 1;
gbc.gridwidth = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.insets = new Insets(5, 0, 0, 0);
if (players.get(0).getNumber() == playerNb) {
initStartBTN();
bottomPL.add(startBTN, gbc);
} else {
initWaitLB(players.get(0).getName());
bottomPL.add(waitLB, gbc);
}
} else if (startBTN != null) {
bottomPL.remove(startBTN);
startBTN = null;
gbc.gridx = 1;
gbc.gridwidth = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.insets = new Insets(5, 0, 0, 0);
bottomPL.add(readyBTN, gbc);
readyBTN.setEnabled(false);
}
}
/**
*
* @param _playerNb
*/
public void setPlayerNb(final int _playerNb) {
playerNb = _playerNb;
}
/**
*
* @param _players
*/
public void setPlayers(final List<PlayerDTO> _players) {
players = new LinkedList<PlayerDTO>(_players);
}
/**********************************************************************************************
* [BLOCK] PRIVATE METHODS
**********************************************************************************************/
/**
*
*/
private void initTopPL() {
topPL = new JPanel();
topPL.setOpaque(false);
}
/**
*
*/
private void initLobbyIPL() {
lobbyIPL = new ImagePanel(ClientGuiConstants.GAME_LOBBY_PATH);
}
/**
*
*/
private void initCenterPL() {
centerPL = new JPanel();
centerPL.setOpaque(false);
centerPL.setLayout(new GridLayout(GameConstants.MAX_NUMBER_OF_PLAYERS / 2, GameConstants.MAX_NUMBER_OF_PLAYERS / 2));
}
/**
*
*/
private void initPlayersPL() {
playersPL = new PlayerPanel[GameConstants.MAX_NUMBER_OF_PLAYERS];
for (int i = 0; i < playersPL.length; i++) {
playersPL[i] = new PlayerPanel(i + 1);
}
}
/**
*
*/
private void initBottomPL() {
bottomPL = new JPanel();
bottomPL.setLayout(new GridBagLayout());
bottomPL.setOpaque(false);
}
/**
*
*/
private void initQuitBTN() {
quitBTN = new JButton("quit game");
quitBTN.addActionListener(new QuitGameListener());
}
/**
*
*/
private void initReadyBTN() {
readyBTN = new JButton("ready !");
readyBTN.addActionListener(new ReadyListener());
}
/**
*
*/
private void initStartBTN() {
startBTN = new JButton("start game");
startBTN.addActionListener(new StartGameListener());
}
/**
*
*/
private void initWaitLB(final String playerName) {
waitLB = new JLabel("waiting for " + playerName + " to start the game");
waitLB.setForeground(Color.white);
waitLB.setFont(new Font("sans-serif", Font.PLAIN, 10));
}
/**********************************************************************************************
* [BLOCK] INTERNAL LISTENERS
**********************************************************************************************/
private class PlayerPanel extends JPanel
{
/** The serial version UID */
private static final long serialVersionUID = -5926630505331840276L;
/** The player label */
private final JLabel playerLB;
/** The icon label */
private final JLabel iconLB;
/** The status label */
private final JLabel statusLB;
/** The score label */
private final JLabel scoreLB;
/**
*
* @param nb
*/
public PlayerPanel(final int nb) {
final GridBagConstraints gbc = new GridBagConstraints();
setLayout(new GridBagLayout());
setOpaque(true);
setBackground(findSnakeColor(nb));
playerLB = generateLabel("Available", 15, Color.gray, Font.ITALIC);
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 1;
gbc.weighty = 0.1;
gbc.insets = new Insets(25, 0, 0, 0);
add(playerLB, gbc);
iconLB = generateLabel("", 15, Color.white, Font.PLAIN);
gbc.gridy = 1;
gbc.weighty = 500;
gbc.insets = new Insets(10, 0, 0, 0);
add(iconLB, gbc);
statusLB = generateLabel("", 15, Color.white, Font.ITALIC);
gbc.gridy = 2;
gbc.weighty = 500;
gbc.anchor = GridBagConstraints.NORTH;
add(statusLB, gbc);
scoreLB = generateLabel("", 15, Color.white, Font.BOLD);
gbc.gridy = 3;
gbc.weighty = 1000;
add(scoreLB, gbc);
}
/**
*
* @param player
*/
public void refreshPlayer(final PlayerDTO player) {
playerLB.setText(player.getName());
playerLB.setFont(new Font("sans-serif", Font.BOLD, 25));
playerLB.setForeground(Color.white);
statusLB.setText("" + player.getStatus());
iconLB.setIcon(new ImageIcon(LobbyView.class.getResource(findSnakeIconPath(player.getNumber()))));
scoreLB.setText("Score : " + player.getScore());
}
/**
*
*/
public void removePlayer() {
playerLB.setText("Available");
playerLB.setFont(new Font("sans-serif", Font.ITALIC, 15));
playerLB.setForeground(Color.gray);
statusLB.setText("");
iconLB.setIcon(null);
scoreLB.setText("");
}
/**
*
* @param text
* @param fontSize
* @param fontColor
* @param fontWeight
* @return
*/
private JLabel generateLabel(final String text, final int fontSize, final Color color, final int fontWeight) {
final JLabel label = new JLabel(text);
label.setForeground(color);
label.setFont(new Font("sans-serif", fontWeight, fontSize));
return label;
}
/**
*
* @param i
* @return
*/
private Color findSnakeColor(final int i) { // TODO duplicated
switch (i) {
case 2:
return new Color(255, 0, 0, 50);
case 3:
return new Color(12, 12, 235, 50);
case 4:
return new Color(0, 0, 0, 50);
default:
return new Color(39, 109, 31, 50);
}
}
/**
*
* @param nb
* @return
*/
private String findSnakeIconPath(final int nb) { // TODO duplicated
switch (nb) {
case 2:
return ClientGuiConstants.RED_SNAKE_ICON_PATH;
case 3:
return ClientGuiConstants.BLUE_SNAKE_ICON_PATH;
case 4:
return ClientGuiConstants.BLACK_SNAKE_ICON_PATH;
default:
return ClientGuiConstants.GREEN_SNAKE_ICON_PATH;
}
}
}
/**
*
* @author Herminaël Rougier
* @author Damien Jouanno
*
*/
private class QuitGameListener implements ActionListener
{
/*
* (non-Javadoc)
*
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
@Override
public void actionPerformed(final ActionEvent e) {
client.leaveSession();
}
}
/**
*
* @author Herminaël Rougier
* @author Damien Jouanno
*
*/
private class ReadyListener implements ActionListener
{
/*
* (non-Javadoc)
*
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
@Override
public void actionPerformed(final ActionEvent e) {
client.readyToPlay();
readyBTN.setEnabled(false);
}
}
/**
*
* @author Herminaël Rougier
* @author Damien Jouanno
*
*/
private class StartGameListener implements ActionListener
{
/*
* (non-Javadoc)
*
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
@Override
public void actionPerformed(final ActionEvent e) {
client.startSession();
}
}
}