package magic.ui.screen.duel.decks;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import magic.data.DeckType;
import magic.data.DuelConfig;
import magic.data.MagicIcon;
import magic.exception.InvalidDeckException;
import magic.model.DuelPlayerConfig;
import magic.model.MagicDeck;
import magic.model.MagicDeckProfile;
import magic.model.MagicDuel;
import magic.model.player.IPlayerProfileListener;
import magic.model.player.PlayerProfile;
import magic.model.player.PlayerProfiles;
import magic.translate.MText;
import magic.ui.FontsAndBorders;
import magic.ui.MagicImages;
import magic.ui.ScreenController;
import magic.ui.screen.deck.editor.DeckSideBar;
import magic.ui.screen.widget.ActionBarButton;
import magic.ui.screen.widget.MenuButton;
import magic.ui.widget.TexturedPanel;
import magic.ui.widget.cards.table.CardTablePanelB;
import magic.ui.widget.deck.stats.IPwlWorkerListener;
import magic.ui.widget.deck.stats.PwlWorker;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
class DuelDecksPanel extends TexturedPanel
implements IPlayerProfileListener, IPwlWorkerListener {
// translatable strings
private static final String _S1 = "UNSAVED";
private static final String _S7 = "Swap Decks";
private static final String _S8 = "Swap your deck with your opponent's.";
private static final String _S15 = "Generate another deck";
private static final String _S16 = "Based on the duel settings, randomly selects an existing prebuilt deck or<br>generates a random deck for the selected player.";
// change properties
static final String CP_DECK_CHANGED = "1fe41854-83e4-4a98-9c4b-46ca9f4c9550";
private final MigLayout migLayout = new MigLayout();
private final MagicDuel duel;
private final JTabbedPane tabbedPane;
private final CardTablePanelB[] cardTables;
private final DeckSideBar sidebar;
private final ActionBarButton newDeckButton;
private boolean isTabChanged = false;
private PwlWorker pwlWorker;
DuelDecksPanel(final MagicDuel duel) {
this.duel = duel;
newDeckButton = getNewDeckActionBarButton();
setBackground(FontsAndBorders.MAGSCREEN_FADE_COLOR);
sidebar = new DeckSideBar();
// create tabs for each player
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
final DuelPlayerConfig[] players = duel.getPlayers();
cardTables = new CardTablePanelB[players.length];
for (int i = 0; i < players.length; i++) {
final DuelPlayerConfig player = players[i];
cardTables[i] = new CardTablePanelB(player.getDeck(), generateTitle(player.getDeck()), true);
cardTables[i].addCardSelectionListener(sidebar.getCardViewer());
cardTables[i].showCardCount(true);
tabbedPane.addTab(null, cardTables[i]);
final DuelConfig duelConfig = duel.getConfiguration();
final PlayerProfile profile = duelConfig.getPlayerProfile(i);
tabbedPane.setTabComponentAt(i, new PlayerPanel(profile, duel));
}
tabbedPane.addChangeListener((ChangeEvent e) -> {
int newIndex = tabbedPane.getSelectedIndex();
int oldIndex = newIndex == 0 ? 1 : 0;
((PlayerPanel) tabbedPane.getTabComponentAt(newIndex)).setSelected(true);
((PlayerPanel) tabbedPane.getTabComponentAt(oldIndex)).setSelected(false);
setDeck();
isTabChanged = true;
});
tabbedPane.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
if (!isTabChanged && duel.getGamesPlayed() == 0) {
doSelectPlayer();
}
isTabChanged = false;
}
});
tabbedPane.setPreferredSize(new Dimension(800, 0));
// layout screen components.
migLayout.setLayoutConstraints("insets 0, gap 0");
setLayout(migLayout);
add(sidebar, "h 100%");
add(tabbedPane, "h 100%, w 100%");
((PlayerPanel) tabbedPane.getTabComponentAt(1)).setSelected(false);
setDeck();
}
private void doSelectPlayer() {
PlayerProfile playerProfile = getSelectedPlayer().getProfile();
if (playerProfile.isHuman()) {
ScreenController.showSelectHumanPlayerScreen(this, playerProfile);
} else {
ScreenController.showSelectAiProfileScreen(this, playerProfile);
}
}
private void setDeck() {
DuelPlayerConfig player = getSelectedPlayer();
MagicDeck deck = player.getDeck();
sidebar.setDeck(deck);
doPWLStatsQuery(deck);
sidebar.setCard(deck.get(0));
boolean isRandomDeck = player.getDeckProfile().getDeckType() == DeckType.Random;
newDeckButton.setEnabled(isRandomDeck && duel.getGamesPlayed() == 0);
}
void setDeck(MagicDeck newDeck) {
getSelectedPlayer().setDeck(newDeck);
setDeck();
updateDecksAfterEdit();
}
private String generateTitle(final MagicDeck deck) {
return deck.isUnsaved()
? MText.get(_S1) + " / " + deck.getName()
: deck.getQualifiedName();
}
MagicDuel getDuel() {
return duel;
}
DuelPlayerConfig getSelectedPlayer() {
return duel.getPlayers()[tabbedPane.getSelectedIndex()];
}
void updateDecksAfterEdit() {
for (int i = 0; i < duel.getPlayers().length; i++) {
final DuelPlayerConfig player = duel.getPlayers()[i];
final MagicDeck deck = player.getDeck();
cardTables[i].setCards(deck);
cardTables[i].setTitle(generateTitle(deck));
}
setDeck();
firePropertyChange(CP_DECK_CHANGED, true, false);
}
private void generateDeck() {
try {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
duel.buildDeck(getSelectedPlayer());
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
} catch (InvalidDeckException ex) {
ScreenController.showWarningMessage(ex.getMessage());
}
updateDecksAfterEdit();
}
private ActionBarButton getNewDeckActionBarButton() {
return new ActionBarButton(
MagicImages.getIcon(MagicIcon.RANDOM),
MText.get(_S15),
MText.get(_S16),
new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
generateDeck();
}
}
);
}
private void swapDecks() {
duel.restart();
final DuelPlayerConfig[] players = duel.getPlayers();
final MagicDeckProfile deckProfile1 = players[0].getDeckProfile();
final MagicDeckProfile deckProfile2 = players[1].getDeckProfile();
final MagicDeck deck1 = new MagicDeck(players[0].getDeck());
final MagicDeck deck2 = new MagicDeck(players[1].getDeck());
players[0].setDeckProfile(deckProfile2);
players[0].setDeck(deck2);
players[1].setDeckProfile(deckProfile1);
players[1].setDeck(deck1);
ScreenController.closeActiveScreen(false);
ScreenController.getFrame().showDuel();
}
private ActionBarButton getSwapDecksButton() {
return new ActionBarButton(
MagicImages.getIcon(MagicIcon.SWAP),
MText.get(_S7), MText.get(_S8),
new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
try {
swapDecks();
} catch (InvalidDeckException ex) {
ScreenController.showWarningMessage(ex.getMessage());
}
}
}
);
}
MenuButton[] getActionBarButtons() {
final List<MenuButton> buttons = new ArrayList<>();
buttons.add(newDeckButton);
buttons.add(getSwapDecksButton());
return buttons.toArray(new MenuButton[buttons.size()]);
}
@Override
public void PlayerProfileUpdated(PlayerProfile player) {
tabbedPane.setTabComponentAt(
tabbedPane.getSelectedIndex(),
new PlayerPanel(player, duel)
);
}
@Override
public void PlayerProfileDeleted(PlayerProfile deletedPlayer) {
PlayerProfile newPlayer = deletedPlayer.isHuman()
? PlayerProfiles.getDefaultHumanPlayer()
: PlayerProfiles.getDefaultAiPlayer();
duel.getConfiguration().setPlayerProfile(deletedPlayer.isHuman() ? 0 : 1, newPlayer);
tabbedPane.setTabComponentAt(
tabbedPane.getSelectedIndex(),
new PlayerPanel(newPlayer, duel)
);
}
@Override
public void PlayerProfileSelected(PlayerProfile player) {
saveSelectedPlayerProfile(player);
tabbedPane.setTabComponentAt(
tabbedPane.getSelectedIndex(),
new PlayerPanel(player, duel)
);
}
private void saveSelectedPlayerProfile(final PlayerProfile player) {
duel.getConfiguration().setPlayerProfile(player.isHuman() ? 0 : 1, player);
}
void refreshLayout() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
void setCardsTableStyle() {
cardTables[0].setStyle();
cardTables[1].setStyle();
}
@Override
public void setPlayedWonLost(String pwl) {
sidebar.setPlayedWonLost(pwl);
}
private void doPWLStatsQuery(MagicDeck deck) {
pwlWorker = new PwlWorker(deck);
pwlWorker.setListeners(sidebar);
pwlWorker.execute();
}
}