package ch.sahits.game.graphic.image;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import ch.sahits.game.graphic.image.ImagesLoader;
/**
* Utility class used by UI delegates for all kinds of buttons.
*/
public class OpenPatricianSlabPainter extends OpenPatricianPainter
{
private ImagesLoader loader = new ImagesLoader();
private static LinkedHashMap<Float, String> slabMap = new LinkedHashMap<Float, String>();
private static LinkedHashMap<Float, String> slabExtMap = new LinkedHashMap<Float, String>();
private static LinkedHashMap<Float, String> slabLightMap = new LinkedHashMap<Float, String>();
static {
slabMap.put(1.3f, "StoneSlab_1_3.png");
slabMap.put(2.2f, "StoneSlab_2_2.png");
slabMap.put(3.5f, "StoneSlab_3_5.png");
slabMap.put(4.1f, "StoneSlab_4_1.png");
slabMap.put(4.7f, "StoneSlab_4_7.png");
slabMap.put(5.8f, "StoneSlab_5_8.png");
slabLightMap.put(1.3f, "StoneLightSlab_1_3.png");
slabLightMap.put(2.2f, "StoneLightSlab_2_2.png");
slabLightMap.put(3.5f, "StoneLightSlab_3_5.png");
slabLightMap.put(4.1f, "StoneLightSlab_4_1.png");
slabLightMap.put(4.7f, "StoneLightSlab_4_7.png");
slabLightMap.put(5.8f, "StoneLightSlab_5_8.png");
slabExtMap.put(1.1f, "StoneSlabExt_1_1.png");
slabExtMap.put(2.2f, "StoneSlabExt_2_2.png");
slabExtMap.put(2.7f, "StoneSlabExt_2_7.png");
slabExtMap.put(3.0f, "StoneSlabExt_3_0.png");
slabExtMap.put(3.1f, "StoneSlabExt_3_1.png");
slabExtMap.put(3.6f, "StoneSlabExt_3_6.png");
}
// /**
// * Paint a button.
// *
// * @param graphics The graphics object to be used for painting.
// * @param button The button to paint
// */
// public static void paintButton (Graphics graphics, AbstractButton button)
// {
// Color oldColor = graphics.getColor();
//
// ButtonModel model = button.getModel();
//
// button.setBorderPainted(false);
//
// boolean isRollover = ((Boolean) button.getClientProperty(OpenPatricianLaFConstants.ROLLOVER_CLENT_PROPERTY_KEY)).booleanValue();
//
// if (button.isEnabled()
// && (isRollover
// || model.isArmed() && model.isPressed()
// || button.hasFocus()
// || button.isSelected()))
// {
// boolean paintShadow = model.isArmed() && model.isPressed() || button.isSelected() && !isRollover;
// drawSlab(graphics, button,paintShadow);
//
// } else if (button.isEnabled()
// && !isRollover){
// boolean paintShadow = model.isArmed() && model.isPressed() || button.isSelected() && !isRollover;
// drawSlab(graphics, button,paintShadow);
// }
//
// graphics.setColor(oldColor);
// }
/**
* Paint a button.
*
* @param graphics The graphics object to be used for painting.
* @param button The button to paint
*/
public void paintButton (Graphics graphics,Rectangle bounds)
{
Color oldColor = graphics.getColor();
drawSlab(graphics, bounds);
graphics.setColor(oldColor);
}
/**
* Paint a button.
*
* @param graphics The graphics object to be used for painting.
* @param button The button to paint
*/
public BufferedImage createButton(Graphics graphics, String text, Rectangle bounds)
{
Color oldColor = graphics.getColor();
BufferedImage img = createSlab(graphics, text,bounds);
graphics.setColor(oldColor);
return img;
}
/**
* Create an image of a scaled plank
* @param width destination width
* @param height destination height
* @return
*/
public BufferedImage createScaledPlank(int width, int height){
return createScaledSlab("InputPlank.jpg", width, height);
}
/**
* Draw a borderless stone slab
* @param graphics Graphics to draw on
* @param button that is represented by the slab
* @param paintShadow indicates if the surrounding mortar has a different color
*/
private void drawSlab(Graphics graphics, Rectangle bounds) {
String fileName = getFileName((int)Math.rint(bounds.getWidth()),(int)Math.rint(bounds.getHeight()));
drawSlab(graphics, bounds, fileName);
}
/**
* Draw a borderless stone slab
* @param graphics Graphics to draw on
* @param button that is represented by the slab
* @param paintShadow indicates if the surrounding mortar has a different color
*/
private BufferedImage createSlab(Graphics graphics,String text, Rectangle bounds) {
String fileName = getFileName((int)Math.rint(bounds.getWidth()),(int)Math.rint(bounds.getHeight()));
return createSlab(graphics, text, fileName,0,bounds);
}
/**
* Draw a borderless stone slab. The name of the image is passed
* @param graphics Graphics to draw on
* @param comp that is represented by the slab
* @param paintShadow indicates if the surrounding mortar has a different color
* @param fileName file name of the image to be drawn
*/
private void drawSlab(Graphics graphics,Rectangle bounds, String fileName) {
drawSlab(graphics, bounds, fileName, 0);
}
/**
* Draw a borderless stone slab. The name of the image is passed
* @param graphics Graphics to draw on
* @param comp that is represented by the slab
* @param paintShadow indicates if the surrounding mortar has a different color
* @param fileName file name of the image to be drawn
*/
private void drawSlab(Graphics graphics, Rectangle bounds, String fileName, int reduce) {
ImagesLoader loader = new ImagesLoader();
BufferedImage img = loader.loadImage(fileName);
final int posX=bounds.x;
final int posY=bounds.y;
final int destWidth= (int)Math.rint(bounds.getWidth())-reduce;
final int destHight=(int)Math.rint(bounds.getHeight());
float xScale = (float) destWidth / img.getWidth();
float yScale = (float) destHight / img.getHeight();
BufferedImage bdest =
new BufferedImage(destWidth, destHight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bdest.createGraphics();
AffineTransform at =
AffineTransform.getScaleInstance(xScale,yScale);
g.drawRenderedImage(img,at);
graphics.drawImage(bdest, posX, posY, null);
}
/**
* Draw a borderless stone slab. The name of the image is passed
* @param graphics Graphics to draw on
* @param comp that is represented by the slab
* @param paintShadow indicates if the surrounding mortar has a different color
* @param fileName file name of the image to be drawn
*/
private BufferedImage createSlab(Graphics graphics, String text,
String fileName, int reduce, Rectangle bounds) {
ImagesLoader loader = new ImagesLoader();
BufferedImage img = loader.loadImage(fileName);
final int destWidth= (int)Math.rint(bounds.getWidth())-reduce;
final int destHight=(int)Math.rint(bounds.getHeight());
float xScale = (float) destWidth / img.getWidth();
float yScale = (float) destHight / img.getHeight();
BufferedImage bdest =
new BufferedImage(destWidth, destHight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bdest.createGraphics();
AffineTransform at =
AffineTransform.getScaleInstance(xScale,yScale);
g.drawRenderedImage(img,at);
return img;
}
/**
* Compute the filename based on the stretching factor
* @param width of the button
* @param height of the button
* @return
*/
private static String getFileName(int width, int height) {
float f = width*1f/height;
String minDistFileName="StoneSlabBorderless.png";
return getFileName(f, minDistFileName,slabMap);
}
/**
* Retrieve the file name that matches best the proportions to be displayed
* @param f result of the division of the displayable width through the displayable height
* @param defaultFileName default file name to be used
* @param fNames Hashmap to be used with the file names
* @return file name
*/
private static String getFileName(float f, String defaultFileName, HashMap<Float, String> fNames) {
float minDist = Float.MAX_VALUE;
int index=0;
for (Map.Entry<Float, String> entry : fNames.entrySet()) {
float diff = Math.abs(entry.getKey()-f);
if (diff<minDist){
minDist=diff;
defaultFileName=entry.getValue();
}
index++;
}
return defaultFileName;
}
/**
* Compute the filename based on the stretching factor
* @param width of the button
* @param height of the button
* @return
*/
private String getFileNameExt(int width, int height, int capWidth) {
float f = (capWidth-width)*1f/height;
return getFileName(f, "StoneSlabExt.png",slabExtMap);
}
/**
* create the check box image
* @return
*/
public BufferedImage createCheckBoxImage(){
return loader.loadImage("checkboxbg.png");
}
/**
* create the check box image
* @return
*/
public BufferedImage createRadioButtonImage(){
return loader.loadImage("radioboxbg.png");
}
/**
* Create an image of the specified size and draw a String on it.
* This method makes sure that the whole string is drawn over a stone slab
* instead of on the brickwork.
* @param s String to be printed
* @param f Font to be used for the drawing
* @param imgWidth Width of the image that is augmented
* @param compWidth width of the component
* @param compHeigh height of the component
* @return
*/
public BufferedImage createTextOnSlab4ToggleButton(String s, Font f, int imgWidth, int compWidth,int compHeigh){
BufferedImage img = new BufferedImage(compWidth, compHeigh, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
Color oldcolor = g.getColor();
g.setColor(Color.BLACK);
try {
GlyphVector gv = createGlyphVector(g, s,f.getSize());
Rectangle2D box =gv.getVisualBounds();
int width = (int) Math.rint(box.getWidth());
final int remainWidth = 28; // width that is left from the background
final int destHight = 27;
final int xStart = imgWidth;
final int yStart = 0;
int destWidth = width-remainWidth;
String fileName = getFileNameExt(destWidth,destHight,remainWidth);
// Scale the image
BufferedImage scaledSlab = createScaledSlab(fileName,destWidth,destHight);
g.drawImage(scaledSlab, xStart, yStart, null);
// Draw the string
int posX = destWidth/2+(xStart-remainWidth);
drawString(g, s, f.getSize(), posX, destHight/2);
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
g.setColor(oldcolor);
return img;
}
/**
* Create a scaled image of the specified name at the specified size
* @param fileName name of the file
* @param destWidth width of the destination image
* @param destHight height of the destination image
* @return
*/
private BufferedImage createScaledSlab(String fileName, int destWidth,
int destHight) {
if (destWidth<=0){
throw new IllegalArgumentException("The final width must be larger than 0");
}
if (destHight<=0){
throw new IllegalArgumentException("The final height must be larger than 0");
}
BufferedImage img = loader.loadImage(fileName);
if (img==null) return null; // can happen when quitting
float xScale = (float) destWidth / img.getWidth();
float yScale = (float) destHight / img.getHeight();
AffineTransform at = new AffineTransform();
at.scale(xScale, yScale);
// instantiate and apply affine transformation filter
BufferedImageOp bio = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
return bio.filter(img, null);
}
}