package arcade.games;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.swing.ImageIcon;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import arcade.controller.Controller;
import arcade.database.Database;
public class GameInfo {
private static final String USER_DIRECTORY = System.getProperty("user.dir");
public static final String FILEPATH = "games.";
public static final String RESOURCE_DIR_NAME = ".resources.";
public static final String FILE_NAME = ".example";
public static final String GAME_NAME = "name";
public static final String THUMBNAIL_NAME = "thumbnail";
public static final String AD_SCREEN = "adscreen";
public static final String AGE_LIMIT_NAME = "agepermission";
public static final String PRICE_KEYWORD = "price";
public static final String GAME_MAIN_CLASS_KEYWORD = "extendsGame";
public static final String MULTIPLAYER_GAME_MAIN_CLASS_KEYWORD = "extendsMultiplayergame";
public static final String DESCRIPTION_KEYWORD = "description";
private ResourceBundle myResourceBundle;
private Controller myModel;
private Database myDb;
private String myGameName;
public GameInfo (String gamename, String genre, String language, Controller model)
throws MissingResourceException {
String filepath = FILEPATH + genre + "." + gamename + RESOURCE_DIR_NAME + language;
myModel = model;
myResourceBundle = ResourceBundle.getBundle(filepath);
}
public GameInfo (Database database, String id) {
myDb = database;
myGameName = id;
}
public ImageIcon getThumbnail () {
return new ImageIcon(USER_DIRECTORY + myDb.getGameThumbnail(myGameName));
}
public String getAuthor() {
return myDb.getAuthor(myGameName);
}
public String getName () {
return myGameName;
}
public String getDescription () {
return myDb.getGameDescription(myGameName);
}
public ImageIcon getAdScreen () {
return new ImageIcon(USER_DIRECTORY + myDb.getGameAdScreen(myGameName));
}
public double getRating () {
List<Comment> comments = myDb.retrieveCommentsForGame(myGameName);
double averageRating = 0;
if (comments.size() != 0) {
double sum = 0;
for (Comment comment : comments) {
sum += comment.getRating();
}
averageRating = sum / comments.size();
}
return averageRating;
}
public double getPrice () {
return myDb.getPrice(myGameName);
}
private String getSingleplayerGameClassKeyword () {
return myDb.getSingleplayerGameClassKeyword(myGameName);
}
public List<Comment> getComments () {
return myDb.retrieveCommentsForGame(myGameName);
}
public List<Score> getScores () {
return myDb.getScoresForGame(myGameName);
}
public List<Score> getSortedScores () {
List<Score> scores = getScores();
Collections.sort(scores);
return scores;
}
public String getGenre () {
return myDb.getGenre(myGameName);
}
// Here, there be shiny reflective dragons . . .
/*
* but seriously, the reflection here is really fragile, we should add some exception handling
* when
* we get a chance. I just want to make sure that it works for now. This whole class makes
* me nervous cause we use a handwritten properties file and we're really relying on the game
* name
* being the same as the class name, being the same as the game name thats stored in the
* database.
*
* In the future, we should consider adding on to the publish procedure a way of generating the
* properties
* file algorithmically, which would tighten this up a little and make it less error prone. Once
* we do that,
* then we should be able to preserve the game names across the class name, the database game
* name, the
* properties file name , and the directory name. This is a later feature though. for now, the
* game
* developers will have to worry about getting things exactly right :(
*/
// I SAY I will add better exception handling here but . . . .
@SuppressWarnings({ "rawtypes", "unchecked" })
public Game getGame (Controller model) {
Class gameClass = getSingleplayerGameClass();
try {
Constructor con = gameClass.getConstructor(ArcadeInteraction.class);
try {
return (Game) con.newInstance(model);
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (InstantiationException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
// TODO make sure this doesnt break if the game isnt single player
@SuppressWarnings("rawtypes")
private Class getSingleplayerGameClass () {
try {
//System.out.println(getSingleplayerGameClassKeyword());
return Class.forName(getSingleplayerGameClassKeyword());
}
catch (ClassNotFoundException e) {
// add some additional tries for letter case, then throw an exception
return null;
}
}
@SuppressWarnings("unchecked")
public GameData getGameData (Game theGame) {
try {
return myDb.getGameData(myGameName);
}
catch (AmazonS3Exception e) {// this should actually be the amazon error. replace.
@SuppressWarnings("rawtypes")
Class game = getClass();
Method method;
try {
method = game.getMethod("generateNewGameProfile");
try {
return (GameData) method.invoke(theGame);
}
catch (IllegalArgumentException e1) {
e1.printStackTrace();
}
catch (IllegalAccessException e1) {
e1.printStackTrace();
}
catch (InvocationTargetException e1) {
e1.printStackTrace();
}
}
catch (SecurityException e1) {
e1.printStackTrace();
}
catch (NoSuchMethodException e1) {
e1.printStackTrace();
}
return null;
}
}
private void print (Object o) {
System.out.println(o);
}
@SuppressWarnings("unchecked")
public UserGameData getUserGameData (Game theGame, String user) {
try {
return myDb.getUserGameData(myGameName, user);
}
catch (AmazonS3Exception e) {
@SuppressWarnings("rawtypes")
Class game = getSingleplayerGameClass();
Method method;
try {
method = game.getMethod("generateNewProfile");
try {
return (UserGameData) method.invoke(theGame);
}
catch (IllegalArgumentException e1) {
e1.printStackTrace();
}
catch (IllegalAccessException e1) {
e1.printStackTrace();
}
catch (InvocationTargetException e1) {
e1.printStackTrace();
}
}
catch (SecurityException e1) {
e1.printStackTrace();
}
catch (NoSuchMethodException e1) {
e1.printStackTrace();
}
return null;
}
}
}