package net.minecraft.src.weasel.obj;


import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagList;


/**
 * List of variables in the WeaselVM<br>
 * Variable list can be put into stack when CALL is executed,<br>
 * and it can also be written into NBT.
 * 
 * @author MightyPork
 * @copy (c) 2012
 */
public class WeaselStack extends WeaselObject {

	private Stack<WeaselObject> stack;

	/**
	 * clear the map.
	 */
	public void clear() {
		stack.clear();
	}

	/**
	 * Check if the stack is empty
	 * 
	 * @return is empty
	 */
	public boolean empty() {
		return stack.empty();
	}

	/**
	 * push object on stack
	 * 
	 * @param obj
	 */
	public void push(WeaselObject obj) {
		stack.push(obj.copy());
	}

	/**
	 * pop object from stack
	 * 
	 * @return the object
	 */
	public WeaselObject pop() {
		return stack.pop();
	}

	/**
	 * Look at the topmost object without removing.
	 * 
	 * @return the object on top of the stack
	 */
	public WeaselObject peek() {
		return stack.peek();
	}

	/**
	 * List of weasel variables
	 */
	public WeaselStack() {
		super(WeaselObjectType.VARIABLE_LIST);
		stack = new Stack<WeaselObject>();
	}

	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound tag) {

		NBTTagList tags = new NBTTagList();

		List<WeaselObject> list = new ArrayList<WeaselObject>(stack);

		for (WeaselObject obj : list) {
			NBTTagCompound tag1 = WeaselObject.saveObjectToNBT(obj,new NBTTagCompound());
			tags.appendTag(tag1);
		}
		tag.setTag("Stack", tags);

		return tag;

	}

	@Override
	public WeaselStack readFromNBT(NBTTagCompound tag) {


		NBTTagList tags = tag.getTagList("Stack");

		stack.clear();
		for (int i = 0; i < tags.tagCount(); i++) {
			NBTTagCompound tag1 = (NBTTagCompound) tags.tagAt(i);
			stack.push(WeaselObject.loadObjectFromNBT(tag1));
		}

		return this;

	}


	@Override
	public String toString() {
		return "STACK(" + stack + ")";
	}


	@Override
	public boolean equals(Object obj) {
		return obj == this;
	}


	@Override
	public int hashCode() {
		return stack.hashCode();
	}


	@Override
	public Object get() {
		return stack;
	}


	@SuppressWarnings("unchecked")
	@Override
	public void set(Object obj) {
		if (obj == null || !(obj instanceof Stack)) {
			throw new RuntimeException("Trying to store " + obj + " in a Stack variable.");
		}
		stack = (Stack<WeaselObject>) obj;
	}

	@Override
	public WeaselStack copy() {
		WeaselObject obj =  new WeaselStack();
		obj.set(stack.clone());
		return (WeaselStack) obj;
	}


}
