package magic.ui.widget.duel.viewer; import magic.ui.duel.viewerinfo.PermanentViewerInfo; import java.awt.Dimension; import java.awt.Point; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import javax.swing.JPanel; import magic.data.GeneralConfig; import magic.ui.screen.duel.game.SwingGameController; import magic.ui.duel.viewerinfo.CardViewerInfo; import magic.ui.dialog.prefs.ImageSizePresets; @SuppressWarnings("serial") public class ImagePermanentsViewer extends JPanel { private static final GeneralConfig CONFIG = GeneralConfig.getInstance(); private static final int POSITION_SPACING = 60; private static final int HORIZONTAL_SPACING = 40; private static final int VERTICAL_SPACING = 30; private static final float CARD_WIDTH = (float) ImageSizePresets.getDefaultSize().width; private static final float CARD_HEIGHT = (float) ImageSizePresets.getDefaultSize().height; private static final float CARD_ASPECT_RATIO = CARD_WIDTH / CARD_HEIGHT; private final SwingGameController controller; private final boolean isTop; private List<ImagePermanentViewer> viewers; private Set<?> validChoices; public ImagePermanentsViewer(final SwingGameController controller) { this(controller, false); } public ImagePermanentsViewer(final SwingGameController controller, final boolean isTop) { this.controller = controller; this.isTop = isTop; setLayout(null); setOpaque(false); viewers=Collections.emptyList(); validChoices=Collections.emptySet(); } private static int divideIntoRows(final List<ImagePermanentViewer> cards, final int maxCardsPerRow, final int startingRow) { int numCardsThisRow = 0; int currentRow = startingRow; for (final ImagePermanentViewer card : cards) { if (numCardsThisRow + 1 > maxCardsPerRow) { // goto next row currentRow++; numCardsThisRow = 0; } numCardsThisRow++; card.setLogicalRow(currentRow); } return currentRow; } private int divideAllIntoRows(final List<ImagePermanentViewer> creatures, final List<ImagePermanentViewer> nonCreatures, final int maxCardsPerRow) { final List<ImagePermanentViewer> firstCards = (isTop) ? nonCreatures : creatures; final List<ImagePermanentViewer> secondCards = (isTop) ? creatures : nonCreatures; int currentRow = divideIntoRows(firstCards, maxCardsPerRow, 1); if (firstCards.size() > 0) { // creatures go in separate row from others currentRow++; } return divideIntoRows(secondCards, maxCardsPerRow, currentRow); } private int calculateAndSetPositions(final List<ImagePermanentViewer> creatures, final List<ImagePermanentViewer> nonCreatures) { int currentRow=1; int x=0; int y=0; int maxWidth=0; int rowHeight=0; final List<ImagePermanentViewer> aViewers = new ArrayList<ImagePermanentViewer>(); if (isTop) { aViewers.addAll(nonCreatures); aViewers.addAll(creatures); } else { aViewers.addAll(creatures); aViewers.addAll(nonCreatures); } int prevPosition=aViewers.get(0).getPosition(); for (final ImagePermanentViewer viewer : aViewers) { if (currentRow!=viewer.getLogicalRow()) { currentRow++; x=0; y+=VERTICAL_SPACING+rowHeight; } if (viewer.getPosition()!=prevPosition) { prevPosition=viewer.getPosition(); if (x>0) { x+=POSITION_SPACING; } } viewer.setLogicalPosition(new Point(x,y)); final Dimension logicalSize=viewer.getLogicalSize(); x+=logicalSize.width; maxWidth=Math.max(maxWidth,x); x+=HORIZONTAL_SPACING; rowHeight=Math.max(rowHeight,logicalSize.height); } final int maxHeight=y+rowHeight; final int width=getWidth(); final int height=getHeight(); int scaleMult=width; int scaleDiv=maxWidth; if ((maxHeight*scaleMult)/scaleDiv>height) { scaleMult=height; scaleDiv=maxHeight; } if (scaleMult>scaleDiv/2) { scaleMult=scaleDiv/2; } for (final ImagePermanentViewer viewer : aViewers) { final Point point=viewer.getLogicalPosition(); viewer.setLocation((point.x*scaleMult)/scaleDiv,(point.y*scaleMult)/scaleDiv); final Dimension size=viewer.getLogicalSize(); viewer.setSize((size.width*scaleMult)/scaleDiv,(size.height*scaleMult)/scaleDiv); } return (1000*scaleMult)/scaleDiv; } private void calculateOptimalPositions(final List<ImagePermanentViewer> creatures, final List<ImagePermanentViewer> nonCreatures) { final float screenWidth = (float) getWidth(); final float screenHeight = (float) getHeight(); final int numCards = creatures.size() + nonCreatures.size(); if (numCards > 0 && screenWidth > 0 && screenHeight > 0) { // ignore cases where drawing doesn't matter int r; int maxCardsForBestNumRow = 1; float largestScaledCardSize = 0; // approximate number of rows needed to contain all the cards for (r = (creatures.size() == 0 || nonCreatures.size() == 0) ? 1 : 2; r < numCards; r++) { float numCardsPerRow = (float) Math.ceil((float) numCards / r); // avoid lost of precision // max width and height for a card using this number of rows float scaledCardHeight = screenHeight / r; float scaledCardWidth = screenWidth / numCardsPerRow; // change width or height to maintain aspect ratio if (scaledCardWidth / scaledCardHeight > CARD_ASPECT_RATIO) { // height is limiting factor on size of scaled card scaledCardWidth = (scaledCardHeight / CARD_HEIGHT) * CARD_WIDTH; } else { // width is limiting factor on size of scaled card scaledCardHeight = (scaledCardWidth / CARD_WIDTH) * CARD_HEIGHT;; } numCardsPerRow = (float) Math.ceil(screenWidth / scaledCardWidth); // scaled -> more cards can fit per row // set best possible final float scaledCardSize = scaledCardWidth * scaledCardHeight; if (scaledCardSize > largestScaledCardSize) { largestScaledCardSize = scaledCardSize; maxCardsForBestNumRow = (int) numCardsPerRow; } } divideAllIntoRows(creatures, nonCreatures, maxCardsForBestNumRow); calculateAndSetPositions(creatures, nonCreatures); } } public void viewPermanents(final Collection<PermanentViewerInfo> permanentInfos) { final List<ImagePermanentViewer> creatures = new ArrayList<ImagePermanentViewer>(); final List<ImagePermanentViewer> nonCreatures = new ArrayList<ImagePermanentViewer>(); final List<ImagePermanentViewer> newViewers = new ArrayList<ImagePermanentViewer>(); for (final PermanentViewerInfo permanentInfo : permanentInfos) { final ImagePermanentViewer perm = new ImagePermanentViewer(this,permanentInfo); if (permanentInfo.creature) { creatures.add(perm); } else { nonCreatures.add(perm); } newViewers.add(perm); // permanentInfos has a specific order } calculateOptimalPositions(creatures, nonCreatures); removeAll(); for (final ImagePermanentViewer viewer : newViewers) { add(viewer); } viewers=newViewers; revalidate(); repaint(); } public SwingGameController getController() { return controller; } public void showValidChoices(final Set<?> aValidChoices) { this.validChoices=aValidChoices; for (final ImagePermanentViewer viewer : viewers) { viewer.repaint(); } } public boolean isValidChoice(final PermanentViewerInfo permanentInfo) { return validChoices.contains(permanentInfo.permanent); } ImagePermanentViewer getViewer(CardViewerInfo cardInfo) { for (final ImagePermanentViewer viewer : viewers) { if (viewer.permanentInfo.isEqualTo(cardInfo)) { return viewer; } for (final PermanentViewerInfo info : viewer.permanentInfo.linked) { if (info.isEqualTo(cardInfo)) { return viewer; } } for (final PermanentViewerInfo info : viewer.permanentInfo.blockers) { if (info.isEqualTo(cardInfo)) { return viewer; } } } return null; } void highlightCard(ImagePermanentViewer aViewer, long cardId) { if (aViewer != null) { aViewer.doShowHighlight(cardId); } } }