package net.minecraft.src.weasel;


import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.PC_INBT;
import net.minecraft.src.PC_Utils;
import net.minecraft.src.weasel.obj.WeaselObject;
import net.minecraft.src.weasel.obj.WeaselStack;
import net.minecraft.src.weasel.obj.WeaselVariableMap;


/**
 * The WEASEL virtual machine.
 * 
 * @author MightyPork
 * @copy (c) 2012
 */
public class WeaselEngine implements PC_INBT {

	/**
	 * List of variables visible in current function body / root list.
	 */
	public WeaselVariableMap variables = new WeaselVariableMap();

	/** Stack of addresses and variable lists */
	public WeaselStack systemStack = new WeaselStack();
	
	/** Stack of user's data (PUSH and POP instructions)  */
	public WeaselStack dataStack = new WeaselStack();

	/** List of all instructions in the program */
	public InstructionList instructionList = new InstructionList(this);

	/** Address of first instruction in current scope */
	public int scopeStart;

	/** Address of last instruction in current scope */
	public int scopeEnd;

	private boolean pauseRequested = false;

	/**
	 * Request pause after the current instruction is finished
	 */
	public void requestPause() {
		pauseRequested = true;
	}

	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound tag) {
		tag.setCompoundTag("Variables", WeaselObject.saveObjectToNBT(variables, new NBTTagCompound()));
		tag.setCompoundTag("SystemStack", WeaselObject.saveObjectToNBT(systemStack, new NBTTagCompound()));
		tag.setCompoundTag("DataStack", WeaselObject.saveObjectToNBT(dataStack, new NBTTagCompound()));
		tag.setCompoundTag("InstructionList", instructionList.writeToNBT(new NBTTagCompound()));
		tag.setInteger("ScopeStart", scopeStart);
		tag.setInteger("ScopeEnd", scopeEnd);
		return tag;
	}

	@Override
	public WeaselEngine readFromNBT(NBTTagCompound tag) {
		
		variables = (WeaselVariableMap) WeaselObject.loadObjectFromNBT(tag.getCompoundTag("Variables"));
		systemStack = (WeaselStack) WeaselObject.loadObjectFromNBT(tag.getCompoundTag("SystemStack"));
		dataStack = (WeaselStack) WeaselObject.loadObjectFromNBT(tag.getCompoundTag("DataStack"));
		instructionList = (InstructionList) new InstructionList(this).readFromNBT(tag.getCompoundTag("InstructionList"));
		scopeStart = tag.getInteger("ScopeStart");
		scopeEnd = tag.getInteger("ScopeEnd");
		
		
		return this;
	}





}
