package magic.cardBuilder.renderers;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import magic.awt.MagicFont;
import magic.model.MagicAbility;
import magic.model.MagicColor;
import magic.model.MagicSubType;
import magic.model.MagicType;
import magic.model.IRenderableCard;
import magic.cardBuilder.ResourceManager;
import magic.cardBuilder.CardResource;
public class PTFrame {
private static final Font cardPTFont = MagicFont.BelerenBold.get().deriveFont(Font.PLAIN, 19);
private static final Font cardPTFontSmall = MagicFont.BelerenBold.get().deriveFont(Font.PLAIN, 15);//scale down when triple figures
private static final Font cardLoyaltyFont = MagicFont.BelerenBold.get().deriveFont(Font.PLAIN, 16);
//draw ptPanel - The only layering requirement besides frame. Ability text must wrap around ptpanel intrusion if any.
static void drawPTPanel(BufferedImage cardImage, IRenderableCard cardDef) {
String ptText = cardDef.getPowerToughnessText();
if (!ptText.isEmpty()) {
BufferedImage ptImage = getPTPanelImage(cardDef);
Graphics2D g2d = cardImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
if (cardDef.hasSubType(MagicSubType.Vehicle)) {
g2d.setColor(Color.WHITE);
} else {
g2d.setColor(Color.BLACK);
}
FontRenderContext frc2 = g2d.getFontRenderContext();
g2d.drawImage(ptImage, 273, 466, null);
//draw ptText
Rectangle2D box = new Rectangle(286, 469, 60, 28); //ptText dimensions (Can't use ptPanel due to shadow distorting size)
Point centre = new Point((int)box.getCenterX(), (int)box.getCenterY()); //Centre of box
TextLayout layout;
layout = new TextLayout(ptText, ptText.length() >= 6 ? cardPTFontSmall : cardPTFont, frc2);
Point textCentre = new Point((int)layout.getBounds().getWidth() / 2, (int)layout.getBounds().getHeight() / 2); //Centre of text
layout.draw(g2d, (float)centre.getX() - (float)textCentre.getX(), (float)centre.getY() + (float)textCentre.getY());
g2d.dispose();
}
}
static void drawLoyaltyPanels(BufferedImage cardImage, IRenderableCard cardDef) {
String loyaltyText = getLoyaltyText(cardDef);
Graphics2D g2d = cardImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setColor(Color.WHITE);
// Draw main Loyalty Panel
int width = 12;
int height = 34;
if (!loyaltyText.equals("0")) {
BufferedImage loyaltyImage = ResourceManager.getImage(CardResource.loyaltyPanel);
g2d.drawImage(loyaltyImage, 302, 460, null);
drawPanelText(g2d, new Rectangle(326, 462, width, height), loyaltyText, cardLoyaltyFont);
}
// Draw activation panels
String panelText;
int xPos = 32;
if (OracleText.getPlaneswalkerAbilityCount(cardDef) <= 3) {
String[] activations = getPlaneswalkerActivationCosts(cardDef);
panelText = activations[0];
if (!panelText.isEmpty()) {
//Panel 1
g2d.drawImage(getLoyaltyPanel(activations[0]), 18, 333, null);
drawPanelText(g2d, new Rectangle(xPos, 335, width, height), panelText, cardLoyaltyFont);
}
//Panel 2
g2d.drawImage(getLoyaltyPanel(activations[1]), 18, 383, null);
drawPanelText(g2d, new Rectangle(xPos, 386, width, height), activations[1], cardLoyaltyFont);
//Panel 3
if (activations.length > 2) {
g2d.drawImage(getLoyaltyPanel(activations[2]), 18, 432, null);
drawPanelText(g2d, new Rectangle(xPos, 435, width, height), activations[2], cardLoyaltyFont);
}
} else {
String[] activations = getPlaneswalkerActivationCosts(cardDef);
panelText = activations[0];
if (!panelText.isEmpty()) {
//Panel 1
g2d.drawImage(getLoyaltyPanel(activations[0]), 18, 294, null);
drawPanelText(g2d, new Rectangle(xPos, 297, width, height), panelText, cardLoyaltyFont);
}
//Panel 2
g2d.drawImage(getLoyaltyPanel(activations[1]), 18, 341, null);
drawPanelText(g2d, new Rectangle(xPos, 344, width, height), activations[1], cardLoyaltyFont);
//Panel 3
g2d.drawImage(getLoyaltyPanel(activations[2]), 18, 388, null);
drawPanelText(g2d, new Rectangle(xPos, 391, width, height), activations[2], cardLoyaltyFont);
//Panel 4
if (!activations[3].isEmpty()) {
g2d.drawImage(getLoyaltyPanel(activations[3]), 18, 435, null);
drawPanelText(g2d, new Rectangle(xPos, 438, width, height), activations[3], cardLoyaltyFont);
}
}
g2d.dispose();
}
private static void drawPanelText(Graphics2D g2d, Rectangle box, String text, Font font) {
TextLayout layout = new TextLayout(text, font, g2d.getFontRenderContext());
layout.draw(g2d, (float)box.getCenterX() - (float)layout.getBounds().getCenterX(), (float)box.getCenterY() - (float)layout.getBounds().getCenterY());
}
private static BufferedImage getLoyaltyPanel(String activation) {
if (activation.startsWith("+")) {
return ResourceManager.getImage(CardResource.loyaltyUp);
} else if (activation.startsWith("0")) {
return ResourceManager.getImage(CardResource.loyaltyEven);
} else {
return ResourceManager.getImage(CardResource.loyaltyDown);
}
}
static void drawLevellerPTPanels(BufferedImage cardImage, IRenderableCard cardDef) {
int xPosImage = 284;
int xPosText = xPosImage + 13;
int width = 60;
int height = 28;
String[] ptText = getLevellerPTText(cardDef);
BufferedImage ptImage = getPTPanelImage(cardDef);
Graphics2D g2d = cardImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setColor(Color.BLACK);
//Panel 1
g2d.drawImage(ptImage, xPosImage, 339, null);
drawPanelText(g2d, new Rectangle(xPosText, 342, width, height), ptText[0], cardPTFont);
//Panel 2
g2d.drawImage(ptImage, xPosImage, 390, null);
drawPanelText(g2d, new Rectangle(xPosText, 393, width, height), ptText[1], cardPTFont);
//Panel 3
g2d.drawImage(ptImage, xPosImage, 441, null);
drawPanelText(g2d, new Rectangle(xPosText, 444, width, height), ptText[2], cardPTFont);
g2d.dispose();
}
static void drawLevellerArrowText(BufferedImage cardImage, IRenderableCard cardDef) {
String[] levelText = getLevellerArrowText(cardDef);
Graphics2D g2d = cardImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setColor(Color.BLACK);
//Arrow 1
int xPosText = 35;
int width = 39;
int height = 39;
OracleText.drawTextToCard(cardImage, xPosText, 386, levelText[0], new Rectangle(0, 0, width, height));
//Arrow 2
OracleText.drawTextToCard(cardImage, xPosText, 437, levelText[1], new Rectangle(0, 0, width, height));
g2d.dispose();
}
private static String[] getLevellerPTText(IRenderableCard cardDef) {
String[] abilities = OracleText.getOracleAsLines(cardDef);
ArrayList<String> text = new ArrayList<>(3);
text.add(cardDef.getPowerToughnessText());
for (String ability : abilities) {
if (ability.matches("\\d+/\\d+")) {
text.add(ability);
}
}
return text.toArray(new String[3]);
}
private static String[] getLevellerArrowText(IRenderableCard cardDef) {
String[] abilities = OracleText.getOracleAsLines(cardDef);
ArrayList<String> text = new ArrayList<>(2);
for (String ability : abilities) {
if (ability.contains("LEVEL")) {
text.add(ability.replace("LEVEL ", "LEVEL\n"));
}
}
return text.toArray(new String[2]);
}
private static BufferedImage getPTPanel(MagicColor color) {
switch (color) {
case White:
return ResourceManager.getImage(CardResource.whitePTPanel);
case Blue:
return ResourceManager.getImage(CardResource.bluePTPanel);
case Black:
return ResourceManager.getImage(CardResource.blackPTPanel);
case Red:
return ResourceManager.getImage(CardResource.redPTPanel);
case Green:
return ResourceManager.getImage(CardResource.greenPTPanel);
default:
return ResourceManager.getImage(CardResource.colorlessPTPanel);
}
}
private static BufferedImage getHiddenPTPanel(MagicColor color) {
switch (color) {
case White:
return ResourceManager.getImage(CardResource.whiteHiddenPTPanel);
case Blue:
return ResourceManager.getImage(CardResource.blueHiddenPTPanel);
case Black:
return ResourceManager.getImage(CardResource.blackHiddenPTPanel);
case Red:
return ResourceManager.getImage(CardResource.redHiddenPTPanel);
case Green:
return ResourceManager.getImage(CardResource.greenHiddenPTPanel);
default:
return ResourceManager.getImage(CardResource.colorlessHiddenPTPanel);
}
}
private static BufferedImage getPTPanelImage(IRenderableCard cardDef) {
if (cardDef.hasAbility(MagicAbility.Devoid)) {
return ResourceManager.getImage(CardResource.colorlessPTPanel);
}
if (cardDef.hasSubType(MagicSubType.Vehicle)) {
return ResourceManager.getImage(CardResource.vehiclePTPanel);
}
//Hybrid cards use colorless PT panel and banners
if (cardDef.isMulti()) {
return cardDef.isHybrid() || cardDef.isToken() && cardDef.getNumColors() == 2 ? ResourceManager.getImage(CardResource.colorlessPTPanel) : ResourceManager.getImage(CardResource.multiPTPanel);
}
for (MagicColor color : MagicColor.values()) {
if (cardDef.hasColor(color)) {
return getPTPanel(color);
}
}
if (cardDef.hasType(MagicType.Artifact)) {
return ResourceManager.getImage(CardResource.artifactPTPanel);
}
return ResourceManager.getImage(CardResource.colorlessPTPanel);
}
private static BufferedImage getHiddenPTPanelImage(IRenderableCard cardDef) {
if (cardDef.hasAbility(MagicAbility.Devoid)) {
return ResourceManager.getImage(CardResource.colorlessHiddenPTPanel);
}
//Hybrid cards use colorless PT panel and banners
if (cardDef.isMulti()) {
return cardDef.isHybrid() || cardDef.isToken() && cardDef.getNumColors() == 2 ? ResourceManager.getImage(CardResource.colorlessHiddenPTPanel) : ResourceManager.getImage(CardResource.multiHiddenPTPanel);
}
for (MagicColor color : MagicColor.values()) {
if (cardDef.hasColor(color)) {
return getHiddenPTPanel(color);
}
}
if (cardDef.hasType(MagicType.Artifact)) {
return ResourceManager.getImage(CardResource.artifactHiddenPTPanel);
}
return ResourceManager.getImage(CardResource.colorlessHiddenPTPanel);
}
private static String getLoyaltyText(IRenderableCard cardDef) {
return cardDef.hasType(MagicType.Planeswalker) ? Integer.toString(cardDef.getStartingLoyalty()) : "";
}
static String[] getPlaneswalkerActivationCosts(IRenderableCard cardDef) {
String[] abilities = OracleText.getOracleAsLines(cardDef);
String[] costs = new String[abilities.length];
for (int i = 0; i < abilities.length; i++) {
String[] parts = abilities[i].split(": ", 2);
costs[i] = parts.length == 2 ? parts[0].replace("\u2212", "-") : "";
}
return costs;
}
static void drawHiddenPTPanel(BufferedImage cardImage, IRenderableCard cardDef) {
String ptText = cardDef.getPowerToughnessText();
if (!ptText.isEmpty()) {
BufferedImage ptImage = getHiddenPTPanelImage(cardDef);
Graphics2D g2d = cardImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setColor(Color.WHITE);
FontRenderContext frc2 = g2d.getFontRenderContext();
g2d.drawImage(ptImage, 273, 466, null);
//draw ptText
Rectangle2D box = new Rectangle(286, 469, 60, 28); //ptText dimensions (Can't use ptPanel due to shadow distorting size)
Point centre = new Point((int)box.getCenterX(), (int)box.getCenterY()); //Centre of box
TextLayout layout = new TextLayout(ptText, ptText.length() >= 6 ? cardPTFontSmall : cardPTFont, frc2); //Power or Toughness over 99
Point textCentre = new Point((int)layout.getBounds().getWidth() / 2, (int)layout.getBounds().getHeight() / 2); //Centre of text
layout.draw(g2d, (float)centre.getX() - (float)textCentre.getX(), (float)centre.getY() + (float)textCentre.getY());
g2d.dispose();
}
}
static void drawTransformSymbol(BufferedImage cardImage, IRenderableCard cardDef) {
Graphics2D g2d = cardImage.createGraphics();
BufferedImage typeSymbol = ResourceManager.getImage(CardResource.daySymbol);
if (cardDef.isHidden()) {
if (cardDef.hasSubType(MagicSubType.Eldrazi)){
typeSymbol = ResourceManager.getImage(CardResource.eldraziSymbol);
}
else if (cardDef.isPlaneswalker() && !cardDef.getTransformedDefinition().isPlaneswalker()){
typeSymbol = ResourceManager.getImage(CardResource.planeswalkerTypeSymbol);
} else {
typeSymbol = ResourceManager.getImage(CardResource.nightSymbol);
}
} else if (cardDef.isCreature() && cardDef.getTransformedDefinition().isPlaneswalker()) {
typeSymbol = ResourceManager.getImage(CardResource.sparkSymbol);
} else if (cardDef.getTransformedDefinition().hasSubType(MagicSubType.Eldrazi)) {
typeSymbol = ResourceManager.getImage(CardResource.moonSymbol);
}
if (cardDef.isPlaneswalker()) {
g2d.drawImage(typeSymbol, 21, 18, null);
} else {
g2d.drawImage(typeSymbol, 19, 25, null);
}
g2d.dispose();
}
}