package codelines;

import animation.CodeLine;
import animation.ControlFlow;
import animation.Memory;
import animation.StackFrame;
import animation.StackFrame.FrameType;

/**
 * Yey, IF is a LOOP.
 * @author kolja
 *
 */
public abstract class IfLoop extends CodeLine {

	@Override
	public ControlFlow runForward(Memory m) {
		if( m.isDefined( "line_" + lineId + "_inside", false ) )
		{
			StackFrame old = m.removeFrame();
			actions.push( (Memory mem) -> {
				mem.addFrame( old );
            	return new ControlFlow( ControlFlow.STEP_INTO );
			} );
            return new ControlFlow( ControlFlow.STEP_OVER );
		}
		else
		{
            if( condition( m ) ) {
            	m.addFrame( new StackFrame( FrameType.LOOP ) );
            	m.declare( "line_" + lineId + "_inside", true, false );
            	actions.push( (Memory mem) -> {
            		mem.removeFrame();
            		return new ControlFlow( ControlFlow.STEP_OVER );
            	} );
            	return new ControlFlow( ControlFlow.STEP_INTO );
            } else {
            	m.declare( "line_" + lineId + "_inside", false, false );
            	actions.push( (Memory mem) -> {
            		mem.undeclare( "line_" + lineId + "_inside", false );
	                return new ControlFlow( ControlFlow.STEP_OVER );
            	} );
                return new ControlFlow( ControlFlow.STEP_OVER );
            }
		}
	}

	abstract protected boolean condition( Memory m );
}
