package arcade.view.forms;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import twitter4j.TwitterException;
import util.ImageHelper;
import arcade.controller.Controller;
import arcade.games.Score;
import arcade.view.MainView;
import arcade.view.TextKeywords;
/**
* The view that shows up at the end of the game. Shows the user's score here,
* high scores, and the option to tweet his/her score.
*
* @author Ellango
*
*/
@SuppressWarnings({ "serial", "unused" })
public class ScoresView extends Form {
private static final String BUTTON_IMAGE = "Twitter.gif";
private static final int NAME_WIDTH = 100;
private static final int SCORE_WIDTH = 40;
private static final int MAX_HIGH_SCORES_SHOWN = 5;
private static final int WINDOW_WIDTH = 270;
private static final int HEIGHT_OFFSET = 20;
private int myScore;
private String myGameName;
private JLabel myUserScore;
private JPanel myPinPanel;
private JTextField myPinTextField;
/**
* Creates a ScoresView with a Controller, ResourceBundle, and the score
* of the user for the game that has just been played.
*
* @param controller
* @param resources
*/
public ScoresView (Controller controller, ResourceBundle resources, int score) {
super(controller, resources);
myScore = score;
myGameName = controller.getCurrentGame();
setUserScoreMessage(score);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBounds(0, 0, WINDOW_WIDTH, getPreferredSize().height + HEIGHT_OFFSET);
setLocationRelativeTo(null);
}
/**
* Creates the message for the user displaying his/her score.
*
* To fill in the label, must call setUserScoreMessage
* @return
*/
private JComponent createUserScoreMessage() {
JPanel panel = new JPanel();
myUserScore = new JLabel("");
panel.add(myUserScore);
return panel;
}
/**
* Creates the heading to denote high scores are listed below.
* @return
*/
private JComponent createHighScoresHeading() {
return createInstruction(TextKeywords.HIGH_SCORES);
}
/**
* Creates the list of the high scores for the game that has just been played.
* @return
*/
private JComponent createHighScoresList() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
List<Score> scores = getController().getCurrentGameInfo().getSortedScores();
if (scores.size() > MAX_HIGH_SCORES_SHOWN) {
scores = scores.subList(0, MAX_HIGH_SCORES_SHOWN);
}
int ranking = 1;
for (Score score : scores) {
JPanel row = new JPanel();
row.add(new JLabel(ranking + ". "));
JLabel user = new JLabel(score.getUser());
user.setPreferredSize(new Dimension(NAME_WIDTH, user.getPreferredSize().height));
row.add(user);
JLabel points = new JLabel(score.getScore()+"");
points.setPreferredSize(new Dimension(SCORE_WIDTH, points.getPreferredSize().height));
row.add(points);
row.setOpaque(false);
panel.add(row);
ranking++;
}
return panel;
}
/**
* Creates the button to start the tweet request.
*
* @return
*/
private JComponent createTweetButton () {
JPanel panel = new JPanel();
ImageIcon icon = new ImageIcon(MainView.IMAGES_DIRECTORY + BUTTON_IMAGE);
final JButton button = new JButton(icon);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed (ActionEvent arg0) {
startTwitterRequest();
button.setEnabled(false);
}
});
panel.add(button);
return panel;
}
/**
* Starts the Twitter request. Opens up a browser for the user to
* authorize the twitter request. Sets the panel visible for the user
* to enter the pin after they finish authorizing.
*/
private void startTwitterRequest() {
try {
String urlToAuthorize = getController().setUpTwitterRequest();
Desktop.getDesktop().browse(URI.create(urlToAuthorize));
myPinPanel.setVisible(true);
setBounds(0, 0, WINDOW_WIDTH, getPreferredSize().height + HEIGHT_OFFSET);
setLocationRelativeTo(null);
}
catch (TwitterException e) {
sendMessage(getResources().getString(TextKeywords.TWITTER_ERROR));
}
catch (IOException e) {
sendMessage(getResources().getString(TextKeywords.TWITTER_ERROR));
}
}
/**
* Creates the panel where the user can enter the pin for the twitter
* authorization.
*
* Initially set as invisible until startTwitterRequest() called.
* @return
*/
private JComponent createPinEntry () {
myPinPanel = new JPanel();
myPinPanel.setLayout(new BoxLayout(myPinPanel, BoxLayout.Y_AXIS));
myPinTextField = new JTextField();
JComponent textPane = createTextPanel(TextKeywords.PIN_INSTRUCTION, myPinTextField);
textPane.setOpaque(false);
myPinPanel.add(textPane);
JComponent submitButton = createButton(TextKeywords.SUBMIT,
new ActionListener() {
@Override
public void actionPerformed (ActionEvent e) {
sendTweet();
}
});
submitButton.setOpaque(false);
myPinPanel.add(submitButton);
myPinPanel.setVisible(false);
return myPinPanel;
}
/**
* After clicking the submit button for the pin, send the tweet
* message for the game and score.
*/
private void sendTweet() {
String pin = myPinTextField.getText();
try {
getController().sendTweet(pin, generateTweetMessage());
}
catch (TwitterException e) {
sendMessage(getResources().getString(TextKeywords.TWITTER_ERROR));
}
}
/**
* Returns the string to be tweeted.
* @return
*/
private String generateTweetMessage() {
return getResources().getString(TextKeywords.MY_SCORE)
+ " " + myScore + " "
+ getResources().getString(TextKeywords.IN) + " "
+ myGameName + " "
+ getResources().getString(TextKeywords.VOOGA_HASHTAG);
}
/**
* Sets the user score message with the text containing the user's score.
*/
private void setUserScoreMessage(double score) {
myUserScore.setText(getResources().getString(TextKeywords.SCORE_MESSAGE) + " " + score);
}
}