package codelines;

import animation.CodeLine;
import animation.ControlFlow;
import animation.Memory;
import animation.Memory.MemoryType;
import animation.Memory.ReadOnlyMemory;

public abstract class DeclareVariable <T> extends CodeLine {

	private boolean oldExists;
	private String name;
	private MemoryType mt;
    
    public DeclareVariable( String name )
    {
        this.name = name;
        this.mt = MemoryType.LOCAL;
    }
	
	public DeclareVariable( String name, MemoryType mt )
	{
		this.name = name;
		this.mt = mt;
	}

	@Override
	public ControlFlow runForward(Memory m) {
		
		oldExists = m.isDefined( name, mt );
		T oldVal = m.read( name, mt );
		m.declare( name, value( m.createReadOnlyMemory() ), mt );
		actions.push( (Memory mem) -> {
			mem.undeclare( name, mt );
            if( oldExists )
				mem.write( name, oldVal, mt );
		});
		return new ControlFlow( ControlFlow.STEP_OVER );
	}
	
	abstract protected T value( ReadOnlyMemory m );
}
