package magic.ui.widget.cards.table;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JViewport;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import magic.model.MagicCardDefinition;
import magic.model.MagicDeck;
import magic.ui.screen.decks.ICardsTableListener;
@SuppressWarnings("serial")
public class DeckViewTablePanel extends CardsTablePanel {
private final List<ICardsTableListener> listeners = new ArrayList<>();
private boolean isSelectionAdjusting = false;
private boolean ignoreListSelectionListener;
public DeckViewTablePanel(List<MagicCardDefinition> defs) {
super(defs);
tableModel.showCardCount(true);
setCardSelectedListener();
setMouseClickListener();
}
public void setListeners(ICardsTableListener... listeners) {
this.listeners.clear();
this.listeners.addAll(Arrays.asList(listeners));
}
private void setCardSelectedListener() {
table.getSelectionModel().addListSelectionListener((ev) -> {
isSelectionAdjusting = ev.getValueIsAdjusting();
if (!ignoreListSelectionListener && !isSelectionAdjusting) {
ListSelectionModel lsm = table.getSelectionModel();
// If cell selection is enabled, both row and column change events are fired
if (ev.getSource() == lsm && table.getRowSelectionAllowed()) {
notifyCardSelected(tableModel.getCardDef(lsm.getLeadSelectionIndex()));
}
}
});
}
private void setMouseClickListener() {
table.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (!isSelectionAdjusting) {
int mouseRow = table.rowAtPoint(e.getPoint());
MagicCardDefinition card = tableModel.getCardDef(mouseRow);
card = card == null ? MagicCardDefinition.UNKNOWN : card;
if (SwingUtilities.isLeftMouseButton(e)) {
notifyOnLeftClick(card);
} else if (SwingUtilities.isRightMouseButton(e)) {
notifyOnRightClick(card);
}
}
}
});
}
@Override
protected MouseAdapter getRowMouseOverListener() {
return new MouseAdapter() {
@Override
public void mouseMoved(final MouseEvent e) {
final Point p = e.getPoint();
final int row = table.rowAtPoint(p);
final MagicCardDefinition card = tableModel.getCardDef(row);
notifyCardSelected(card);
}
};
}
private void setCards(final List<MagicCardDefinition> defs) {
ignoreListSelectionListener = true;
tableModel.setCards(defs);
table.tableChanged(new TableModelEvent(tableModel));
table.repaint();
ignoreListSelectionListener = false;
}
public void setCards(MagicDeck deck, MagicCardDefinition selectCard) {
setCards(deck);
setSelectedCard(selectCard);
}
private void notifyCardSelected(MagicCardDefinition card) {
for (ICardsTableListener listener : listeners) {
SwingUtilities.invokeLater(() -> {
listener.onCardSelected(card == null ? MagicCardDefinition.UNKNOWN : card);
});
}
}
private void notifyOnLeftClick(MagicCardDefinition card) {
for (ICardsTableListener listener : listeners) {
SwingUtilities.invokeLater(() -> {
listener.onLeftClick(card);
});
}
}
private void notifyOnRightClick(MagicCardDefinition card) {
for (ICardsTableListener listener : listeners) {
SwingUtilities.invokeLater(() -> {
listener.onRightClick(card);
});
}
}
private void scrollRowToViewportCenter(int row) {
JViewport viewport = (JViewport) table.getParent();
Rectangle viewRect = viewport.getViewRect();
Rectangle rect = table.getCellRect(row, 0, true);
int y = rect.y < viewRect.y || rect.y > (viewRect.y + viewRect.height)
? rect.y - (viewRect.height / 2) + rect.height
: viewRect.y;
viewport.setViewPosition(new Point(viewRect.x, y));
}
public void setSelectedCard(MagicCardDefinition card) {
int index = card != null ? tableModel.findCardIndex(card) : -1;
if (index != -1) {
table.getSelectionModel().addSelectionInterval(index, index);
scrollRowToViewportCenter(index);
} else if (tableModel.getRowCount() > 0) {
// no card specified, select first row.
table.getSelectionModel().addSelectionInterval(0, 0);
}
}
public MagicCardDefinition getSelectedCard() {
ListSelectionModel lsm = table.getSelectionModel();
return tableModel.getCardDef(lsm.getLeadSelectionIndex());
}
}