/*
Created 26-May-2006 - Richard Morris
*/
package weasel.jep.function;


import java.util.Stack;
import java.util.Vector;

import weasel.jep.ASTVarNode;
import weasel.jep.EvaluatorI;
import weasel.jep.Node;
import weasel.jep.ParseException;
import weasel.jep.Variable;


/**
 * Function which allows array access using the a[3] notation on left and right
 * hand side. <code>
 * a=[4,3,2,1];
 * a[2]; // returns 2
 * a[2]=5; // a is now [4,5,2,1]
 * </code>
 * 
 * @author Richard Morris
 */
public class Ele extends PostfixMathCommand implements LValueI {

	/**
	 * 
	 */
	public Ele() {
		numberOfParameters = 2;
	}

	@Override
	public void set(EvaluatorI pv, Node node, Object value) throws ParseException {
		Node lhsNode = node.jjtGetChild(0);

		if (!(lhsNode instanceof ASTVarNode)) throw new ParseException("Ele: lhs must be a variable");
		ASTVarNode vn = (ASTVarNode) lhsNode;
		Variable var = vn.getVar();
		Object rhs = pv.eval(node.jjtGetChild(1));
		int index = -1;
		if (rhs instanceof Number) {
			index = ((Number) rhs).intValue() - 1;
		} else if (rhs instanceof Vector) {
			Vector vec = (Vector) rhs;
			if (vec.size() != 1) throw new ParseException("Ele: only single dimension arrays supported in JEP");
			index = ((Number) vec.firstElement()).intValue() - 1;
		} else
			throw new ParseException("Ele: rhs must be a number");
		Object oldVarVal = var.getValue();
		if (!(oldVarVal instanceof Vector)) throw new ParseException("Ele: the value of the variable must be a Vector");
		Vector newVarVal = (Vector) ((Vector) oldVarVal).clone();
		newVarVal.set(index, value);
		var.setValue(newVarVal);
	}

	@Override
	public void run(Stack s) throws ParseException {
		checkStack(s);// check the stack
		Object rhs = s.pop();
		Object lhs = s.pop();
		if (!(lhs instanceof Vector)) throw new ParseException("Ele: lhs must be an instance of Vector");

		if (rhs instanceof Number) {
			int index = ((Number) rhs).intValue();
			Object val = ((Vector) lhs).elementAt(index - 1);
			s.push(val);
			return;
		}
		if (rhs instanceof Vector) {
			Vector vec = (Vector) rhs;
			if (vec.size() != 1) throw new ParseException("Ele: only single dimension arrays supported in JEP");
			int index = ((Number) vec.firstElement()).intValue();
			Object val = ((Vector) lhs).elementAt(index - 1);
			s.push(val);
			return;

		}
		throw new ParseException("Ele: only single dimension arrays supported in JEP");
	}

}
