/*
* UFO Saved Game Editor
* Copyright (C) 2010 Christopher Davoren
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.rubikscomplex.ufosge.gui;
import net.rubikscomplex.ufosge.gui.table.SavedGameListTable;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import net.rubikscomplex.ufosge.data.SaveInfo;
import net.rubikscomplex.ufosge.data.SavedGame;
import net.rubikscomplex.ufosge.resources.ResourceManager;
/**
*
* @author Chris Davoren
*/
public class SaveSelectFrame extends JFrame implements ActionListener, MouseListener {
SavedGameListTable saveListTable;
Object[][] savedGameData;
public static final int DATA_COLUMN_SLOT = 0;
public static final int DATA_COLUMN_NAME = 1;
public static final int DATA_COLUMN_TIME = 2;
public static final int DATA_COLUMN_TYPE = 3;
static final String[] SAVE_TABLE_COLUMNS = {"Game", "Name", "Date/Time", "Type"};
JLabel dirLabel;
DefaultTableModel tableModel;
/*
* This annotation suppresses the warning thrown by the rowSorter cast.
* TODO: Find out a typesafe way to rewrite this code.
*/
@SuppressWarnings("unchecked")
public SaveSelectFrame(ArrayList<SaveInfo> sgSummaries) {
super("UFOSGE - Select saved game");
setIconImage(ResourceManager.getDefaultFrameIcon().getImage());
tableModel = new DefaultTableModel();
refreshTableModel(sgSummaries);
saveListTable = new SavedGameListTable(tableModel);
saveListTable.addMouseListener(this);
saveListTable.getColumnModel().getColumn(0).setPreferredWidth(20);
saveListTable.setFillsViewportHeight(true);
saveListTable.setAutoCreateRowSorter(true);
TableRowSorter rowSorter = (TableRowSorter)saveListTable.getRowSorter();
rowSorter.setComparator(DATA_COLUMN_SLOT, new IntComparator());
JLabel label = new JLabel("Select saved game to load :");
label.setLabelFor(saveListTable);
dirLabel = new JLabel("Current UFO directory is " + ResourceManager.getUserPreference(ResourceManager.PREF_UFO_DIR));
JScrollPane tableScroller = new JScrollPane(saveListTable);
tableScroller.setPreferredSize(new Dimension(250, 80));
tableScroller.setAlignmentX(Component.LEFT_ALIGNMENT);
JPanel listPanel = new JPanel();
listPanel.setLayout(new BoxLayout (listPanel, BoxLayout.Y_AXIS));
listPanel.add(label);
listPanel.add(Box.createRigidArea(new Dimension(0, 5)));
listPanel.add(tableScroller);
listPanel.add(Box.createRigidArea(new Dimension(0, 5)));
listPanel.add(dirLabel);
listPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
listPanel.setPreferredSize(new Dimension(400, 200));
JButton preferencesButton = new JButton("Preferences...");
preferencesButton.setMnemonic(KeyEvent.VK_P);
preferencesButton.addActionListener(this);
JButton loadButton = new JButton("Load");
loadButton.setMnemonic(KeyEvent.VK_L);
loadButton.addActionListener(this);
JButton exitButton = new JButton("Exit");
exitButton.setMnemonic(KeyEvent.VK_X);
exitButton.addActionListener(this);
getRootPane().setDefaultButton(loadButton);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(preferencesButton);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(loadButton);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(exitButton);
Container contentPane = getContentPane();
contentPane.add(listPanel, BorderLayout.CENTER);
contentPane.add(buttonPanel, BorderLayout.PAGE_END);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
pack();
int locx = ResourceManager.getUserPreferenceInt(ResourceManager.PREF_SAVESELECTFRAME_POSX);
int locy = ResourceManager.getUserPreferenceInt(ResourceManager.PREF_SAVESELECTFRAME_POSY);
if (locx != -1) {
setLocation(locx, locy);
}
else {
setLocationRelativeTo(null);
}
}
protected void refreshTableModel(ArrayList<SaveInfo> sgSummaries) {
savedGameData = new Object[sgSummaries.size()][4];
Iterator<SaveInfo> infoIterator = sgSummaries.iterator();
int datapos = 0;
while (infoIterator.hasNext()) {
SaveInfo info = infoIterator.next();
savedGameData[datapos][DATA_COLUMN_SLOT] = info.slot;
savedGameData[datapos][DATA_COLUMN_NAME] = info.name;
savedGameData[datapos][DATA_COLUMN_TIME] = info.formatTime();
savedGameData[datapos][DATA_COLUMN_TYPE] = info.type == SaveInfo.TYPE_GEOSCAPE ? "Geoscape" : "Battlescape";
datapos++;
}
tableModel.setDataVector(savedGameData, SAVE_TABLE_COLUMNS);
tableModel.fireTableDataChanged();
}
public void actionPerformed(ActionEvent e) {
// System.out.println("Action performed: " + e.getActionCommand());
if ("Exit".equals(e.getActionCommand())) {
this.dispose();
}
else if ("Load".equals(e.getActionCommand())) {
loadSelectedSavedGame();
}
else if ("Preferences...".equals(e.getActionCommand())) {
String oldUfoDir = ResourceManager.getUserPreference(ResourceManager.PREF_UFO_DIR);
PreferencesDialog prefsDialog = new PreferencesDialog(this);
prefsDialog.setVisible(true);
String newUfoDir = ResourceManager.getUserPreference(ResourceManager.PREF_UFO_DIR);
if (oldUfoDir.equals(newUfoDir)) {
return;
}
try {
refreshTableModel(SavedGame.loadSummaries(newUfoDir));
}
catch(IOException ioe) {
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(this, "Error loading saved games from " + newUfoDir + ":\n\n" + ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
protected void loadSelectedSavedGame() {
int selectedRow = saveListTable.getSelectedRow();
if (selectedRow == -1) {
JOptionPane.showMessageDialog(this, "You must select a saved game from the list.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
int selectedSlot = (Integer)savedGameData[saveListTable.convertRowIndexToModel(selectedRow)][DATA_COLUMN_SLOT];
SavedGame game;
try {
game = SavedGame.loadSavedGame(ResourceManager.getUserPreference(ResourceManager.PREF_UFO_DIR), selectedSlot);
// game.printToConsole();
}
catch (IOException e) {
JOptionPane.showMessageDialog(null, "Unable to load saved game:\n" + e.getMessage(), "Load Error", JOptionPane.ERROR_MESSAGE);
return;
}
SaveEditFrame saveEditFrame = new SaveEditFrame(game);
saveEditFrame.setVisible(true);
this.dispose();
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
loadSelectedSavedGame();
}
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
@Override
public void dispose() {
Point loc = getLocation();
ResourceManager.setUserPreferenceInt(ResourceManager.PREF_SAVESELECTFRAME_POSX, loc.x);
ResourceManager.setUserPreferenceInt(ResourceManager.PREF_SAVESELECTFRAME_POSY, loc.y);
super.dispose();
}
static class IntComparator implements Comparator<Integer> {
public int compare(Integer i1, Integer i2) {
return i1.intValue() - i2.intValue();
}
}
}