package magic.ui.screen.duel.decks;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import magic.data.DuelConfig;
import magic.data.MagicIcon;
import magic.exception.InvalidDeckException;
import magic.model.DuelPlayerConfig;
import magic.model.MagicDeck;
import magic.model.MagicDeckConstructionRule;
import magic.model.MagicDuel;
import magic.model.MagicGame;
import magic.translate.MText;
import magic.ui.FontsAndBorders;
import magic.ui.MagicImages;
import magic.ui.ScreenController;
import magic.ui.WikiPage;
import magic.ui.screen.HeaderFooterScreen;
import magic.ui.screen.deck.editor.IDeckEditorClient;
import magic.ui.screen.widget.DuelSettingsPanel;
import magic.ui.screen.widget.MenuButton;
import magic.ui.screen.widget.SampleHandActionButton;
import magic.utility.MagicSystem;
@SuppressWarnings("serial")
public class DuelDecksScreen extends HeaderFooterScreen
implements IDeckEditorClient {
// translatable strings
private static final String _S1 = "Duel Decks";
private static final String _S2 = "Main Menu";
private static final String _S3 = "Restart duel";
private static final String _S4 = "Game %d";
private static final String _S5 = "Deck Editor";
private static final String _S6 = "Open the Deck Editor.";
private static final String _S9 = "%s wins the duel";
private static final String _S10 = "Restart Duel";
private static final String _S11 = "Same players, same decks, same duel settings. Same result...?";
private static final String _S12 = "Deck View";
private static final String _S13 = "Shows complete deck using tiled card images.";
private static final String _S14 = "%s's deck is illegal.\n\n%s";
private final DuelSettingsPanel settingsPanel;
private final DuelDecksPanel screenContent;
private MagicGame nextGame = null;
private final StartGameButton nextGameButton;
private NewGameWorker worker;
private OptionsPanel optionsPanel;
public DuelDecksScreen(final MagicDuel duel) {
super(MText.get(_S1));
screenContent = new DuelDecksPanel(duel);
nextGameButton = new StartGameButton(getStartDuelCaption(), getPlayGameAction());
if (duel.getGamesPlayed() > 0 && MagicSystem.isAiVersusAi() == false) {
saveDuel();
}
MagicImages.clearCache();
setMainContent(screenContent);
if (MagicSystem.isAiVersusAi() == false) {
doGameSetupInBackground(duel);
screenContent.addPropertyChangeListener(
DuelDecksPanel.CP_DECK_CHANGED,
(e) -> { doGameSetupInBackground(duel); }
);
}
final DuelConfig config = duel.getConfiguration();
settingsPanel = new DuelSettingsPanel(config);
settingsPanel.setEnabled(duel.getGamesPlayed() == 0);
settingsPanel.setBorder(null);
settingsPanel.setBackground(FontsAndBorders.TEXTAREA_TRANSPARENT_COLOR_HACK);
settingsPanel.addPropertyChangeListener(
DuelSettingsPanel.CP_CONFIG_UPDATED, evt -> onConfigUpdate()
);
setHeaderContent(settingsPanel);
optionsPanel = new OptionsPanel(this);
setHeaderOptions(optionsPanel);
setFooterButtons();
setWikiPage(WikiPage.DUEL_DECKS);
}
private void onConfigUpdate() {
doGameSetupInBackground(screenContent.getDuel());
}
private void setFooterButtons() {
setLeftFooter(screenContent.getDuel().getGamesPlayed() == 0
? MenuButton.getCloseScreenButton()
: MenuButton.build(this::doShowMainMenu, MText.get(_S2))
);
setRightFooter(screenContent.getDuel().isFinished()
? MenuButton.build(this::doRestartDuel, MText.get(_S3))
: nextGameButton
);
// middle actions
if (isNewDuel()) {
addToFooter(MenuButton.build(this::showDeckEditor,
MagicIcon.DECK, MText.get(_S5), MText.get(_S6)
),
getTiledDeckCardImagesButton(),
SampleHandActionButton.createInstance(getActiveDeck())
);
addToFooter(screenContent.getActionBarButtons());
} else if (isDuelFinished()) {
addToFooter(getWinnerButton());
} else { // duel in progress
addToFooter(getTiledDeckCardImagesButton(),
SampleHandActionButton.createInstance(getActiveDeck()),
MenuButton.build(this::doRestartDuel,
MagicIcon.REFRESH, MText.get(_S10), MText.get(_S11)
)
);
}
}
private MenuButton getTiledDeckCardImagesButton() {
return MenuButton.build(this::showTiledDeckCardImages,
MagicIcon.TILED, MText.get(_S12), MText.get(_S13));
}
/**
* Return to main menu without closing this screen.
*/
private void doShowMainMenu() {
ScreenController.showMainMenuScreen();
}
private void startNextGame() {
final DuelPlayerConfig[] players = screenContent.getDuel().getPlayers();
if (isLegalDeckAndShowErrors(players[0]) && isLegalDeckAndShowErrors(players[1])) {
saveDuel();
ScreenController.showDuelGameScreen(nextGame);
}
}
private void updateDuelConfig() {
final DuelConfig config = screenContent.getDuel().getConfiguration();
config.setStartLife(settingsPanel.getStartLife());
config.setHandSize(settingsPanel.getHandSize());
config.setNrOfGames(settingsPanel.getNrOfGames());
config.setCube(settingsPanel.getCube());
}
private AbstractAction getPlayGameAction() {
return new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
updateDuelConfig();
startNextGame();
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
};
}
private void doRestartDuel() {
try {
ScreenController.getFrame().restartDuel();
} catch (InvalidDeckException ex) {
ScreenController.showWarningMessage(ex.getMessage());
}
}
private String getStartDuelCaption() {
return MText.get(_S4, screenContent.getDuel().getGamesPlayed() + 1);
}
private boolean isNewDuel() {
return screenContent.getDuel().getGamesPlayed() == 0;
}
private boolean isDuelFinished() {
return screenContent.getDuel().isFinished();
}
private void showDeckEditor() {
ScreenController.showDeckEditor(this);
}
private void showTiledDeckCardImages() {
ScreenController.showDeckTiledCardsScreen(getActiveDeck());
}
private MenuButton getWinnerButton() {
String winner = screenContent.getDuel().getWinningPlayerProfile().getPlayerName();
return new MenuButton(MText.get(_S9, winner), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
// do nothing
}
});
}
public void updateDecksAfterEdit() {
screenContent.updateDecksAfterEdit();
}
public int getGamesPlayed() {
return screenContent.getDuel().getGamesPlayed();
}
private void saveDuel() {
screenContent.getDuel().save(MagicDuel.getLatestDuelFile());
}
private boolean isLegalDeckAndShowErrors(DuelPlayerConfig aPlayer) {
final String brokenRulesText =
MagicDeckConstructionRule.getRulesText(MagicDeckConstructionRule.checkDeck(aPlayer.getDeck()));
if (brokenRulesText.length() > 0) {
ScreenController.showWarningMessage(MText.get(_S14, aPlayer.getName(), brokenRulesText));
return false;
}
return true;
}
private MagicDeck getActiveDeck() {
return screenContent.getSelectedPlayer().getDeck();
}
private void doGameSetupInBackground(final MagicDuel duel) {
nextGameButton.setBusy(true);
if (worker != null && worker.isDone() == false) {
worker.cancel(true);
}
worker = new NewGameWorker(duel, this);
worker.execute();
}
void setNextGame(MagicGame aGame) {
nextGame = aGame;
nextGameButton.setBusy(nextGame == null);
}
@Override
public MagicDeck getDeck() {
return getActiveDeck();
}
@Override
public boolean setDeck(MagicDeck newDeck) {
MagicDeck oldDeck = getActiveDeck();
if (!newDeck.equals(oldDeck)) {
if (newDeck.isSameDeckFile(oldDeck)) {
// cards list has changed.
newDeck.setUnsavedStatus();
}
screenContent.setDeck(newDeck);
return true;
}
return true;
}
void setCardsTableStyle() {
screenContent.setCardsTableStyle();
}
}