package magic.ui.screen.deck.editor;
import java.awt.event.ActionEvent;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.swing.AbstractAction;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import magic.data.DeckType;
import magic.data.GeneralConfig;
import magic.data.MagicIcon;
import magic.data.MagicSetDefinitions;
import magic.exception.InvalidDeckException;
import magic.model.MagicDeck;
import magic.ui.MagicFileChoosers;
import magic.ui.MagicLogs;
import magic.ui.ScreenController;
import magic.ui.WikiPage;
import magic.ui.screen.HeaderFooterScreen;
import magic.ui.screen.MScreen;
import magic.ui.screen.duel.decks.DuelDecksScreen;
import magic.ui.screen.interfaces.IDeckConsumer;
import magic.ui.screen.widget.MenuButton;
import magic.ui.widget.deck.DeckStatusPanel;
import magic.utility.DeckUtils;
@SuppressWarnings("serial")
public class DeckEditorSplitScreen extends HeaderFooterScreen
implements IDeckConsumer {
private final DeckEditorSplitPanel screenContent;
private final boolean isStandalone;
private final DeckStatusPanel deckStatusPanel = new DeckStatusPanel();
// CTR : opens Deck Editor ready to update passed in deck.
public DeckEditorSplitScreen(final MagicDeck deck) {
super("Deck Editor");
isStandalone = (deck == null);
this.screenContent = new DeckEditorSplitPanel(deck);
setMainContent(this.screenContent);
setHeaderContent(deckStatusPanel);
setLeftFooter(getLeftAction());
setRightFooter(getRightAction());
addToFooter(
MenuButton.build(this::loadDeck,
MagicIcon.OPEN, "Select Deck", "Select an existing prebuilt or player deck."
),
MenuButton.build(this::saveDeck,
MagicIcon.SAVE, "Save Deck", "Save deck to file."
),
MenuButton.build(this::showSampleHand,
MagicIcon.HAND_ICON, "Sample Hand", "See what kind of Hand you might be dealt from this deck."
),
MenuButton.build(this::showDeckImageView,
MagicIcon.TILED, "Deck View", "Shows complete deck using tiled card images."
)
);
setWikiPage(WikiPage.DECK_EDITOR);
}
// CTR : open Deck Editor in standalone mode starting with an empty deck.
public DeckEditorSplitScreen() {
this(null);
loadMostRecentDeck();
}
private void showSampleHand() {
if (screenContent.getDeck().size() >= 7) {
ScreenController.showSampleHandScreen(screenContent.getDeck());
} else {
showInvalidActionMessage("A deck with a minimum of 7 cards is required first.");
}
}
private void showDeckImageView() {
if (screenContent.getDeck().size() > 0) {
ScreenController.showDeckTiledCardsScreen(screenContent.getDeck());
} else {
showInvalidActionMessage("Deck is empty! Nothing to show.");
}
}
private void loadMostRecentDeck() {
final Path deckFilePath = GeneralConfig.getInstance().getMostRecentDeckFilePath();
if (deckFilePath != null) {
final MagicDeck recentDeck = loadDeck(deckFilePath);
if (recentDeck != null && recentDeck.isValid()) {
this.screenContent.setDeck(recentDeck);
deckStatusPanel.setDeck(recentDeck, false);
}
}
}
private MagicDeck loadDeck(final Path deckFilePath) {
try {
return DeckUtils.loadDeckFromFile(deckFilePath);
} catch (InvalidDeckException ex) {
// if the most recent deck is invalid for some reason then I think it suffices
// to log the error to console and open the deck editor with an empty deck.
System.err.println(ex);
return null;
}
}
public MenuButton getLeftAction() {
final String caption = (!screenContent.isStandaloneDeckEditor() ? "Cancel" : "Close");
return MenuButton.getCloseScreenButton(caption);
}
public MenuButton getRightAction() {
if (!screenContent.isStandaloneDeckEditor()) {
return new MenuButton("Use this deck", new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (screenContent.validateDeck(true) && screenContent.applyDeckUpdates()) {
ScreenController.closeActiveScreen(false);
}
}
});
} else {
return null;
}
}
private void showInvalidActionMessage(final String message) {
ScreenController.showWarningMessage(message);
}
public void createNewEmptyDeck() {
screenContent.setDeck(new MagicDeck());
}
public void loadDeck() {
ScreenController.showDecksScreen(this);
}
public void saveDeck() {
if (screenContent.getDeck().size() == 0) {
showInvalidActionMessage("Deck is empty! Nothing to save.");
return;
}
final JFileChooser fileChooser = new JFileChooser(DeckUtils.getDecksFolder().toString()) {
@Override
public void approveSelection() {
// first ensure filename has "dec" extension
String filename = getSelectedFile().getAbsolutePath();
if (!filename.endsWith(DeckUtils.DECK_EXTENSION)) {
setSelectedFile(new File(filename + DeckUtils.DECK_EXTENSION));
}
final Path prebuiltDecksFolder = DeckUtils.getPrebuiltDecksFolder();
final Path saveFolder = getSelectedFile().toPath().getParent();
if (saveFolder.equals(prebuiltDecksFolder)) {
ScreenController.showWarningMessage("This directory is reserved for prebuilt decks.\nPlease choose a different directory.");
} else if (Files.exists(getSelectedFile().toPath())) {
int response = JOptionPane.showConfirmDialog(
ScreenController.getFrame(),
"Overwrite existing deck file?",
"Overwrite file",
JOptionPane.YES_NO_OPTION);
if (response == JOptionPane.YES_OPTION) {
super.approveSelection();
}
} else {
super.approveSelection();
}
}
};
final MagicDeck deck = screenContent.getDeck();
fileChooser.setDialogTitle("Save deck");
fileChooser.setFileFilter(MagicFileChoosers.DECK_FILEFILTER);
fileChooser.setAcceptAllFileFilterUsed(false);
if (deck != null) {
fileChooser.setSelectedFile(new File(deck.getFilename()));
}
final int action = fileChooser.showSaveDialog(ScreenController.getFrame());
if (action == JFileChooser.APPROVE_OPTION) {
final String filename = fileChooser.getSelectedFile().getAbsolutePath();
if (DeckUtils.saveDeck(filename, screenContent.getDeck())) {
final String shortFilename = fileChooser.getSelectedFile().getName();
screenContent.getDeck().setFilename(shortFilename);
screenContent.setDeck(screenContent.getDeck());
setMostRecentDeck(filename);
} else {
ScreenController.showWarningMessage("There was a problem saving the deck file!");
}
}
}
private void setMostRecentDeck(final String filename) {
if (isStandalone) {
GeneralConfig.getInstance().setMostRecentDeckFilename(filename);
GeneralConfig.getInstance().save();
}
}
/*
* (non-Javadoc)
*
* @see magic.ui.MagScreen#canScreenClose()
*/
@Override
public boolean isScreenReadyToClose(MScreen nextScreen) {
if (screenContent.isDeckEditor() && !screenContent.isStandaloneDeckEditor() && nextScreen instanceof DuelDecksScreen) {
((DuelDecksScreen)nextScreen).updateDecksAfterEdit();
}
MagicSetDefinitions.clearLoadedSets();
MagicLogs.clearLoadedLogs();
return true;
}
@Override
public boolean setDeck(MagicDeck deck, Path deckPath) {
screenContent.setDeck(deck);
setMostRecentDeck(deckPath.toString());
deckStatusPanel.setDeck(deck, false);
return true;
}
@Override
public void setDeck(String deckName, DeckType deckType) { }
@Override
public void setDeck(MagicDeck deck) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}