package net.sf.freecol.client.gui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
import net.sf.freecol.client.gui.i18n.Messages;
import net.sf.freecol.client.gui.panel.InfoPanel;
import net.sf.freecol.common.model.Player;
import net.sf.freecol.common.model.StringTemplate;
/**
* Custom component to paint turn progress.
* <p>
* Currently the component darken out background using alpha channel and
* then paints the player's icon and wait message.
*/
public class GrayLayer extends Component {
/** Color for graying out background component */
private static final Color MASK_COLOR = new Color(0f, 0f, 0f, .6f);
/** Default font size for message text */
private static final int DEFAULT_FONT_SIZE = 18;
/** Font size decrement for message text to reduce length */
private static final int FONT_SIZE_DECREMENT = 2;
/**
* Maximum text width to show. This is additional constraint to the
* component's bounds
*/
private static final int MAX_TEXT_WIDTH = 640;
/** Image library for icon lookup */
private ImageLibrary imageLibrary;
/** Player object or <code>null</code> */
private Player player;
public GrayLayer(ImageLibrary imageLibrary) {
this.imageLibrary = imageLibrary;
}
/**
* Executes painting. The method shadows the background image, and
* paints the message with icon (if available) and text.
* @param g a <code>Graphics</code> value
*/
@Override
public void paint(Graphics g) {
Rectangle clipArea = g.getClipBounds();
if (clipArea == null) {
clipArea = getBounds();
clipArea.x = clipArea.y = 0;
}
if (clipArea.isEmpty()) {
// we are done - the picture is OK
return;
}
g.setColor(MASK_COLOR);
g.fillRect(clipArea.x, clipArea.y, clipArea.width, clipArea.height);
if (player == null) {
// we are done, no player information
return;
}
ImageIcon coatOfArmsIcon = imageLibrary
.getCoatOfArmsImageIcon(player.getNation());
Rectangle iconBounds = new Rectangle();
if (coatOfArmsIcon != null) {
iconBounds.width = coatOfArmsIcon.getIconWidth();
iconBounds.height = coatOfArmsIcon.getIconHeight();
}
Font nameFont = getFont();
FontMetrics nameFontMetrics = getFontMetrics(nameFont);
StringTemplate t = StringTemplate.template("waitingFor")
.addStringTemplate("%nation%", player.getNationName());
String message = Messages.message(t);
Rectangle textBounds;
int fontSize = DEFAULT_FONT_SIZE;
int maxWidth = Math.min(MAX_TEXT_WIDTH, getSize().width);
do {
nameFont = nameFont.deriveFont(Font.BOLD, fontSize);
nameFontMetrics = getFontMetrics(nameFont);
textBounds = nameFontMetrics.getStringBounds(message, g)
.getBounds();
fontSize -= FONT_SIZE_DECREMENT;
} while (textBounds.width > maxWidth);
Dimension size = getSize();
textBounds.x = (size.width - textBounds.width) / 2;
textBounds.y = size.height - InfoPanel.PANEL_HEIGHT - 2 * textBounds.height;
iconBounds.x = (size.width - iconBounds.width) / 2;
iconBounds.y = textBounds.y + 3 * textBounds.height / 2;
if (textBounds.intersects(clipArea)) {
// show message
g.setFont(nameFont);
g.setColor(imageLibrary.getColor(player));
g.drawString(message, textBounds.x, textBounds.y
+ textBounds.height);
}
if (coatOfArmsIcon != null && iconBounds.intersects(clipArea)) {
// show icon
coatOfArmsIcon.paintIcon(this, g, iconBounds.x, iconBounds.y);
}
}
/**
* Set the player for which we paint. If the player is already set, then
* nothing happens, otherwise a repaint event is sent.
*
* @param player
* Player for status information
*
* @see #paint(Graphics)
*/
public void setPlayer(Player player) {
if (this.player == player) {
return;
}
this.player = player;
repaint();
}
}