/*****************************************************************************

 JEP 2.4.1, Extensions 1.1.1
      April 30 2007
      (c) Copyright 2007, Nathan Funk and Richard Morris
      See LICENSE-*.txt for license information.

 *****************************************************************************/
package org.nfunk.jep.function;


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

import org.nfunk.jep.ParseException;


/**
 * Encapsulates and improves the Math.random() function.
 */
public class Random extends PostfixMathCommand {
	
	private java.util.Random rand = new java.util.Random();
	
	/**
	 * random function
	 */
	public Random() {
		numberOfParameters = -1;

	}

	@SuppressWarnings("rawtypes")
	@Override
	public void run(Stack stack) throws ParseException {
		checkStack(stack);// check the stack
		
		if(curNumberOfParameters > 2) throw new ParseException("Random() takes 0 to 2 parameters.");
		
		if(curNumberOfParameters == 0) {
			
			stack.push(new Double(rand.nextDouble()));	
			
		}else		
		if(curNumberOfParameters == 1) {
			
			Object arg = stack.pop();
			
			if(arg instanceof Number) {
				if(arg instanceof Double)
					stack.push(new Integer(rand.nextInt((int) Math.round((Double) arg))));
				else if(arg instanceof Float)
					stack.push(new Integer(rand.nextInt(Math.round((Float) arg))));
				else if(arg instanceof Integer)
					stack.push(new Integer(rand.nextInt((Integer) arg)));
				else if(arg instanceof Long)
					stack.push(new Integer(rand.nextInt(Math.round((Long) arg))));
				else if(arg instanceof Vector)
					stack.push(((Vector)arg).get(rand.nextInt(((Vector)arg).size())));
				else 
					throw new ParseException("Random() can't work with "+arg.getClass().getSimpleName());
			}
			return;			
			
		}else		
		if(curNumberOfParameters == 2) {
			
			Object end = stack.pop();
			Object start = stack.pop();
			
			if(start instanceof Integer && end instanceof Integer) {
				
				int st = (Integer)start;
				int en = (Integer)end;
				
				if(st == en) {
					stack.push(new Integer(st));
					return;
				}
				
				if(st > en) {
					throw new ParseException("Random(start,end) can't have start > end.");
				}		
				
				stack.push(new Integer((Integer)start + rand.nextInt(((Integer)end-(Integer)start+1))));
			}
			return;			
			
		}
		
		throw new ParseException("Random() got invalid number of parameters ("+curNumberOfParameters+")");
	}
}
