/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.portrayal.simple;
import sim.portrayal.*;
import java.awt.*;
import sim.display.*;
import sim.util.*;
/**
A wrapper for multiple Portrayal2Ds which calls on one or the other one according to the
underlying state of the object, which must be Valuable or a Number of some sort. The
particular sub-portrayal (called a "facet") chosen is based on the integer value returned
(or converted to an integer if it's a double). Optionally FacetedPortrayal2D will call on
*all* its underlying portrayals at one time. If any array element is null, FacetedPortrayal2D
will assume it represents the object itself (assuming the object itself is also a SimplePortrayal2D).
*/
public class FacetedPortrayal2D extends SimplePortrayal2D
{
public SimplePortrayal2D[] children;
boolean portrayAllChildren = false;
boolean errorThrown;
/** If child is null, then the underlying model object
is presumed to be a Portrayal2D and will be used. */
public FacetedPortrayal2D(SimplePortrayal2D[] children, boolean portrayAllChildren)
{
this.children = children;
this.portrayAllChildren = portrayAllChildren;
}
/** If child is null, then the underlying model object
is presumed to be a Portrayal2D and will be used. */
public FacetedPortrayal2D(SimplePortrayal2D[] children)
{
this(children, false);
}
/** Returns the child index to use for the given object.
The value must be >= 0 and < numIndices. The default implementation
returns the value of the object if it's a Number or is sim.util.Valuable
and if the value is within the given range (and is an integer).
Otherwise 0 is returned.
*/
public int getChildIndex(Object object, int numIndices)
{
int element = 0;
if( object instanceof Number )
element = (int)(((Number)object).doubleValue());
else if (object instanceof Valuable)
element = (int)(((Valuable)object).doubleValue());
if (element < 0 || element >= children.length)
{
if (!errorThrown)
{
errorThrown = true;
System.err.println("WARNING: FacetedPortrayal was given a value that doesn't correspond to any array element.");
}
element = 0;
}
return element;
}
SimplePortrayal2D getChild(Object object)
{
int element = getChildIndex(object, children.length);
if (children[element] == null)
if (object instanceof SimplePortrayal2D)
return (SimplePortrayal2D)object;
else throw new RuntimeException("FacetedPortrayal had a null child but the object is not itself a SimplePortrayal2D");
else return children[element];
}
public void draw(Object object, Graphics2D graphics, DrawInfo2D info)
{
if (portrayAllChildren)
for(int i = 0; i < children.length;i++)
children[i].draw(object, graphics, info);
else
getChild(object).draw(object, graphics, info);
}
public boolean hitObject(Object object, DrawInfo2D range)
{
if (portrayAllChildren)
{
for(int i = 0; i < children.length;i++)
if (children[i].hitObject(object, range))
return true;
return false;
}
else
return getChild(object).hitObject(object,range);
}
/** If portrayAllChildren, Returns true if any ONE of the children returns true. */
public boolean setSelected(LocationWrapper wrapper, boolean selected)
{
if (portrayAllChildren)
{
for(int i = 0; i < children.length;i++)
if (children[i].setSelected(wrapper, selected))
return true;
return false;
}
else
return getChild(wrapper.getObject()).setSelected(wrapper, selected);
}
/** If portrayAllChildren, Calls on the first child to return the inspector. */
public Inspector getInspector(LocationWrapper wrapper, GUIState state)
{
if (portrayAllChildren)
return children[0].getInspector(wrapper,state);
else
return getChild(wrapper.getObject()).getInspector(wrapper,state);
}
/** If portrayAllChildren, Calls on the first child to return the name. */
public String getName(LocationWrapper wrapper)
{
if (portrayAllChildren)
return children[0].getName(wrapper);
else
return getChild(wrapper.getObject()).getName(wrapper);
}
}