import java.util.Iterator;
import java.util.Vector;

public class RPNMultiDigit extends RPN {

	/**
	 * @param args
	 */
	public static void main(String[] args) {


	}
	
	public static String toRPN (String infixFormula) throws FormulaFormatException {
		
		rQueue = new RpnQueue();
		rStack = new RpnStack();
		
		String ret = "";
		
		for (int i = 0; i < infixFormula.length(); i++) {
						
			// check if current character is a number
			if (isNumber(infixFormula.charAt(i))) {
			
				rQueue.add(infixFormula.charAt(i));
				
			}
			// character is an operator
			else {
				
				// add seperator for number ending
				if (!rQueue.isEmpty() && isNumber(rQueue.getLast())) rQueue.add('#');
								
				// check if an operator already exists in stack
				if (!rStack.isEmpty()) {
					try {

						// check for open round bracket
						if (infixFormula.charAt(i) == '(') {
							
							rStack.add(infixFormula.charAt(i));
							
						}
						else if (infixFormula.charAt(i) == ')') {
							
							// get all from stack until open bracket found
							while (rStack.getFirst() != '(') {
								Character c = rStack.remove();
								if (c != '(') {
									
									// add operator to queue only if 
									// it is not a parenthesis
									rQueue.add(c);
								}
							}
							
							if (rStack.getFirst() == '(') {
								rStack.remove();
							}
							
						}
						// check if operator is higher than the one on the stack
						else if (isHigher(infixFormula.charAt(i), rStack.getFirst())) {
							
							rStack.add(infixFormula.charAt(i));
						}
						else {
							
							Character c = rStack.remove();
							
							// add operator to queue only if 
							// it is not a parenthesis
							rQueue.add(c);

							// push new operator onto stack
							rStack.add(infixFormula.charAt(i));
						}
					} catch (EmptyException e) {
						
						e.printStackTrace();
					}

				}
				else {
 					
					rStack.add(infixFormula.charAt(i));
				}

			}
		}
		
		Iterator iter;
		
		iter = rQueue.charList.iterator();
		while(iter.hasNext()) {
		  ret += iter.next().toString();
		}
		
		// add special key for seperating last numbers
		if (isNumber(ret.charAt(ret.length()-1))) ret += "#";
		
		iter = rStack.charList.iterator();
		while(iter.hasNext()) {
			
			String s = iter.next().toString();
			
			// if stack contains bracket something is wrong ...
			if ( s.equals("(") || s.equals(")")) throw new FormulaFormatException("");
			
			ret += s.toString();
		}
		
		return ret;
	}
	
	public static double evaluateRPN(String RPNformula) throws FormulaFormatException {
		
		Vector results = new Vector();
		
		double n1 = 0, 
			   n2 = 0,
			   result = 0;
		
		String z1 = "";
		
		for (int i = 0; i < RPNformula.length(); i++) {
			
			if (isNumber(RPNformula.charAt(i))) {
				// if no special key build number
				z1 += RPNformula.charAt(i);				
			}
			else if ( String.valueOf(RPNformula.charAt(i)).equals("#") ) {
					// push into results				
					results.add(0,z1);
					z1 = "";
			} 
			else {				
				
				try {
					n2 = Double.parseDouble(results.remove(0).toString());
					n1 = Double.parseDouble(results.remove(0).toString());
				}
				catch (Exception ex) {
					
					throw new FormulaFormatException("");
				}
				
				switch (RPNformula.charAt(i)) {
				case '+':
					result = n1 + n2;
					break;
				case '-':
					result = n1 - n2;
					break;
				case '*':
					result = n1 * n2;
					break;
				case '/':
					result = n1 / n2;
					break;
				case '^':
					result = Math.pow(n1, n2);
					break;
				default:
					break;
				}
				
				//push result back
				results.add(0,result);	
			}
		}
		return Double.parseDouble(results.get(0).toString());
	}

}
