package org.jactr.modules.pm.motor.managers;
/*
* default logging
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.commonreality.identifier.IIdentifier;
import org.jactr.core.buffer.six.IStatusBuffer;
import org.jactr.core.chunk.IChunk;
import org.jactr.core.production.condition.CannotMatchException;
import org.jactr.core.slot.BasicSlot;
import org.jactr.core.slot.DefaultMutableSlot;
import org.jactr.core.slot.IConditionalSlot;
import org.jactr.core.slot.IMutableSlot;
import org.jactr.core.slot.ISlot;
import org.jactr.core.slot.IUniqueSlotContainer;
import org.jactr.modules.pm.buffer.IPerceptualBuffer;
import org.jactr.modules.pm.motor.IMotorModule;
public class MuscleState implements IUniqueSlotContainer
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(MuscleState.class);
private Map<String, ISlot> _slotMap;
private double[] _position = { 0, 0, 0 };
private IIdentifier _identifier;
private String _name;
public MuscleState(IIdentifier identifier, String name, IChunk freeChunk)
{
_identifier = identifier;
_name = name;
_slotMap = new TreeMap<String, ISlot>();
addSlot(new BasicSlot(IMotorModule.MUSCLE_SLOT, name));
addSlot(new DefaultMutableSlot(IStatusBuffer.STATE_SLOT, freeChunk));
addSlot(new DefaultMutableSlot(IPerceptualBuffer.PREPARATION_SLOT,
freeChunk));
addSlot(new DefaultMutableSlot(IPerceptualBuffer.PROCESSOR_SLOT, freeChunk));
addSlot(new DefaultMutableSlot(IPerceptualBuffer.EXECUTION_SLOT, freeChunk));
addSlot(new DefaultMutableSlot("p1", null));
addSlot(new DefaultMutableSlot("p2", null));
addSlot(new DefaultMutableSlot("p3", null));
addSlot(new DefaultMutableSlot("p4", null));
}
public IIdentifier getIdentifier()
{
return _identifier;
}
public String getName()
{
return _name;
}
@Override
public String toString()
{
return getName();
}
public void set(IChunk chunk, String... slotNames)
{
for (String slotName : slotNames)
{
IMutableSlot slot = (IMutableSlot) getSlot(slotName);
if (slot != null)
{
slot.setValue(chunk);
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("%s.%s = %s", _name, slotName, chunk));
}
}
}
public double[] getPosition(double[] container)
{
System.arraycopy(_position, 0, container, 0, Math.min(container.length,
_position.length));
return container;
}
void setPosition(double[] position)
{
System.arraycopy(position, 0, _position, 0, Math.min(position.length,
_position.length));
for (int i = 0; i < position.length; i++)
{
String slotName = String.format("p%d", i + 1);
IMutableSlot slot = (IMutableSlot) getSlot(slotName);
if (slot == null)
{
slot = new DefaultMutableSlot(slotName, null);
addSlot(slot);
}
slot.setValue(position[i]);
}
}
public ISlot getSlot(String slotName)
{
return _slotMap.get(slotName.toLowerCase());
}
public void addSlot(ISlot slot)
{
_slotMap.put(slot.getName().toLowerCase(), slot);
}
public boolean canModify()
{
return false;
}
public Collection<? extends ISlot> getSlots()
{
return new ArrayList<ISlot>(_slotMap.values());
}
public Collection<ISlot> getSlots(Collection<ISlot> slots)
{
if (slots == null) slots = new ArrayList<ISlot>();
slots.addAll(_slotMap.values());
return slots;
}
public void removeSlot(ISlot slot)
{
_slotMap.remove(slot.getName().toLowerCase());
}
public Collection<IConditionalSlot> matchesStatus(
Collection<IConditionalSlot> slots, Map<String, Object> bindings)
throws CannotMatchException
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("Checking conditional slots against buffer status : "
+ slots);
Collection<IConditionalSlot> slotsToRemove = new ArrayList<IConditionalSlot>(
slots.size());
for (IConditionalSlot cSlot : slots)
{
IConditionalSlot slot = cSlot;
if (_slotMap.containsKey(slot.getName().toLowerCase()))
{
Object testValue = testStatusSlot(slot);
if (cSlot.isVariableValue())
bindings.put((String) cSlot.getValue(), testValue);
slotsToRemove.add(slot);
}
}
return slotsToRemove;
}
private Object testStatusSlot(IConditionalSlot slot)
throws CannotMatchException
{
ISlot statusSlot = getSlot(slot.getName());
// we have something named this..
if (!slot.matchesCondition(statusSlot.getValue()))
{
String message = String.format("%s.%s doesn't match condition %s",
getName(), statusSlot, slot);
if (LOGGER.isDebugEnabled()) LOGGER.debug(message);
throw new CannotMatchException(message);
}
if (LOGGER.isDebugEnabled())
LOGGER.debug(getName() + " : " + statusSlot
+ " matches conditional slot " + slot);
return statusSlot.getValue();
}
}