/*
* $Id$
*
* Copyright (c) 2004 by Rodney Kinney
*
* 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.map;
import javax.swing.JToolBar;
import VASSAL.build.AbstractConfigurable;
import VASSAL.build.Buildable;
import VASSAL.build.module.Map;
import VASSAL.build.module.documentation.HelpFile;
import VASSAL.configure.SingleChildInstance;
import VASSAL.configure.StringArrayConfigurer;
import VASSAL.counters.Deck;
import VASSAL.counters.DeckVisitor;
import VASSAL.counters.DeckVisitorDispatcher;
import VASSAL.counters.GamePiece;
import VASSAL.counters.Stack;
import VASSAL.i18n.Resources;
import VASSAL.tools.TemporaryToolBar;
/**
* Defines PieceCollection in which pieces are assigned to an arbitrary number of layers
* according to a property setting
*/
public class LayeredPieceCollection extends AbstractConfigurable {
public static final String PROPERTY_NAME="property";
public static final String LAYER_ORDER="layerOrder";
protected Collection collection = new Collection("Layer", new String[0]);
protected Map map;
protected TemporaryToolBar tempToolBar;
public LayeredPieceCollection() {
this.setAttributeTranslatable(PROPERTY_NAME, false);
}
public String[] getAttributeDescriptions() {
return new String[]{
Resources.getString("Editor.GamePieceLayers.property_layer"), //$NON-NLS-1$
Resources.getString("Editor.GamePieceLayers.order_layer"), //$NON-NLS-1$
};
}
public Class<?>[] getAttributeTypes() {
return new Class<?>[]{
String.class,
String[].class
};
}
public String[] getAttributeNames() {
return new String[]{
PROPERTY_NAME,
LAYER_ORDER
};
}
public String getAttributeValueString(String key) {
if (PROPERTY_NAME.equals(key)) {
return collection.propertyName;
}
else if (LAYER_ORDER.equals(key)) {
return StringArrayConfigurer.arrayToString(collection.layerOrder);
}
else {
return null;
}
}
public void setAttribute(String key, Object value) {
if (PROPERTY_NAME.equals(key)) {
collection.propertyName = (String) value;
}
else if (LAYER_ORDER.equals(key)) {
if (value instanceof String) {
value = StringArrayConfigurer.stringToArray((String) value);
}
collection.layerOrder = (String[]) value;
collection.initLayers(collection.layerOrder.length+1);
}
}
public void addTo(Buildable parent) {
map = (Map)parent;
validator = new SingleChildInstance(map,getClass());
map.setPieceCollection(collection);
if (tempToolBar != null) {
tempToolBar.setDelegate(map);
}
}
public JToolBar getToolBar() {
if (tempToolBar == null) {
tempToolBar = new TemporaryToolBar();
if (map != null) {
tempToolBar.setDelegate(map);
}
}
return tempToolBar.getToolBar();
}
public Class<?>[] getAllowableConfigureComponents() {
return new Class<?>[] { LayerControl.class };
}
public HelpFile getHelpFile() {
return HelpFile.getReferenceManualPage("GamePieceLayers.htm");
}
public static String getConfigureTypeName() {
return Resources.getString("Editor.GamePieceLayers.component_type"); //$NON-NLS-1$
}
public void removeFrom(Buildable parent) {
map.setPieceCollection(new DefaultPieceCollection());
for (LayerControl lc : this.getComponentsOf(LayerControl.class)) {
lc.removeFrom(this);
}
}
public Map getMap() {
return map;
}
public CompoundPieceCollection getPieceCollection() {
return collection;
}
/** The PieceCollection class used by the map to which a LayeredPieceCollection has been added */
public static class Collection extends CompoundPieceCollection implements DeckVisitor {
private String propertyName;
private String[] layerOrder;
private DeckVisitorDispatcher dispatcher = new DeckVisitorDispatcher(this);
public Collection(String propertyName, String[] layerOrder) {
super(0);
setPropertyName(propertyName);
setLayerOrder(layerOrder);
}
public String[] getLayerOrder() {
return layerOrder;
}
public void setLayerOrder(String[] layerOrder) {
this.layerOrder = layerOrder;
initLayers(layerOrder.length+1);
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public int getLayerForPiece(GamePiece p) {
return ((Integer)dispatcher.accept(p)).intValue();
}
public int getLayerForName(String layer) {
for (int i=0; i < layerOrder.length; i++) {
if (layer.equals(layerOrder[i])) {
return i;
}
}
return -1;
}
public String getLayerNameForPiece(GamePiece p) {
int layer = getLayerForPiece(p);
return layer >= layerOrder.length ? "" : layerOrder[layer];
}
protected boolean canPiecesMerge(GamePiece p1, GamePiece p2) {
return super.canPiecesMerge(p1, p2)
&& getLayerForPiece(p1) == getLayerForPiece(p2);
}
public Object visitDeck(Deck d) {
return layerOrder.length;
}
public Object visitDefault(GamePiece p) {
String property = (String) p.getProperty(propertyName);
int layer = layerOrder.length;
for (int i=0;i<layerOrder.length;++i) {
if (layerOrder[i].equals(property)) {
layer = i;
break;
}
}
return layer;
}
public Object visitStack(Stack s) {
GamePiece top = s.topPiece();
if (top == null) {
return layerOrder.length;
}
return visitDefault(top);
}
}
}