package at.oefai.aaa.agent.jam;

import java.io.Serializable;

/**
 * A pair of a Relation and a Plan, used for bookkeeping in MetaData.
 * This is a kind of static snapshot (no bindings) of an Intention, i.e. an APLElement
 * @author Stefan Rank
 * @author Sandro Pirkwieser
 */
class IntentionPair implements Serializable {
    // package level access as this is used as a simple Pair class
    final Plan plan;
    final Relation relation;

    IntentionPair(final APLElement pAplele) {
        assert (pAplele != null);
        this.relation = new Relation(pAplele.getFromGoal().getGoalAction().getRelation(),
                                     pAplele.getFromGoal().getGoalBinding());
        this.plan = pAplele.getPlan();
    }

    IntentionPair(final Relation pRel, final Plan pPlan) {
        assert (pRel != null && pPlan != null);
        this.relation = pRel;
        this.plan = pPlan;
    }

    public String toString() {
        return "Goal: " + this.relation.simpleString(null) + " | Plan: " + this.plan.getName();
    }

    /**
     * ATTENTION: equals of IntentionPair violates the hashCode-equals contract.
     * tests for plan object identity and unification of the relations (no bindings).
     * do not use IntentionPair as Map-keys!
     */
    public boolean equals(final Object o) {
        if (o == null || o.getClass() != this.getClass()) {
            return false;
        }
        if (this.plan != ((IntentionPair) o).plan) {
            return false;
        }
        // here check the goalaction relations, otherwise the same plan, but with other
        // bindings could be compared equal
        return Relation.unify(((IntentionPair) o).relation, null, this.relation, null);
    }

    /**
     * ATTENTION: hashCode is simply calling super.hashCode(), i.e. Object.hashCode().
     * This must be changed if IntentionPair should be used as keys in maps.
     */
    public int hashCode() {
        return super.hashCode();
    }

}
