package mapmaker;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.text.*;
import util.*;
import mapmaker.mapcmd.*;
public class MapImagePainter {
public static final int
LEGEND_RIGHT = CollumnPrinter.STYLE_MATCH_HEIGHT,
LEGEND_BELOW = CollumnPrinter.STYLE_MATCH_WIDTH;
protected AreaMap map;
protected MapGraphics mg;
protected CollumnPrinter legendPrinter;
/** stores all room names in the order as they will appear
* in the legend
*/
protected Vector legend;
protected int layoutStyle;
protected static Color
backgroundColor = Color.lightGray,
mapColor = Color.gray,
legendColor = Color.black,
legendNrColor = Color.black;
public MapImagePainter(AreaMap mapData) {
// init map
map = new CMap(0, 0, new MyObservable());
map.deepCopyFrom(mapData);
// init mg
mg = new MapGraphics(map, null);
mg.setPaintSize(3);
// init cp
legendPrinter = new CollumnPrinter(200, 12);
} // MapImagePainter
/** returns a legend text for the map, based on the contents of
* the legend variable
*/
protected Text createLegendText() {
Text legendText = new Text();
for (int i = 0; i < legend.size(); i++)
legendText.append(i + " " + legend.elementAt(i));
return legendText;
} // createLegendText
protected void createLegend() {
legend = new Vector();
Room[] rooms = map.getRooms();
for (int i = 0; i < rooms.length; i++)
if (rooms[i] instanceof DescObj) {
String roomName =
MapDescParser.get().getName(((DescObj)rooms[i]).getDesc());
if (roomName.length() > 0 && legend.indexOf(roomName) == -1)
legend.add(roomName);
}
// sort the legend alphabetically
Collections.sort((java.util.List)legend,
(Comparator)Collator.getInstance());
} // createLegend
/** returns the size (in pixels) the map image takes
*/
protected Dimension getSize() {
Dimension mapSize = mg.getSize();
Dimension legendSize = legendPrinter.getSize();
Dimension totalSize = new Dimension(0, 0);
if (layoutStyle == LEGEND_BELOW) {
totalSize.width = Math.max(mapSize.width, legendSize.width);
totalSize.height = mapSize.height + legendSize.height;
}
else {
totalSize.width = mapSize.width + legendSize.width;
totalSize.height = Math.max(mapSize.height, legendSize.height);
}
return totalSize;
} // getSize
public void layout(int style) {
// store style
layoutStyle = style;
// prepare map
map.execute(new CmdSetSize(new Dimension(0, 0)));
MapUtil.unmarkRooms(map);
map.execute(new CmdUnselectRoom());
// create and layout legend
createLegend();
legendPrinter.setText(createLegendText());
int size;
if (style == CollumnPrinter.STYLE_MATCH_WIDTH)
size = mg.getSize().width;
else
size = mg.getSize().height;
legendPrinter.layout(style, size);
} // layout
/** paints the map into an image and returns it;
* if nothing there to be painted (no rooms), returns null
*/
public BufferedImage paintMapImage() {
Dimension dim = getSize();
// ensure that map dimension isn't 0
if (dim.width == 0 || dim.height == 0)
return null;
BufferedImage image = new BufferedImage(dim.width, dim.height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.setColor(backgroundColor);
g.fillRect(0, 0, dim.width, dim.height);
// paint map
g.setColor(mapColor);
mg.paint(g);
// paint legend
// move relative graphics position according to style before painting
int dx = 0;
int dy = 0;
if (layoutStyle == LEGEND_BELOW)
dy = mg.getSize().height;
else
dx = mg.getSize().width;
g.translate(dx, dy);
g.setColor(legendColor);
legendPrinter.print(g);
g.translate(-dx, -dy);
// paint the numbers on the map
g.setColor(legendNrColor);
paintLegendNumbers(g);
return image;
} // paintMapImage
/** paints the numbers that are mapped to the room names on the map
*/
protected void paintLegendNumbers(Graphics g) {
Font orgFont = g.getFont();
g.setFont(new Font("SansSerif", Font.BOLD, 9));
Room[] rooms = map.getRooms();
for (int i = 0; i < rooms.length; i++) {
Room room = rooms[i];
if (room instanceof DescObj) {
String roomName =
MapDescParser.get().getName(((DescObj)room).getDesc());
if (roomName.length() > 0) {
int legendNr = legend.indexOf(roomName);
if (legendNr == -1)
throw new IllegalStateException("room name not in legend");
Point paintPos = mg.roomPaintPos(room);
paintPos.y += (mg.sizePerRoom() + 1) / 2;
g.drawString(legendNr + "", paintPos.x + 3, paintPos.y + 3);
}
}
}
g.setFont(orgFont);
} // PaintLegendNumbers
} // MapImagePainter