package at.oefai.aaa.agent.jam;

import java.io.Serializable;
import java.util.ListIterator;

import at.oefai.aaa.agent.jam.types.Binding;
import at.oefai.aaa.agent.jam.types.DList;

/**
 * A boolean-evaluable World Model fact.
 * @author Marc Huber
 * @author Jaeho Lee
 */
class FactCondition extends RelationCondition implements Serializable {

    /** Constructor w/ World Model relation to check and interpreter as arguments. */
    FactCondition(final Relation pRelation, final WorldModelTable pWorldModel) {
        super(pRelation, pWorldModel);
    }

    // Member functions

    /** Compare the relation against the world model and add and/or delete bindings as appropriate. */
    public boolean check(final DList<Binding> bl) {
        ListIterator<Binding> ble = bl.listIterator(); // needed for .remove() and .previous()
        while (ble.hasNext()) {
            Binding oldBinding = ble.next();
            // go back one binding in the iterator
            Binding backupBinding = ble.previous();
            assert (backupBinding == oldBinding);
            // now insert new ones before oldBinding
            Binding newBinding = new Binding(oldBinding);
            DList<Binding> bindList = getWorldModel().getWMBindingList(newBinding,getRelation(),false);
            for (Binding b : bindList) {
                ble.add(b);
            }
            // remove the oldBinding using the iterator (Stefan Rank)
            backupBinding = ble.next();
            assert (backupBinding == oldBinding);
            ble.remove();
        }
        return (bl.size() == 0) ? false : true;
    }

    /** Confirm whether the binding is still valid against the current World Model. */
    public boolean confirm(final Binding b) {
        return getWorldModel().match(getRelation(), b);
    }

}

