package common.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import common.Face;
import common.FaceModel;
import common.FaceModel.FacePart;
import common.clientevent.FaceChooserClientEvent;
public class FaceChooser extends JFrame {
private static final long serialVersionUID = 3544949952699576885L;
private FaceModel model; private List<Integer> parts;
private final JPanel sidePanel = new JPanel(); private final JLabel faceLabel = new JLabel(); private final JButton modelButton; private final JButton randomButton; private final JPanel loadingPanel = new JPanel(new BorderLayout()); private final JProgressBar loadingBar = new JProgressBar(); private final JButton saveButton = new JButton("Save & Exit"); private final JButton cancelButton = new JButton("Cancel");
private Collection<JButton> buttons = new ArrayList<JButton>();
private static final Random random = new Random();
public FaceChooser(Face face) {
super("Face Chooser");
modelButton = new JButton("Model");
modelButton.setAlignmentX(0.5f);
randomButton = new JButton("Random");
randomButton.setAlignmentX(0.5f);
sidePanel.setLayout(new BoxLayout(sidePanel, BoxLayout.Y_AXIS));
sidePanel.setBackground(Color.black);
sidePanel.setBorder(new EmptyBorder(5, 5, 5, 5));
JPanel facePanel = new JPanel();
facePanel.setOpaque(false);
facePanel.setLayout(new BoxLayout(facePanel, BoxLayout.Y_AXIS));
faceLabel.setAlignmentX(0.5f);
facePanel.add(Box.createVerticalGlue());
facePanel.add(faceLabel);
facePanel.add(Box.createVerticalGlue());
JPanel mainPanel = new JPanel();
mainPanel.setBackground(Color.black);
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS));
mainPanel.add(Box.createHorizontalGlue());
mainPanel.add(sidePanel);
mainPanel.add(Box.createHorizontalStrut(5));
mainPanel.add(facePanel);
mainPanel.add(Box.createHorizontalGlue());
add(mainPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
buttonPanel.add(saveButton);
buttonPanel.add(cancelButton);
buttonPanel.setOpaque(false);
JLabel loadingLabel = new JLabel("Loading:");
loadingLabel.setBorder(new EmptyBorder(5, 5, 5, 5));
loadingLabel.setForeground(Color.white);
loadingBar.setOpaque(false);
loadingBar.setBorder(new CompoundBorder(new EmptyBorder(10, 0, 10, 0), loadingBar.getBorder()));
loadingBar.setIndeterminate(true);
loadingPanel.setOpaque(false);
loadingPanel.add(loadingLabel, BorderLayout.WEST);
loadingPanel.add(loadingBar, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel(new BorderLayout());
bottomPanel.setBackground(Color.black);
bottomPanel.add(loadingPanel, BorderLayout.CENTER);
bottomPanel.add(buttonPanel, BorderLayout.EAST);
add(bottomPanel, BorderLayout.SOUTH);
modelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
nextModel();
}
});
randomButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
randomizeParts();
redrawFace();
}
});
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
saveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
GameClient.send(new FaceChooserClientEvent(new Face(model, parts)));
dispose();
}
});
if (face == null) {
nextModel(); }
else {
model = face.getFaceModel();
parts = new ArrayList<Integer>(face.getParts());
prepareModel();
}
setLocationByPlatform(true);
}
private void nextModel() {
int modelNum = model == null ? -1 : model.ordinal();
FaceModel[] models = FaceModel.values();
model = models[++modelNum % models.length];
randomizeParts();
prepareModel();
}
private void prepareModel() {
buttons.clear();
sidePanel.removeAll();
sidePanel.add(Box.createVerticalGlue());
sidePanel.add(modelButton);
sidePanel.add(Box.createVerticalStrut(5));
sidePanel.add(randomButton);
sidePanel.add(Box.createVerticalStrut(20));
List<FacePart> faceParts = model.getFaceParts();
int idx = 0;
for (FacePart facePart : faceParts) {
if (facePart.isStatic()) {
continue;
}
if (idx > 0) {
sidePanel.add(Box.createVerticalStrut(5));
}
final int fidx = idx++;
final int partCount = facePart.getCount();
JButton partButton = new JButton(facePart.getName());
partButton.setAlignmentX(0.5f);
sidePanel.add(partButton);
partButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int value = parts.get(fidx);
value %= partCount;
value++;
parts.set(fidx, value);
redrawFace();
}
});
buttons.add(partButton);
}
sidePanel.add(Box.createVerticalGlue());
faceLabel.setIcon(FaceIcon.LOADING_IMAGE);
redrawFace();
pack();
repaint();
}
private void randomizeParts() {
List<Integer> oldParts = parts;
parts = new ArrayList<Integer>();
for (FacePart facePart : model.getFaceParts()) {
if (facePart.isStatic()) {
continue;
}
int part = 1;
for (int i = 0; i < 10; i++) {
part = random.nextInt(facePart.getCount()) + 1;
if (oldParts == null) {
break; }
if (parts.size() >= oldParts.size()) {
break; }
if (oldParts.get(parts.size()) != part) {
break;
}
}
parts.add(part);
}
}
private void redrawFace() {
setLoading(true);
loadingBar.setIndeterminate(true);
loadingPanel.setVisible(true);
new Thread() {
@Override
public void run() {
Icon icon = null;
try {
icon = new FaceIcon(new Face(model, parts));
}
finally {
final Icon ficon = icon;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
faceLabel.setIcon(ficon);
setLoading(false);
}
});
}
}
}.start();
}
private void setLoading(boolean loading) {
for (JButton b : buttons) {
b.setEnabled(!loading);
}
saveButton.setEnabled(!loading);
cancelButton.setEnabled(!loading);
modelButton.setEnabled(!loading);
randomButton.setEnabled(!loading);
loadingPanel.setVisible(loading);
loadingBar.setIndeterminate(loading);
repaint();
}
}