package magic.ui.widget.duel.viewer; import magic.ui.duel.viewerinfo.PlayerViewerInfo; import magic.model.MagicCardList; import magic.ui.screen.duel.game.SwingGameController; import magic.ui.widget.TabSelector; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; import java.awt.image.BufferedImage; import java.util.HashMap; import java.util.Map; import javax.swing.ImageIcon; import magic.data.MagicIcon; import magic.model.MagicPlayerZone; import magic.ui.ScreenController; import magic.translate.StringContext; import magic.translate.MText; import magic.ui.MagicImages; import magic.ui.helpers.ImageHelper; @SuppressWarnings("serial") public class PlayerZoneViewer extends JPanel implements ChangeListener { private static final Map<MagicIcon, ImageIcon> tabIcons = getTabIcons(); // translatable strings @StringContext(eg = "as in 'Other' player zone") private static final String _S1 = "Other"; private static final String _S2 = "Other : %s"; private static final String _S3 = "%s Hand"; private static final String _S4 = "%s Graveyard"; private static final String _S5 = "%s Exile"; // fired when contents of player zone is changed public static final String CP_PLAYER_ZONE = "ece91afb-3290-463e-ad03-8a24731f2aa0"; private final SwingGameController controller; private final TabSelector tabSelector; private final MagicCardList other = new MagicCardList(); private JToggleButton selectedTab = null; private final ImageCardListViewer imageCardsListViewer; private static Map<MagicIcon, ImageIcon> getTabIcons() { Map<MagicIcon, ImageIcon> icons = new HashMap<>(); icons.put(MagicIcon.HAND_ZONE, getTabIcon(MagicIcon.HAND_ZONE)); icons.put(MagicIcon.GRAVEYARD_ZONE, getTabIcon(MagicIcon.GRAVEYARD_ZONE)); icons.put(MagicIcon.EXILE_ZONE, getTabIcon(MagicIcon.EXILE_ZONE)); icons.put(MagicIcon.LIBRARY_ZONE, getTabIcon(MagicIcon.LIBRARY_ZONE)); return icons; } private static ImageIcon getTabIcon(MagicIcon icon) { ImageIcon handIcon = MagicImages.getIcon(icon); BufferedImage handImage = ImageHelper.getBufferedImage(handIcon); BufferedImage scaledImage = ImageHelper.scale(handImage, 16, 16); return new ImageIcon(scaledImage); } public PlayerZoneViewer(final SwingGameController controller) { this.controller = controller; this.imageCardsListViewer = new ImageCardListViewer(controller); setOpaque(false); setLayout(new BorderLayout(6, 0)); tabSelector = new TabSelector(this); tabSelector.addTab(tabIcons.get(MagicIcon.HAND_ZONE), getHandZoneName(getUserPlayer())); tabSelector.addTab(tabIcons.get(MagicIcon.GRAVEYARD_ZONE), getGraveyardZoneName(getUserPlayer())); tabSelector.addTab(tabIcons.get(MagicIcon.GRAVEYARD_ZONE), getGraveyardZoneName(getAiPlayer())); tabSelector.addTab(tabIcons.get(MagicIcon.EXILE_ZONE), getExileZoneName(getUserPlayer())); tabSelector.addTab(tabIcons.get(MagicIcon.EXILE_ZONE), getExileZoneName(getAiPlayer())); tabSelector.addTab(tabIcons.get(MagicIcon.LIBRARY_ZONE), MText.get(_S2, getUserPlayer().getName())); // this is used if the players are switched (ie. using the 'S' key). tabSelector.addTab(tabIcons.get(MagicIcon.LIBRARY_ZONE), getHandZoneName(getAiPlayer())); add(tabSelector, BorderLayout.WEST); add(imageCardsListViewer, BorderLayout.CENTER); } private void setSelectedTab(final int selectedTab, final boolean showFullScreen) { if (selectedTab >= 0) { tabSelector.setSelectedTab(selectedTab, showFullScreen); } } public void setSelectedTab(final int selectedTab) { setSelectedTab(selectedTab, false); } public void showCards(final MagicCardList cards) { other.clear(); other.addAll(cards); } public void update() { update(false); } private void showCards(final MagicCardList cards, final boolean showFullScreen, final String cardZoneTitle, final boolean showCardIcons) { if (showFullScreen) { showFullScreenZone(cards, cardZoneTitle); } else { imageCardsListViewer.setCardList(cards, showCardIcons); firePropertyChange(CP_PLAYER_ZONE, null, cardZoneTitle); } } private void update(final boolean showFullScreen) { switch (tabSelector.getSelectedTab()) { case 0: showCards( getUserPlayer().hand, showFullScreen, getHandZoneName(getUserPlayer(), !showFullScreen && !getUserPlayer().isAi()), true); break; case 1: showCards( getUserPlayer().graveyard, showFullScreen, getGraveyardZoneName(getUserPlayer()), false); break; case 2: showCards( getAiPlayer().graveyard, showFullScreen, getGraveyardZoneName(getAiPlayer()), false); break; case 3: showCards( getUserPlayer().exile, showFullScreen, getExileZoneName(getUserPlayer()), false); break; case 4: showCards( getAiPlayer().exile, showFullScreen, getExileZoneName(getAiPlayer()), false); break; case 5: showCards(other, showFullScreen, MText.get(_S1), false); break; case 6: showCards( getAiPlayer().hand, showFullScreen, getHandZoneName(getAiPlayer()), false); break; } repaint(); } private String getHandZoneName(final PlayerViewerInfo player, final boolean hideName) { return hideName ? "" : MText.get(_S3, player.getName()); } private String getHandZoneName(final PlayerViewerInfo player) { return getHandZoneName(player, false); } private String getGraveyardZoneName(final PlayerViewerInfo player) { return MText.get(_S4, player.getName()); } private String getExileZoneName(final PlayerViewerInfo player) { return MText.get(_S5, player.getName()); } private void showFullScreenZone(final MagicCardList aCardList, final String zoneName) { ScreenController.showCardZoneScreen(aCardList, zoneName, false); } @Override public void stateChanged(final ChangeEvent event) { final JToggleButton btn = (JToggleButton) event.getSource(); final boolean zoneChanged = selectedTab == null || !selectedTab.getActionCommand().equals(btn.getActionCommand()); final boolean showFullScreenZone = !zoneChanged && tabSelector.isUserClick(); if (zoneChanged || showFullScreenZone) { update(showFullScreenZone); if (zoneChanged) { notifyPlayerZoneListeners(Integer.parseInt(btn.getActionCommand())); } } this.selectedTab = btn; } public void setPlayerZone(final PlayerViewerInfo playerInfo, final MagicPlayerZone zone) { final int tabIndex = getZoneButtonIndex(playerInfo, zone); final boolean showFullScreen = tabSelector.getSelectedTab() == tabIndex; setSelectedTab(tabIndex, showFullScreen); } private void notifyPlayerZoneListeners(final int newPlayerZoneIndex) { if (newPlayerZoneIndex == 0) { controller.notifyPlayerZoneChanged(getUserPlayer(), MagicPlayerZone.HAND); } else if (newPlayerZoneIndex == 1) { controller.notifyPlayerZoneChanged(getUserPlayer(), MagicPlayerZone.GRAVEYARD); } else if (newPlayerZoneIndex == 2) { controller.notifyPlayerZoneChanged(getAiPlayer(), MagicPlayerZone.GRAVEYARD); } else if (newPlayerZoneIndex == 3) { controller.notifyPlayerZoneChanged(getUserPlayer(), MagicPlayerZone.EXILE); } else if (newPlayerZoneIndex == 4) { controller.notifyPlayerZoneChanged(getAiPlayer(), MagicPlayerZone.EXILE); } else if (newPlayerZoneIndex == 5) { controller.notifyPlayerZoneChanged(getUserPlayer(), MagicPlayerZone.LIBRARY); } else if (newPlayerZoneIndex == 6) { controller.notifyPlayerZoneChanged(getAiPlayer(), MagicPlayerZone.HAND); } } /** * Returns the latest instance of PlayerViewInfo. * <p> * <b>Do not retain a reference toPlayerViewerInfo since a new instance * is created whenever ViewerInfo is updated.</b> */ private PlayerViewerInfo getUserPlayer() { return controller.getViewerInfo().getPlayerInfo(false); } /** * Returns the latest instance of PlayerViewInfo. * <p> * <b>Do not retain a reference toPlayerViewerInfo since a new instance * is created whenever ViewerInfo is updated.</b> */ private PlayerViewerInfo getAiPlayer() { return controller.getViewerInfo().getPlayerInfo(true); } private int getZoneButtonIndex(PlayerViewerInfo playerInfo, MagicPlayerZone zone) { if (playerInfo.player == getUserPlayer().player) { switch (zone) { case HAND: return 0; case GRAVEYARD: return 1; case EXILE: return 3; case LIBRARY: return 5; default: throw new RuntimeException("No zone viewer available!"); } } else { switch (zone) { case HAND: return 6; case GRAVEYARD: return 2; case EXILE: return 4; default: throw new RuntimeException("No zone viewer available!"); } } } public ImageCardListViewer getImageCardsListViewer() { return imageCardsListViewer; } public void switchPlayerZone() { switch (Integer.parseInt(selectedTab.getActionCommand())) { case 0: // P0 hand setSelectedTab(6); break; case 1: // P0 graveyard setSelectedTab(2); break; case 2: // P1 graveyard setSelectedTab(1); break; case 3: // P0 exile setSelectedTab(4); break; case 4: // P1 exile setSelectedTab(3); break; case 6: // P1 hand setSelectedTab(0); break; default: // do ntohing } } }