package server;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import org.json.JSONArray;
import org.json.JSONObject;
import card.Card;
import card.CardInfo;
import player.BasePlayer;
public class SwingClientGame extends ClientGame {
//UI STUFF
JFrame mainFrame;
JPanel gamePanel;
JPanel hintPanel;
JPanel flashPanel;
JPanel playingDeckPanel;
JLabel[][] playingDeckUi;
JLabel[] hintUi;
JLabel[] flashUi;
GridBagConstraints layoutConstr;
// Hints
JFrame hintFrame;
JLabel[] hintTypes;
int clickedPlayer;
Font font;
final static Color BACKGROUND = Color.black;
private static final ImageIcon HINT_0 = new ImageIcon(new ImageIcon("hint_0.png").getImage().getScaledInstance(40, 40, Image.SCALE_SMOOTH));
private static final ImageIcon HINT_1 = new ImageIcon(new ImageIcon("hint_1.png").getImage().getScaledInstance(40, 40, Image.SCALE_SMOOTH));
private static final ImageIcon FLASH_0 = new ImageIcon(new ImageIcon("flash_0.png").getImage().getScaledInstance(40, 40, Image.SCALE_SMOOTH));
private static final ImageIcon FLASH_1 = new ImageIcon(new ImageIcon("flash_1.png").getImage().getScaledInstance(40, 40, Image.SCALE_SMOOTH));
public static void main(String[] args){
new SwingClientGame();
}
private void createHintUi(){
hintFrame = new JFrame("Hint UI");
hintFrame.setSize(450, 150);
hintFrame.setLayout(new GridLayout(0, 5));
hintFrame.getContentPane().setBackground(BACKGROUND);
hintTypes = new JLabel[10];
hintTypes[0] = new JLabel("1", SwingConstants.CENTER);
hintTypes[0].setForeground(Color.white);
hintTypes[0].addMouseListener(new HintMouseListener(true, 0));
hintTypes[1] = new JLabel("2", SwingConstants.CENTER);
hintTypes[1].setForeground(Color.white);
hintTypes[1].addMouseListener(new HintMouseListener(true, 1));
hintTypes[2] = new JLabel("3", SwingConstants.CENTER);
hintTypes[2].setForeground(Color.white);
hintTypes[2].addMouseListener(new HintMouseListener(true, 2));
hintTypes[3] = new JLabel("4", SwingConstants.CENTER);
hintTypes[3].setForeground(Color.white);
hintTypes[3].addMouseListener(new HintMouseListener(true, 3));
hintTypes[4] = new JLabel("5", SwingConstants.CENTER);
hintTypes[4].setForeground(Color.white);
hintTypes[4].addMouseListener(new HintMouseListener(true, 4));
hintTypes[5] = new JLabel("G", SwingConstants.CENTER);
hintTypes[5].setForeground(Color.green);
hintTypes[5].addMouseListener(new HintMouseListener(false, GREEN));
hintTypes[6] = new JLabel("R", SwingConstants.CENTER);
hintTypes[6].setForeground(Color.red);
hintTypes[6].addMouseListener(new HintMouseListener(false, RED));
hintTypes[7] = new JLabel("Y", SwingConstants.CENTER);
hintTypes[7].setForeground(Color.yellow);
hintTypes[7].addMouseListener(new HintMouseListener(false, YELLOW));
hintTypes[8] = new JLabel("W", SwingConstants.CENTER);
hintTypes[8].setForeground(Color.white);
hintTypes[8].addMouseListener(new HintMouseListener(false, WHITE));
hintTypes[9] = new JLabel("B", SwingConstants.CENTER);
hintTypes[9].setForeground(Color.blue);
hintTypes[9].addMouseListener(new HintMouseListener(false, BLUE));
for(int i=0; i<hintTypes.length; ++i){
hintTypes[i].setBackground(BACKGROUND);
hintTypes[i].setFont(font);
hintFrame.add(hintTypes[i]);
}
hintFrame.validate();
hintFrame.setVisible(false);
}
private void toggleHintUi(int x, int y){
hintFrame.setLocation(x, y);
hintFrame.setVisible(!hintFrame.isVisible());
}
@Override
protected void createUi() {
clickedPlayer = 0;
layoutConstr = new GridBagConstraints();
mainFrame = new JFrame("Hanabi - Player " + (ownId+1) + " (" + players[ownId].getName() + ")");
mainFrame.setSize(1000, 650);
mainFrame.setLocation(0, 0);
mainFrame.setLayout(new GridBagLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.getContentPane().setBackground(BACKGROUND);
mainFrame.setVisible(true);
gamePanel = new JPanel();
gamePanel.setLayout(new BoxLayout(gamePanel, BoxLayout.Y_AXIS));
GridLayout deckLayout = new GridLayout(COLORS, 5);
playingDeckPanel = new JPanel(deckLayout);
playingDeckPanel.setBackground(BACKGROUND);
playingDeckUi = new JLabel[COLORS][5];
for(int i=0; i<COLORS; ++i){
for(int j=0; j<5; ++j){
JLabel tmp = new JLabel("X");
tmp.setBackground(BACKGROUND);
tmp.setForeground(Color.white);
tmp.setFont(font);
tmp.setHorizontalAlignment(JLabel.CENTER);
playingDeckUi[i][j] = tmp;
playingDeckPanel.add(playingDeckUi[i][j]);
}
}
hintPanel = new JPanel();
hintPanel.setBackground(BACKGROUND);
flashPanel = new JPanel();
flashPanel.setBackground(BACKGROUND);
//first empty cell
layoutConstr.gridx = 0;
layoutConstr.gridy = 0;
layoutConstr.weightx = 0.2;
layoutConstr.weighty = 0.1;
layoutConstr.gridwidth = 1;
mainFrame.add(new JPanel(), layoutConstr);
layoutConstr.gridx = 1;
if(nPlayers < 5){
layoutConstr.weightx = 0.6;
layoutConstr.gridwidth = 1;
int index = (nPlayers == 2) ? 1 : 2;
//mainFrame.add(((SwingPlayer) players[index]).getContainer(), layoutConstr);
JPanel playerPanel = ((SwingPlayer) players[getPlayersSightId(index)]).getPlayerUi();
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.X_AXIS));
mainFrame.add(playerPanel, layoutConstr);
} else {
layoutConstr.weightx = 0.3;
layoutConstr.gridwidth = 1;
//mainFrame.add(((SwingPlayer) players[3]).getContainer(), layoutConstr);
JPanel playerPanel = ((SwingPlayer) players[getPlayersSightId(3)]).getPlayerUi();
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.X_AXIS));
mainFrame.add(playerPanel, layoutConstr);
layoutConstr.gridx = 2;
//mainFrame.add(((SwingPlayer) players[2]).getContainer(), layoutConstr);
playerPanel = ((SwingPlayer) players[getPlayersSightId(2)]).getPlayerUi();
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.X_AXIS));
mainFrame.add(playerPanel, layoutConstr);
}
//second empty cell
layoutConstr.gridx = (nPlayers < 5) ? 2 : 3;
layoutConstr.weightx = 0.2;
layoutConstr.gridwidth = 1;
mainFrame.add(new JPanel(), layoutConstr);
//4th or 5th player
layoutConstr.gridx = 0;
layoutConstr.gridy = 1;
layoutConstr.weightx = 0.2;
layoutConstr.weighty = 0.8;
layoutConstr.gridwidth = 1;
if(nPlayers == 2 || nPlayers == 3){
mainFrame.add(new JPanel(), layoutConstr);
} else {
int index = (nPlayers == 4) ? 3 : 4;
//mainFrame.add(((SwingPlayer) players[index]).getContainer(), layoutConstr);
JPanel playerPanel = ((SwingPlayer) players[getPlayersSightId(index)]).getPlayerUi();
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.Y_AXIS));
mainFrame.add(playerPanel, layoutConstr);
}
layoutConstr.gridx = 1;
layoutConstr.weightx = 0.6;
layoutConstr.gridwidth = (nPlayers < 5) ? 1 : 2;
mainFrame.add(gamePanel, layoutConstr);
//2nd player
layoutConstr.gridx = (nPlayers < 5) ? 2 : 3;
layoutConstr.weightx = 0.2;
layoutConstr.gridwidth = 1;
if(nPlayers == 2){
mainFrame.add(new JPanel(), layoutConstr);
} else {
//mainFrame.add(((SwingPlayer) players[1]).getContainer(), layoutConstr);
JPanel playerPanel = ((SwingPlayer) players[getPlayersSightId(1)]).getPlayerUi();
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.Y_AXIS));
mainFrame.add(playerPanel, layoutConstr);
}
//third empty cell
layoutConstr.gridx = 0;
layoutConstr.gridy = 2;
layoutConstr.weightx = 0.2;
layoutConstr.weighty = 0.1;
layoutConstr.gridwidth = 1;
mainFrame.add(new JPanel(), layoutConstr);
layoutConstr.gridx = 1;
layoutConstr.weightx = 0.6;
layoutConstr.gridwidth = (nPlayers < 5) ? 1 : 2;
//mainFrame.add(((SwingPlayer) players[0]).getContainer(), layoutConstr);
JPanel playerPanel = ((SwingPlayer) players[getPlayersSightId(0)]).getPlayerUi();
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.X_AXIS));
mainFrame.add(playerPanel, layoutConstr);
//fourth empty cell
layoutConstr.gridx = (nPlayers < 5) ? 2 : 3;
layoutConstr.weightx = 0.2;
layoutConstr.gridwidth = 1;
mainFrame.add(new JPanel(), layoutConstr);
gamePanel.add(hintPanel);
gamePanel.add(flashPanel);
gamePanel.add(playingDeckPanel);
hintUi = new JLabel[MAX_HINTS];
for(int i=0; i<MAX_HINTS; ++i){
JLabel tmp = new JLabel();
tmp.setIcon(HINT_1);
tmp.setForeground(Color.white);
tmp.setName("Hint_" + i);
tmp.setFont(font);
hintPanel.add(tmp);
hintUi[i] = tmp;
}
flashUi = new JLabel[MAX_FLASHS];
for(int i=0;i<MAX_FLASHS; ++i){
JLabel tmp = new JLabel();
tmp.setIcon(FLASH_0);
tmp.setForeground(Color.white);
tmp.setName("Flash_" + i);
tmp.setFont(font);
flashPanel.add(tmp);
flashUi[i] = tmp;
}
mainFrame.validate();
createHintUi();
}
@Override
public void loadFont() {
font = new Font("Shanghai", Font.PLAIN, fontSize);
}
@Override
protected BasePlayer createPlayer(int id, int nrOfCards, String name){
return new SwingPlayer(id, nrOfCards, name);
}
@Override
protected BasePlayer createPlayer(JSONObject jo){
return new SwingPlayer(jo);
}
@Override
protected void updateUi() {
for(int i=0; i<hints; ++i){
hintUi[i].setIcon(HINT_1);
}
for(int i=hints; i<MAX_HINTS; ++i){
hintUi[i].setIcon(HINT_0);
}
for(int i=0; i<flashs; ++i){
flashUi[i].setIcon(FLASH_1);
}
for(int i=flashs; i<MAX_FLASHS; ++i){
flashUi[i].setIcon(FLASH_0);
}
for(int i=0; i<playingDeck.length; ++i){
for(int j=0; j<playingDeck[i].length; ++j){
String value = String.valueOf(playingDeck[i][j].getValue() + 1);
playingDeckUi[i][j].setText(value);
playingDeckUi[i][j].setForeground(getColor(playingDeck[i][j].getColorInt()));
}
}
}
private static Color getColor(int id){
Color color = null;
switch(id){
case 0:
color = Color.green;
break;
case 1:
color = Color.red;
break;
case 2:
color = Color.yellow;
break;
case 3:
color = Color.white;
break;
case 4:
color = Color.blue;
break;
}
return color;
}
private class SwingPlayer extends BasePlayer {
JPanel playerUi;
JButton playerName;
JLabel[] cardUi;
PlaceListener placeListener;
public SwingPlayer(int id, int nrOfCards, String name){
super(id, nrOfCards, name);
playerUi = new JPanel();
playerUi.setBackground(BACKGROUND);
playerName = new JButton();
String text = name;
if(ownId == id){
playerName.setEnabled(false);
text += " (You)";
} else {
playerName.addMouseListener(new HintListener(id));
}
playerName.setText(text);
playerUi.add(playerName);
cardUi = new JLabel[nrOfCards];
for(int i=0; i<cardUi.length; ++i){
cardUi[i] = new JLabel();
cardUi[i].setFont(font);
cardUi[i].setBackground(BACKGROUND);
playerUi.add(cardUi[i]);
}
}
public SwingPlayer(JSONObject jo) {
super(jo);
playerUi = new JPanel();
playerUi.setBackground(BACKGROUND);
playerName = new JButton(name);
playerName.addMouseListener(new HintListener(id));
playerUi.add(playerName);
cardUi = new JLabel[cards.length];
for(int i=0; i<cardUi.length; ++i){
JLabel uiCard = new JLabel(String.valueOf(cards[i].getValue() + 1));
uiCard.setForeground(getColor(cards[i].getColorInt()));
uiCard.setBackground(BACKGROUND);
uiCard.setFont(font);
uiCard.addMouseListener(new PlaceListener(cards[i]));
cardUi[i] = uiCard;
playerUi.add(cardUi[i]);
}
}
@Override
public void setCards(JSONArray ja){
super.setCards(ja);
Log("set Swing cards");
for(int i=0; i<cards.length; ++i){
if(cardUi[i] == null) cardUi[i] = new JLabel();
JLabel tmp = cardUi[i];
String text = "";
Color color = null;
if(ownId == id){
text = "?";
color = Color.gray;
tmp.removeMouseListener(placeListener);
placeListener = new PlaceListener(cards[i]);
tmp.addMouseListener(placeListener);
} else {
text = String.valueOf(cards[i].getValue()+1);
color = getColor(cards[i].getColorInt());
}
tmp.setText(text);
tmp.setForeground(color);
List<CardInfo> infos = cards[i].getCardInfos();
String toolTipText = "";
for(CardInfo info : infos){
toolTipText += info.isIs() ? "is " : "not ";
if(info.getType() == HINT_COLOR){
toolTipText += Card.intColorToText(info.getWhat());
} else {
toolTipText += String.valueOf(info.getWhat() + 1);
}
toolTipText += " (From Player " + info.getFrom() + ")";
toolTipText += "\n";
}
tmp.setToolTipText(toolTipText);
cardUi[i] = tmp;
}
}
public JPanel getPlayerUi(){
return playerUi;
}
}
private class HintMouseListener implements MouseListener {
private boolean isValue;
private int value;
public HintMouseListener(boolean isValue, int value) {
this.isValue = isValue;
this.value = value;
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e)){
moveHint(isValue, value, clickedPlayer);
toggleHintUi(e.getXOnScreen(), e.getYOnScreen());
}
}
}
private class HintListener implements MouseListener {
private int playerId;
public HintListener(int playerId){
this.playerId = playerId;
}
@Override
public void mouseReleased(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e)){
Log("Hint!");
clickedPlayer = playerId;
toggleHintUi(e.getXOnScreen(), e.getYOnScreen());
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
}
private class PlaceListener implements MouseListener {
private Card c;
public PlaceListener(Card c){
this.c = c;
}
@Override
public void mouseReleased(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e)){
movePlaceCard(c);
} else if(SwingUtilities.isRightMouseButton(e)){
moveTrashCard(c);
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
}
}