// ==UserScript==
// @name          IRAD Calculator
// @namespace     http://www.toadking.com/irad
// @description	  props to all my YOSPOS homies
// @include       *
// ==/UserScript==
var div = document.createElement("div");
div.id = "rpnbox";
div.style.cssText = "position: fixed; z-index: 99999; top: 5px; left: 5px; background-color: white; background-color: rgba(255, 255, 255, 0.8); border: 1px black solid; width: 210px; padding: 2px; display: none;";
var img = document.createElement("img");
img.src = "data:image/gif;base64," +
"R0lGODlhCwALAPcAAICAgP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
"ACwAAAAACwALAAAIKwADCBxIUCCAgwgRGiy4MAAAhwMfPoQIcaLFiBgpSmy4ceFFhhYTJmTIMCAAOw==";
img.style.cssText = "cursor: pointer; float: right";
img.addEventListener("click", RPNShowHide, false);
div.appendChild(img);
var input = document.createElement("input");
input.type = "text";
input.id = "rpninput";
input.style.width = "160px";
input.addEventListener("change", RPNDatShit, false);
div.appendChild(input);
div.appendChild(document.createElement("br"));
var span = document.createElement("span");
span.id = "rpndisplay";
span.textContent = "Type RPN formula";
div.appendChild(span);
document.body.appendChild(div);
document.addEventListener("keypress", RPNShowHide, false);

function RPNShowHide(e)
{
	if (e.type == "keypress" && !(String.fromCharCode(e.which).toLowerCase() == "r" && e.altKey && !e.ctrlKey && !e.shiftKey))
		return;
	
	e.preventDefault();
	if (document.getElementById("rpnbox").style.display == "none")
		document.getElementById("rpnbox").style.display = "block";
	else
		document.getElementById("rpnbox").style.display = "none";
}

function RPNDatShit(e)
{
	document.getElementById("rpndisplay").textContent = (function(){
		var stack = new Array();
		var input = (document.getElementById("rpninput").value + " ").split(" ");

		while (input.length) {
			var curr = input.shift().toLowerCase();

			if (curr == "" || input.length == 0)
				continue;

			if (/^-?[0-9]+(\.[0-9]+)?$/.exec(curr)) {
				stack.push(curr);
				continue;
			}

			try {
				switch (curr) {
					case "+":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop() * 1;
						stack[stack.length - 1] = (stack[stack.length - 1] * 1) + tmp;
						break;

					case "-":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop() * 1;
						stack[stack.length - 1] = (stack[stack.length - 1] * 1) - tmp;
						break;

					case "*":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop() * 1;
						stack[stack.length - 1] = (stack[stack.length - 1] * 1) * tmp;
						break;

					case "/":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop() * 1;
						stack[stack.length - 1] = (stack[stack.length - 1] * 1) / tmp;
						break;

					case "%":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop() * 1;
						stack[stack.length - 1] = (stack[stack.length - 1] * 1) % tmp;
						break;

					case "sq":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.pow(stack[stack.length - 1], 2);
						break;

					case "^":
					case "**":
					case "pow":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop();
						stack[stack.length - 1] = Math.pow(stack[stack.length - 1], tmp);
						break;

					case "abs":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.abs(stack[stack.length - 1]);
						break;

					case "acos":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.acos(stack[stack.length - 1]);
						break;

					case "asin":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.asin(stack[stack.length - 1]);
						break;

					case "atan":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.atan(stack[stack.length - 1]);
						break;

					case "atan2":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop();
						stack[stack.length - 1] = Math.atan2(stack[stack.length - 1], tmp);
						break;

					case "ceil":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.ceil(stack[stack.length - 1]);
						break;

					case "cos":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.cos(stack[stack.length - 1]);
						break;

					case "exp":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.exp(stack[stack.length - 1]);
						break;

					case "floor":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.floor(stack[stack.length - 1]);
						break;

					case "log":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.log(stack[stack.length - 1]);
						break;

					case "max":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop();
						stack[stack.length - 1] = Math.max(stack[stack.length - 1], tmp);
						break;

					case "min":
						if (stack.length < 2)
							return "Operator (" + curr + ") argument error!";

						var tmp = stack.pop();
						stack[stack.length - 1] = Math.min(stack[stack.length - 1], tmp);
						break;

					case "round":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.round(stack[stack.length - 1]);
						break;

					case "sin":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.sin(stack[stack.length - 1]);
						break;

					case "sqrt":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.sqrt(stack[stack.length - 1]);
						break;

					case "tan":
						if (stack.length < 1)
							return "Operator (" + curr + ") argument error!";

						stack[stack.length - 1] = Math.tan(stack[stack.length - 1]);
						break;

					default:
						return "Unknown operator \"" + curr + "\"!";
				}
			} catch(e) {
				return "Operator (" + curr + ") error!";
			}
		}
		
		if (!stack || stack.length == 0)
			return "Type RPN formula";
		else if (stack.length != 1)
			return "Stack error!";
		else
			return stack[0];
	})();
}
