package magic.ui.screen.deck.editor; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import javax.swing.JPanel; import javax.swing.JTable; import magic.model.MagicCardDefinition; import magic.ui.MagicSound; import magic.ui.screen.widget.ActionBarButton; import magic.ui.widget.cards.table.BasicDeckTablePanel; import magic.ui.widget.cards.table.CardTablePanelA; import net.miginfocom.swing.MigLayout; @SuppressWarnings("serial") class CardRecallPanel extends JPanel implements IDeckEditorView, FocusListener { // fired when card selection changes public static final String CP_CARD_SELECTED = "5d3dc52f-b1b3-419e-a4ab-375c3c85d29c"; private final DeckEditorController controller = DeckEditorController.instance; private final CardQuantityActionPanel quantityPanel; private final BasicDeckTablePanel deckPanel; private final CardTablePanelA recallTablePanel; private final MigLayout miglayout = new MigLayout(); private final List<MagicCardDefinition> recallCards; private MagicCardDefinition selectedCard = MagicCardDefinition.UNKNOWN; private final IDeckEditorListener listener; CardRecallPanel(final IDeckEditorListener aListener, final CardQuantityActionPanel aPanel) { this.listener = aListener; this.quantityPanel = aPanel; deckPanel = new BasicDeckTablePanel(); recallCards = new ArrayList<>(); recallTablePanel = new CardTablePanelA(recallCards); recallTablePanel.setDeckEditorSelectionMode(); setPropertyChangeListeners(); setLookAndFeel(); refreshLayout(); } private MagicCardDefinition getRecallSelectedCard() { return recallTablePanel.getSelectedCards().size() > 0 ? recallTablePanel.getSelectedCards().get(0) : null; } private void clearRecallSelection() { recallTablePanel.clearSelection(); } private void doDeckPanelSelectionAction() { if (deckPanel.getSelectedCard() != null) { selectedCard = deckPanel.getSelectedCard(); if (selectedCard != getRecallSelectedCard()) { clearRecallSelection(); } listener.cardSelected(getSelectedCard()); } } private void doRecallPanelSelectionAction() { if (getRecallSelectedCard() != null) { selectedCard = getRecallSelectedCard(); if (controller.getDeck().contains(selectedCard) == false) { deckPanel.clearSelection(); } else { deckPanel.setSelectedCard(selectedCard); } listener.cardSelected(getSelectedCard()); } } private void setPropertyChangeListeners() { deckPanel.addPropertyChangeListener( BasicDeckTablePanel.CP_CARD_SELECTED, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { doDeckPanelSelectionAction(); } }); recallTablePanel.addPropertyChangeListener(CardTablePanelA.CP_CARD_SELECTED, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { doRecallPanelSelectionAction(); } }); recallTablePanel.addPropertyChangeListener(CardTablePanelA.CP_CARD_LCLICKED, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { addSelectedCardToDeck(); } }); recallTablePanel.addPropertyChangeListener(CardTablePanelA.CP_CARD_RCLICKED, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { removeSelectedCardFromDeck(); } }); } private void setLookAndFeel() { setOpaque(false); setLayout(miglayout); } private void refreshLayout() { removeAll(); miglayout.setLayoutConstraints("insets 0, gap 0"); add(deckPanel, "w 220!, h 100%"); add(recallTablePanel, "w 100%, h 100%"); revalidate(); } @Override public MagicCardDefinition getSelectedCard() { return selectedCard; } private void addSelectedCardToDeck() { final MagicCardDefinition card = getSelectedCard(); if (card == null || card == MagicCardDefinition.UNKNOWN) { return; } for (int i = 0; i < quantityPanel.getQuantity(); i++) { controller.getDeck().add(card); } listener.deckUpdated(controller.getDeck()); // Ensures the count overlay is updated on card image. listener.cardSelected(card); deckPanel.getTableModel().setCards(controller.getDeck()); deckPanel.getTable().repaint(); deckPanel.setSelectedCard(card); MagicSound.ADD_CARD.play(); } private void removeSelectedCardFromDeck() { final MagicCardDefinition card = getSelectedCard(); if (card == null || card == MagicCardDefinition.UNKNOWN) { return; } if (controller.getDeck().contains(card) == false) { MagicSound.BEEP.play(); return; } for (int i = 0; i < quantityPanel.getQuantity(); i++) { controller.getDeck().remove(card); } listener.deckUpdated(controller.getDeck()); // Ensures the count overlay is updated on card image. listener.cardSelected(card); deckPanel.getTableModel().setCards(controller.getDeck()); deckPanel.getTable().repaint(); if (card != deckPanel.getSelectedCard() && getRecallSelectedCard() != null) { deckPanel.clearSelection(); } if (getRecallSelectedCard() == null) { doDeckPanelSelectionAction(); } MagicSound.REMOVE_CARD.play(); } @Override public boolean requestFocusInWindow() { if (recallTablePanel.getSelectedCards().isEmpty()) { recallTablePanel.selectFirstRow(); } return super.requestFocusInWindow(); } void addCardToRecall(final MagicCardDefinition card) { if (!recallCards.contains(card)) { recallCards.add(card); recallTablePanel.setCards(recallCards); } } void setDeckTable(final JTable aDeckTable) { deckPanel.setDeckTable(aDeckTable); deckPanel.getTable().removeFocusListener(this); deckPanel.getTable().addFocusListener(this); } @Override public void doPlusButtonAction() { addSelectedCardToDeck(); } @Override public void doMinusButtonAction() { removeSelectedCardFromDeck(); } @Override public List<ActionBarButton> getActionButtons() { return new ArrayList<>(); } private void doFocusLostAction(FocusEvent e) { if (e.getOppositeComponent() == deckPanel.getTable()) { clearRecallSelection(); } } @Override public void focusGained(FocusEvent e) { // do nothing. } @Override public void focusLost(FocusEvent e) { doFocusLostAction(e); } @Override public void notifyShowing() { // not applicable. } }