/* * $Id$ * * Copyright (c) 2005 by Rodney Kinney, Brent Easton * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License (LGPL) as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, copies are available * at http://www.opensource.org. */ package VASSAL.build.module.gamepieceimage; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; import VASSAL.build.AbstractConfigurable; import VASSAL.build.AutoConfigurable; import VASSAL.build.Buildable; import VASSAL.build.GameModule; import VASSAL.build.module.documentation.HelpFile; import VASSAL.configure.Configurer; import VASSAL.configure.ConfigurerFactory; import VASSAL.configure.VisibilityCondition; import VASSAL.tools.ArchiveWriter; import VASSAL.tools.ErrorDialog; import VASSAL.tools.UniqueIdManager; import VASSAL.tools.imageop.Op; import VASSAL.tools.imageop.SourceOp; /** * */ public class GamePieceImage extends AbstractConfigurable implements Visualizable, Cloneable, UniqueIdManager.Identifyable { protected static final String NAME = "name"; //$NON-NLS-1$ protected static final String PROPS = "props"; //$NON-NLS-1$ public static final String PART_SIZE = "Size"; //$NON-NLS-1$ public static final String PART_SYMBOL1 = "Symbol1"; //$NON-NLS-1$ public static final String PART_SYMBOL2 = "Symbol2"; //$NON-NLS-1$ public static final String BG_COLOR = "bgColor"; //$NON-NLS-1$ public static final String BORDER_COLOR = "borderColor"; //$NON-NLS-1$ protected List<ItemInstance> instances = new ArrayList<ItemInstance>(); protected InstanceConfigurer defnConfig = null; protected GamePieceLayout layout; protected ColorSwatch bgColor = ColorSwatch.getWhite(); protected ColorSwatch borderColor = ColorSwatch.getBlack(); protected String id; protected static UniqueIdManager idMgr = new UniqueIdManager("GamePieceImage"); //$NON-NLS-1$ protected String nameInUse; protected Image visImage = null; protected SourceOp srcOp; public GamePieceImage() { super(); setConfigureName(""); //$NON-NLS-1$ } public GamePieceImage(String s) { instances = InstanceConfigurer.StringToProperties(s, this); } public GamePieceImage(GamePieceLayout l) { this(); setConfigureName(l.getConfigureName()); layout = l; } public GamePieceImage(GamePieceImage defn) { this(); this.setConfigureName(defn.getConfigureName()); this.layout = defn.getLayout(); this.bgColor = defn.getBgColor(); this.borderColor = defn.getBorderColor(); this.instances.addAll(defn.getInstances()); } /* * The Generic trait needs a deep copy of the Image Definition */ public Object clone() { return new GamePieceImage(this); } public List<ItemInstance> getInstances() { return instances; } public String[] getAttributeDescriptions() { return new String[] { "Name: ", "Background Color: ", "Border Color: ", "" //$NON-NLS-1$ }; } public Class<?>[] getAttributeTypes() { return new Class<?>[] { String.class, BgColorSwatchConfig.class, BorderColorSwatchConfig.class, DefnConfig.class }; } public static class BgColorSwatchConfig implements ConfigurerFactory { public Configurer getConfigurer(AutoConfigurable c, String key, String name) { return new ColorSwatchConfigurer(key, name, ((GamePieceImage) c).getBgColor()); } } public static class BorderColorSwatchConfig implements ConfigurerFactory { public Configurer getConfigurer(AutoConfigurable c, String key, String name) { return new ColorSwatchConfigurer(key, name, ((GamePieceImage) c).getBorderColor()); } } public static class DefnConfig implements ConfigurerFactory { static GamePieceImage id; public Configurer getConfigurer(AutoConfigurable c, String key, String name) { id = (GamePieceImage) c; id.defnConfig = new InstanceConfigurer(key, name, id); id.rebuildInstances(); return id.defnConfig; } public static void refresh() { if (id.defnConfig != null) { id.defnConfig.repack(); } } } public String[] getAttributeNames() { return new String[] {NAME, BG_COLOR, BORDER_COLOR, PROPS}; } public ColorSwatch getBgColor() { return bgColor; } public ColorSwatch getBorderColor() { return borderColor; } @SuppressWarnings("unchecked") public void setAttribute(String key, Object value) { if (NAME.equals(key)) { final String newName = (String) value; final String oldName = getConfigureName(); if (newName != oldName && oldName.length() > 0) { final ArchiveWriter w = GameModule.getGameModule().getArchiveWriter(); w.removeImage(oldName); w.addImage(newName, getEncodedImage((BufferedImage) visImage)); } setConfigureName(newName); } else if (BG_COLOR.equals(key)) { if (value instanceof String) { value = new ColorSwatch((String) value); } bgColor = (ColorSwatch) value; if (defnConfig != null) { defnConfig.visualizer.rebuild(); } } else if (BORDER_COLOR.equals(key)) { if (value instanceof String) { value = new ColorSwatch((String) value); } borderColor = (ColorSwatch) value; if (defnConfig != null) { defnConfig.visualizer.rebuild(); } } else if (PROPS.equals(key)) { if (value instanceof String) { value = InstanceConfigurer.StringToProperties((String) value, this); } if (instances instanceof List<?>) { instances = (List<ItemInstance>) value; } if (defnConfig != null) { rebuildInstances(); defnConfig.visualizer.rebuild(); defnConfig.repack(); } } if (defnConfig != null) { rebuildVisualizerImage(); } } public String getAttributeValueString(String key) { if (NAME.equals(key)) { return getConfigureName(); } else if (BG_COLOR.equals(key)) { return bgColor.encode(); } else if (BORDER_COLOR.equals(key)) { return borderColor.encode(); } else if (PROPS.equals(key)) { return InstanceConfigurer.PropertiesToString(instances); } else return null; } public VisibilityCondition getAttributeVisibility(String name) { if (BORDER_COLOR.equals(name)) { return borderCond; } else { return super.getAttributeVisibility(name); } } private VisibilityCondition borderCond = new VisibilityCondition() { public boolean shouldBeVisible() { if (getLayout() == null) { return false; } else { return getLayout().isColoredBorder(); } } }; public void removeFrom(Buildable parent) { idMgr.remove(this); } public HelpFile getHelpFile() { return HelpFile.getReferenceManualPage("GamePieceImage.htm"); //$NON-NLS-1$ } public Class<?>[] getAllowableConfigureComponents() { return new Class[0]; } public void addTo(Buildable parent) { layout = (GamePieceLayout) parent; idMgr.add(this); validator = idMgr; setAllAttributesUntranslatable(); rebuildInstances(); } public String getId() { return id; } public void setId(String id) { this.id = id; } public static String getConfigureTypeName() { return "Game Piece Image"; } public void refreshConfig() { rebuildVisualizerImage(); } public GamePieceLayout getLayout() { return layout; } public int getVisualizerHeight() { return getLayout().getVisualizerHeight(); } public int getVisualizerWidth() { return getLayout().getVisualizerWidth(); } public Image getVisualizerImage() { if (visImage == null) { rebuildVisualizerImage(); } return visImage; } // Build the new image and add to the archive public void rebuildVisualizerImage() { if (layout != null) { visImage = layout.buildImage(this); final ArchiveWriter w = GameModule.getGameModule().getArchiveWriter(); if (w != null) { if (getConfigureName() != null && getConfigureName().length() > 0) { w.addImage(getConfigureName(), getEncodedImage((BufferedImage) visImage)); SourceOp op = Op.load(getConfigureName()); op.update(); } } } } public byte[] getEncodedImage(BufferedImage bufferedImage) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); try { ImageIO.write(bufferedImage,"png", out); //$NON-NLS-1$ } catch (IOException e) { ErrorDialog.bug(e); // FIXME: why byte[1] instead of byte[0]? return new byte[1]; } return out.toByteArray(); } public ItemInstance getInstance(String name) { for (ItemInstance instance : instances) { if (name.equals(instance.getName())) { return instance; } } return null; } public TextItemInstance getTextInstance(String name) { for (ItemInstance instance : instances) { if (instance instanceof TextItemInstance) { if (name.equals(instance.getName())) { return (TextItemInstance) instance; } } } return null; } public TextBoxItemInstance getTextBoxInstance(String name) { for (ItemInstance instance : instances) { if (instance instanceof TextBoxItemInstance) { if (name.equals(instance.getName())) { return (TextBoxItemInstance) instance; } } } return null; } public SymbolItemInstance getSymbolInstance(String name) { for (ItemInstance instance : instances) { if (instance instanceof SymbolItemInstance) { if (name.equals(instance.getName())) { return (SymbolItemInstance) instance; } } } return null; } public ShapeItemInstance getShapeInstance(String name) { for (ItemInstance instance : instances) { if (instance instanceof ShapeItemInstance) { if (name.equals(instance.getName())) { return (ShapeItemInstance) instance; } } } return null; } public ImageItemInstance getImageInstance(String name) { for (ItemInstance instance : instances) { if (instance instanceof ImageItemInstance) { if (name.equals(instance.getName())) { return (ImageItemInstance) instance; } } } return null; } /* * Reconcile our current elements with the elements in the owning scheme. */ protected void rebuildInstances() { final ArrayList<ItemInstance> newInstances = new ArrayList<ItemInstance>(); for (ItemInstance prop : instances) { final Item item = layout.getItem(prop.getName()); if (item != null && item.getType().equals(prop.getType())) { prop.setLocation(item.getLocation()); newInstances.add(prop); } } if (layout != null) { for (Item item : layout.getItems()) { final String name = item.getConfigureName(); final String type = item.getType(); final String location = item.getLocation(); boolean found = false; for (ItemInstance prop : instances) { found = name.equals(prop.getName()); if (found) break; } if (!found) { final ItemInstance instance = ItemInstance.newDefaultInstance(name, type, location); instance.addTo(this); newInstances.add(instance); } } } instances = newInstances; if (defnConfig != null) { defnConfig.setValue(instances); } rebuildVisualizerImage(); } }