package jadex.bdi.examples.blocksworld;
import jadex.commons.SUtil;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* A table in the blocks-world.
* In contrast to a block, a table may have multiple blocks on top.
*/
public class Table extends Block
{
//-------- attributes --------
/** The name of the table. */
protected String name;
/** The blocks located on top of the table. */
protected List blocks;
/** The target configuration (if any). */
protected Table target;
// /** The block listener (if any). */
// protected PropertyChangeListener listener;
/** The old solution state. */
protected boolean solution;
//-------- constructors --------
/**
* Create a new table.
*/
public Table()
{
this("Table", new Color(64, 32, 32));
}
/**
* Create a new table.
* /
public Table(Table target)
{
this();
this.target = target;
if(target!=null)
{
this.solution = configurationEquals(target);
listener = new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent evt)
{
boolean oldsolution = solution;
solution = configurationEquals(Table.this.target);
pcs.firePropertyChange("solution", oldsolution, solution);
}
};
}
}*/
/**
* Create a new table.
* @param name The name of the table.
* @param color The color of the table.
*/
public Table(String name, Color color)
{
super(-1, color, null);
this.name = name;
this.blocks = new ArrayList();
}
//-------- methods --------
/**
* The table is always clear.
*/
public boolean isClear()
{
return true;
}
/**
* Create a string representation of this block.
*/
public String toString()
{
return name;
}
/**
* Get all blocks on the table.
* Also returns blocks which are located on other blocks on the table.
*/
public Block[] getAllBlocks()
{
List ret = new ArrayList(blocks);
for(int i=0; i<ret.size(); i++)
{
Block b = (Block)ret.get(i);
if(b.upper!=null)
ret.add(b.upper);
}
return (Block[])ret.toArray(new Block[ret.size()]);
}
/**
* Get the stacks on the table.
*/
public Block[][] getStacks()
{
Block[][] stacks = new Block[blocks.size()][];
for(int i=0; i<stacks.length; i++)
{
List ret = new ArrayList();
Block b = (Block)blocks.get(i);
while(b!=null)
{
ret.add(b);
b = b.upper;
}
stacks[i] = (Block[])ret.toArray(new Block[ret.size()]);
}
return stacks;
}
/**
* clear all blocks from the table.
*/
public void clear()
{
Block[] all = getAllBlocks();
for(int i=all.length-1; i>=0; i--)
all[i].stackOn(null);
}
/**
* Check if two configurations are equal.
*/
public boolean configurationEquals(Table table)
{
boolean ret = false;
if(blocks.size()==table.blocks.size())
{
// Iterate through base blocks.
ret = true;
for(Iterator i=blocks.iterator(); ret && i.hasNext(); )
{
Block block = (Block)i.next();
int index = table.blocks.indexOf(block);
if(index!=-1)
{
// Traverse and compare corresponding stacks.
Block block2 = (Block)table.blocks.get(index);
while((block!=null || block2!=null)
&& (ret=SUtil.equals(block, block2)))
{
block = block.upper;
block2 = block2.upper;
}
}
else
{
ret = false;
}
}
}
return ret;
}
/**
* Add a block to this block.
*/
protected void addBlock(Block block)
{
blocks.add(block);
// if(listener!=null)
// block.addPropertyChangeListener(listener);
this.pcs.firePropertyChange("allBlocks", null, block);
}
/**
* Remove a block from this block.
*/
protected void removeBlock(Block block)
{
blocks.remove(block);
// if(listener!=null)
// block.removePropertyChangeListener(listener);
this.pcs.firePropertyChange("allBlocks", block, null);
}
/**
* Check for equality.
* /
public boolean equals(Object o)
{
return o instanceof Table && configurationEquals((Table)o);
}*/
/**
* Check for equality.
* /
public boolean isSolution()
{
return solution;
}*/
/**
* Get the hash code.
* /
public int hashCode()
{
int ret = 1;
List allblocks = new ArrayList(blocks);
for(int i=0; i<allblocks.size(); i++)
{
Block b = (Block)allblocks.get(i);
ret = ret*31 + b.hashCode();
if(b.upper!=null)
allblocks.add(b.upper);
}
return ret;
}*/
}