package at.oefai.aaa.agent.jam;

import java.io.Serializable;

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

/**
 * Represents an agent's goals.
 * @author Marc Huber
 * @author Jaeho Lee
 */
public interface Goal extends Serializable {
    static enum Status { UNTRIED, FAILURE, SUCCESS, ACTIVE, BLOCKED, ABANDONED }

    GoalAction getGoalAction();
    Relation getConcludeRelation();

    boolean isNew();

    boolean isToplevelGoal();

    boolean isLeafGoal();

    void setNew(final boolean flag);

    Goal getPrevGoal();

    Goal getSubgoal();

    void setSubgoal(final Goal g);

    APLElement getIntention();

    void setIntention(final APLElement se);

    Status getStatus();

    void setStatus(final Status st);

    PlanRuntimeState getRuntimeState();

    void setRuntimeState(PlanRuntimeState r);

    /** Verify that the plan's context is valid. */
    boolean confirmContext();

    /** Execute the procedure associated with a plan's BODY specification. */
    PlanRuntimeState.State execute();

    /** Execute the procedure associated with a plan's FAILURE specification. */
    PlanRuntimeState.State executeFailure();

    /** Execute the procedure associated with a plan's EFFECTS specification. */
    PlanRuntimeState.State executeEffects();

    /** Return the goal's relation label. */
    String getName();

    /** Check whether the goal should have an Applicable Plan List created for it. */
    boolean generateAPL();

    /** Get the binding of the goal arguments based upon the parent goal (if it exists). */
    Binding getGoalBinding();

    /** Get the binding of the goal arguments based upon the plan's goal (if it exists). */
    Binding getIntentionBinding();

    /**
     * This function should be defined in this goal class because it must use the binding of the subgoaling plan,
     * not the candidate plans for this goal.
     */
    float evalUtility();

    void reduceUtility();

    /** this one uses the utility of an intended APLElement if present. */
    float getIntendedUtility();

    /** gets the intended utility of the root goal that spawned this one. */
    float getTopLevelIntendedUtility();


    /** Find matches between bound and unbound variables. */
    boolean matchRelation(Relation dstRelation, Binding dstBinding);

    /** Check whether the goal's specification compares to the parameters. */
    boolean matchGoal(GoalAction pGoalAction, Binding goalActionBinding);

    /** Return the agent's intention structure. */
    IntentionStructure getIntentionStructure();

    /** Remove the goal's intention and all subgoal intentions. */
    void removeIntention(boolean failed);

    /** Format output to the given stream so that it can be in-line with other output. */
    String formattedString();

    String toString();
}
