package at.oefai.aaa.agent.jam;

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

/**
 * Represents the runtime state of plan constructs.
 * @author Marc Huber
 * @author Jaeho Lee
 */

class PlanRuntimeWhileState implements PlanRuntimeState {

    private PlanConstruct thisConstruct = null;
    private PlanRuntimeState substate = null;

    private boolean checkLoopCondition;

    /**  */
    PlanRuntimeWhileState(final PlanWhileConstruct be) {
        this.thisConstruct = be;
        this.substate = be.getSequence().newRuntimeState();
        this.checkLoopCondition = true;
    }

    // Member functions

    /**  */
    public State execute(final Binding b, final Goal thisGoal) {
        // If we're at the top of the loop we evaluate the test and execute the
        // first step if it succeeds.  Otherwise the loop is done.
        if (this.checkLoopCondition) {

            Action.Result testReturnVal = ((PlanWhileConstruct) this.thisConstruct).getTest().execute(b, thisGoal);
            if (testReturnVal != Action.Result.SUCCEEDED) {
                return State.CONSTRUCT_COMPLETE;
            }
            this.checkLoopCondition = false;
        }

        State returnVal = this.substate.execute(b, thisGoal);

        if (returnVal == State.CONSTRUCT_FAILED) {
            return State.CONSTRUCT_FAILED;
        } else if (returnVal == State.CONSTRUCT_COMPLETE) {
            this.substate = ((PlanWhileConstruct) this.thisConstruct).getSequence().newRuntimeState();
            this.checkLoopCondition = true;
            return State.CONSTRUCT_INCOMP;
        } else { // return_val == Status.CONSTRUCT_INCOMP
            return State.CONSTRUCT_INCOMP;
        }
    }

}

