var stack = new Array();
stack[0] = 0;
stack[1] = 0;
stack[2] = 0;
stack[3] = 0;

var store = new Array();
store[0] = 0.0;
store[1] = 0.0;
store[2] = 0.0;
store[3] = 0.0;
store[4] = 0.0;
store[5] = 0.0;
store[6] = 0.0;
store[7] = 0.0;
store[8] = 0.0;
store[9] = 0.0;
store[10] = 0.0;
store[11] = 0.0;
store[12] = 0.0;
store[13] = 0.0;
store[14] = 0.0;
store[15] = 0.0;
store[16] = 0.0;
store[17] = 0.0;
store[18] = 0.0;
store[19] = 0.0;
store[20] = 0.0;
store[21] = 0.0;
store[22] = 0.0;
store[23] = 0.0;
store[24] = 0.0;
store[25] = 0.0;

var decimalDivisors = new Array( // up to 1E15
1,
2,
4,
5,
8,
10,
16,
20,
25,
32,
40,
50,
64,
80,
100,
125,
128,
160,
200,
250,
256,
320,
400,
500,
512,
625,
640,
800,
1000,
1024,
1250,
1280,
1600,
2000,
2048,
2500,
2560,
3125,
3200,
4000,
5000,
5120,
6250,
6400,
8000,
10000,
10240,
12500,
12800,
15625,
16000,
20000,
25000,
25600,
31250,
32000,
40000,
50000,
51200,
62500,
64000,
78125,
80000,
100000,
125000,
128000,
156250,
160000,
200000,
250000,
256000,
312500,
320000,
390625,
400000,
500000,
625000,
640000,
781250,
800000,
1000000,
1250000,
1280000,
1562500,
1600000,
1953125,
2000000,
2500000,
3125000,
3200000,
3906250,
4000000,
5000000,
6250000,
6400000,
7812500,
8000000,
12500000,
16000000,
31250000,
32000000,
62500000,
80000000,
125000000,
128000000,
156250000,
160000000,
200000000,
250000000,
256000000,
312500000,
320000000,
400000000,
500000000,
512000000,
625000000,
640000000,
781250000,
800000000,
1000000000,
1250000000,
1280000000,
1562500000,
1600000000,
2000000000,
2500000000,
2560000000,
3125000000,
3200000000,
3906250000,
4000000000,
5000000000,
6250000000,
6400000000,
7812500000,
8000000000,
10000000000,
12500000000,
12800000000,
15625000000,
16000000000,
19531250000,
20000000000,
25000000000,
31250000000,
32000000000,
39062500000,
40000000000,
50000000000,
62500000000,
64000000000,
78125000000,
80000000000,
97656250000,
100000000000,
125000000000,
156250000000,
160000000000,
195312500000,
200000000000,
250000000000,
312500000000,
320000000000,
390625000000,
400000000000,
488281250000,
500000000000,
625000000000,
781250000000,
800000000000,
976562500000,
1000000000000,
1250000000000,
1562500000000,
1600000000000,
1953125000000,
2000000000000,
2500000000000,
3125000000000,
3906250000000,
4000000000000,
5000000000000,
6250000000000,
7812500000000,
8000000000000,
10000000000000,
12500000000000,
15625000000000,
20000000000000,
25000000000000,
31250000000000,
40000000000000,
50000000000000,
62500000000000,
100000000000000,
125000000000000,
200000000000000,
250000000000000,
500000000000000,
1000000000000000
);

var newStack = 1;
var fn = '';
var mod = 0; //0 = none, 1 = white, 2 = orange, 3 = blue
var fix = 4; //decimal precision
var fdisp = 0;

function setMod(modTemp) {
    if (mod == modTemp) {
        modTemp = 0;
    }
    mod = modTemp;
    document.getElementById('mod1').style.visibility='collapse';
    document.getElementById('mod2').style.visibility='collapse';
    switch (mod) {
        case 1:
            document.getElementById('mod1').style.visibility='visible';
            break;
        case 2:
            document.getElementById('mod2').style.visibility='visible';
            break;
    }
}

function setFn(fnTemp) {
    fn = fnTemp;
}

function doFn(n) {
    eval(fn+'('+n+')');
}

function number(n) {
    if (newStack) {
        document.getElementById('display').value = n;
        newStack = 0;
    } else {
        document.getElementById('display').value = document.getElementById('display').value + n;
    }
}

function point() {
    if (newStack) {
        document.getElementById('display').value = '0.';
        newStack = 0;
    } else if ((document.getElementById('display').value.indexOf('.') == -1) && (document.getElementById('display').value.indexOf(' ') == -1)) {
        document.getElementById('display').value += '.';
    } else if (document.getElementById('display').value.indexOf('/') == -1) {
        document.getElementById('display').value = document.getElementById('display').value.replace('.', ' ');
        document.getElementById('display').value += '/';
    }
}

function pushStack() { 
    stack[3] = stack[2];
    stack[2] = stack[1];
    stack[1] = stack[0];
    newStack = 1;
}

function showStack0() {
    if (fdisp) {
        var gz = Math.floor(stack[0]);
        if (gz < stack[0]) {
            var tz = Math.floor((stack[0]+'0001') * 10000 - gz * 10000); // allow 1/9999
            var i=0;
            while (tz / decimalDivisors[i] >= 1.0) {
                if (tz / decimalDivisors[i] == Math.floor(tz / decimalDivisors[i])) {
                    teiler = decimalDivisors[i];
                }
                i++;
            }
            document.getElementById('display').value = gz+' '+tz/teiler+'/'+10000/teiler;
        } else {
            document.getElementById('display').value = gz;
        }
    } else {
        document.getElementById('display').value = stack[0].toFixed(fix);
    }
}



// Button 0
function opSqare() {
    enter();
    stack[0] = Math.pow(stack[0], 2.0);
    showStack0();
}

function opSqrt() {
    enter();
    stack[0] = Math.sqrt(stack[0]);
    showStack0();
}



// Button 1
function opExp() {
    enter();
    stack[0] = Math.exp(stack[0]);
    showStack0();
}

function opTenPow() {
    enter();
    stack[0] = Math.pow(10, stack[0]);
    showStack0();
}



// Button 2
function opLN() {
    enter();
    stack[0] = Math.log(stack[0]);
    showStack0();
}
function opLOG() {
    enter();
    stack[0] = Math.log(stack[0]) / Math.log(10.0);
    showStack0();
}



// Button 3
function opPow() {
    enter();
    stack[0] = Math.pow(stack[0], stack[1]);
    showStack0();
}
function opXRoot() {
    enter();
    stack[0] = Math.pow(stack[1], 1.0/stack[0]);
    showStack0();
}



// Button 4
function opFaculty() {
    enter();
    var f = 1;
    for (var i = 1; i<=stack[0]; i++) {
        f = f*i;
    }
    stack[0] = f;
    showStack0();
}

function opOneOver() {
    enter();
    stack[0] = 1 / stack[1];
    showStack0();
}



// Button 6
function opSto(n) {
    setFn('sto');
    setMod(3);
    enter();
    document.getElementById('display').value = "STO _";
    document.getElementById('modA2Z').style.visibility='visible';
}
function sto(n) {
    store[n] = stack[0];
    document.getElementById('modA2Z').style.visibility='collapse';
    showStack0();
    setMod(0);
}



// Button 7
function opRcl(n) {
    setFn('rcl');
    setMod(3);
    enter();
    document.getElementById('display').value = "RCL _";
    document.getElementById('modA2Z').style.visibility='visible';
}
function rcl(n) {
    document.getElementById('display').value = (store[n]).toFixed(fix);
    document.getElementById('modA2Z').style.visibility='collapse';
    setMod(0);
}



// Button 8
function stackDown() {
    temp = stack[0];
    stack[0] = stack[1];
    stack[1] = stack[2];
    stack[2] = stack[3];
    stack[3] = temp;
    showStack0();
}

function stackUp() {
    temp = stack[3];
    stack[3] = stack[2];
    stack[2] = stack[1];
    stack[1] = stack[0];
    stack[0] = temp;
    showStack0();
}



// Button 9
function opASin() {
    enter();
    stack[0] = Math.asin(stack[0]);
    showStack0();
}

function showPi() {
    enter();
    stack[0] = Math.PI;
    showStack0();
}

function opSin() {
    enter();
    stack[0] = Math.sin(stack[0]);
    showStack0();
}



// Button 10
function opACos() {
    enter();
    stack[0] = Math.acos(stack[0]);
    showStack0();
}

function opPercent() {
    enter();
    stack[0] = stack[1] * 0.01 * stack[0];
    showStack0();
}

function opCos() {
    enter();
    stack[0] = Math.cos(stack[0]);
    showStack0();
}



// Button 11
function opATan() {
    enter();
    stack[0] = Math.atan(stack[0]);
    showStack0();
}

function opPercentChange() {
    enter();
    stack[0] = stack[1] * 0.01 / (stack[0] - stack[1]);
    showStack0();
}

function opTan() {
    enter();
    stack[0] = Math.tan(stack[0]);
    showStack0();
}



// Button 12
function showAlldigits() {
    document.getElementById('display').value = stack[0];
}

function enter() {
    pushStack();
    
    if (document.getElementById('display').value.indexOf("/") == -1) {
        stack[0] = Number(document.getElementById('display').value);
    } else {
        var nennerStart = document.getElementById('display').value.indexOf(" ");
        var zaehlerStart = document.getElementById('display').value.indexOf("/");
        var gz = Number(document.getElementById('display').value.substring(0,nennerStart));
        var nz = Number(document.getElementById('display').value.substring(nennerStart+1,zaehlerStart));
        var tz = Number(document.getElementById('display').value.substr(zaehlerStart+1,4));
        stack[0] = gz+nz/tz;
    }
    showStack0();
}



// Button 13
function opMax() {
    enter();
    stack[0] = Math.max(stack[0], stack[1]);
    showStack0();
}



// Button 14
function opSwitchSign() {
    enter();
    stack[0] = stack[0] * -1.0;
    showStack0();
}



// Button 15
function opE() {
    if (document.getElementById('display').value.indexOf("/") == -1) {
        if (Number(document.getElementById('display').value) == 0.0) {
            document.getElementById('display').value = "1E";
        } else {
            document.getElementById('display').value = document.getElementById('display').value + "E";
        }
    }
}



// Button 16
function backspace() {
    if (!newStack) {
        if(document.getElementById('display').value.length > 1) {
            if (document.getElementById('display').value.charAt(document.getElementById('display').value.length-1) == '/') {
                document.getElementById('display').value = document.getElementById('display').value.replace(' ', '.');
            }
            document.getElementById('display').value = document.getElementById('display').value.substr(0,document.getElementById('display').value.length - 1);
        } else {
            document.getElementById('display').value = (0).toFixed(fix);
            newStack = 1;
        }
    } else {
        document.getElementById('display').value = (0).toFixed(fix);
        newStack = 1;
    }
}



// Button 21
function opDivide() {
    enter();
    stack[0] = stack[1] / stack[0];
    showStack0();
}



// Button 24
function opToHour() {
    enter();
    stack[0] = Math.floor(stack[0]) + (stack[0] - Math.floor(stack[0])) / 0.6;
    showStack0();
}

function opToHoursAndMinutes() {
    enter();
    stack[0] = Math.floor(stack[0]) + (stack[0] - Math.floor(stack[0])) * 0.6;
    showStack0();
}



// Button 25
function opToDeg() {
    enter();
    stack[0] = stack[0] * 180.0/Math.PI;
    showStack0();
}

function opToRad() {
    enter();
    stack[0] = stack[0] * Math.PI/180.0;
    showStack0();
}



// Button 26
function opMultiply() {
    enter();
    stack[0] = stack[1] * stack[0];
    showStack0();
}



// Button 28
function opToKg() {
    enter();
    stack[0] = stack[0] * 0.45359237;
    showStack0();
}

function opToLb() {
    enter();
    stack[0] = stack[0] / 0.45359237;
    showStack0();
}



// Button 29
function opToGC() {
    enter();
    stack[0] = (stack[0] -32) / 1.8;
    showStack0();
}

function opToGF() {
    enter();
    stack[0] = stack[0] * 1.8 + 32;
    showStack0();
}



// Button 30
function opToCm() {
    enter();
    stack[0] = stack[0] * 2.54;
    showStack0();
}

function opToIn() {
    enter();
    stack[0] = stack[0] / 2.54;
    showStack0();
}



// Button 31
function opToL() {
    enter();
    stack[0] = stack[0] * 3.785411784;
    showStack0();
}

function opToGal() {
    enter();
    stack[0] = stack[0] / 3.785411784;
    showStack0();
}

function opSub() {
    enter();
    stack[0] = stack[1] - stack[0];
    showStack0();
}



// Button 32
function doClear() {
    document.getElementById('display').value = (0).toFixed(fix);
    newStack = 1;
}



// Button 34
function toggleFdisp() {
    enter();
    if (fdisp) {
        fdisp = 0;
    } else {
        fdisp = 1;
    }
    showStack0();
}



// Button 36
function opAdd() {
    enter();
    stack[0] = stack[1] + stack[0];
    showStack0();
}



function notImplemented(message) {
    alert("Sorry! "+message+": Function not implemented.");
}




// Key pressed
function buttonUp(key) {
    // add a delay for iPhone/iTouch
    setTimeout(function(){document.getElementById('touch').style.top='-1000px';}, 500);
}

function keyPressed(key) {

    //move visiblefeedback
    if (key==12) {
        document.getElementById('touch').style.left=Number(document.getElementById('b'+key).style.left.replace(/px/i,""))+3+'px';
    } else {
        document.getElementById('touch').style.left=Number(document.getElementById('b'+key).style.left.replace(/px/i,""))-20+'px';
    }
    document.getElementById('touch').style.top=Number(document.getElementById('b'+key).style.top.replace(/px/i,""))-27+'px';

    tmod = mod;
    setMod(0);

    switch (key) {
      case 0:
        switch (tmod) {
            case 1: // square
                opSqare();
                break;
            case 2: // PARTS
                notImplemented('PARTS');
                break;
            case 3: // A
                doFn(0);
                break;
            default: //SquareRoot
                opSqrt();
                break;
        }
        break;
      case 1:
        switch (tmod) {
            case 1: // 10 power X
                opTenPow();
                break;
            case 2: // PROB
                notImplemented('PROB');
                break;
            case 3: // B
                doFn(1);
                break;
            default: //e power X
                opExp();
                break;
        }
        break;
      case 2:
        switch (tmod) {
            case 1: // LOG
                opLOG();
                break;
            case 2: // L.R.
                notImplemented('L.R.');
                break;
            case 3: // C
                doFn(2);
                break;
            default: //LN
                opLN();
                break;
        }
        break;
      case 3:
        switch (tmod) {
            case 1: // x root y
                opXRoot();
                break;
            case 2: // X Y
                notImplemented('X Y');
                break;
            case 3: // D
                doFn(3);
                break;
            default: //Y power X
                opPow();
                break;
        }
        break;
      case 4:
        switch (tmod) {
            case 1: // X!
                opFaculty();
                break;
            case 2: // s,o
                notImplemented('s,o');
                break;
            case 3: // E
                doFn(4);
                break;
            default: // 1/X
                opOneOver();
                break;
        }
        break;
      case 5:
        switch (tmod) {
            case 1: // E-
                notImplemented('SUM-');
                break;
            case 2: // SUMS
                notImplemented('SUMS');
                break;
            case 3: // F
                doFn(5);
                break;
            default: // E+
                notImplemented('SUM+');
                break;
        }
        break;
      case 6:
        switch (tmod) {
            case 1: // CMPLX
                notImplemented('CMPLX');
                break;
            case 2: // EQN
                notImplemented('EQN');
                break;
            case 3: // G
                doFn(6);
                break;
            default: // STO
                opSto();
                break;
        }
        break;
      case 7:
        switch (tmod) {
            case 1: // RND
                notImplemented('RND');
                break;
            case 2: // SCRL
                notImplemented('SCRL');
                break;
            case 3: // H
                doFn(7);
                break;
            default: // RCL
                opRcl();
                break;
        }
        break;
      case 8:
        switch (tmod) {
            case 1: // HYP
                notImplemented('HYP');
                break;
            case 2: // R up
                stackUp();
                break;
            case 3: // I
                doFn(8);
                break;
            default: // R down
                stackDown();
                break;
        }
        break;
      case 9:
        switch (tmod) {
            case 1: // ASIN
                opASin();
                break;
            case 2: // PI
                showPi();
                break;
            case 3: // J
                doFn(9);
                break;
            default: // SIN
                opSin();
                break;
        }
        break;
      case 10:
        switch (tmod) {
            case 1: // ACOS
                opACos();
                break;
            case 2: // %
                opPercent();
                break;
            case 3: // K
                doFn(10);
                break;
            default: // COS
                opCos();
                break;
        }
        break;
      case 11:
        switch (tmod) {
            case 1: // ACOS
                opATan();
                break;
            case 2: // %CHG
                opPercentChange();
                break;
            case 3: // L
                doFn(11);
                break;
            default: // TAN
                opTan();
                break;
        }
        break;
      case 12:
        switch (tmod) {
            case 1: // LAST X
                notImplemented('LAST X');
                break;
            case 2: // SHOW
                showAlldigits();
                break;
            case 3: // M
                doFn(12);
                break;
            default: // ENTER
                enter();
                break;
        }
        break;
      case 13:
        switch (tmod) {
            case 1: // MEM
                notImplemented('MEM');
                break;
            case 2: // X<>
                notImplemented('X<>');
                break;
            case 3: // N
                doFn(13);
                break;
            default: // X <> Y
                opMax();
                break;
        }
        break;
      case 14:
        switch (tmod) {
            case 1: // MODES
                notImplemented('MODES');
                break;
            case 2: // (
                notImplemented('(');
                break;
            case 3: // O
                doFn(14);
                break;
            default: // +/-
                opSwitchSign();
                break;
        }
        break;
      case 15:
        switch (tmod) {
            case 1: // DISP
                notImplemented('DISP');
                break;
            case 2: // )
                notImplemented(')');
                break;
            case 3: // P
                doFn(15);
                break;
            default: // E
                opE();
                break;
        }
        break;
      case 16:
        switch (tmod) {
            case 1: // CLEAR
                notImplemented('CLEAR');
                break;
            case 2: // =
                notImplemented('=');
                break;
            case 3: // emtpy
                break;
            default: // backspace
                backspace();
                break;
        }
        break;
      case 17:
        switch (tmod) {
            case 1: // GTO
                notImplemented('GTO');
                break;
            case 2: // FN=
                notImplemented('FN=');
                break;
            case 3: // emtpy
                break;
            default: // XEQ
                notImplemented('XEQ');
                break;
        }
        break;
      case 18:
        switch (tmod) {
            case 1: // DOWN
                notImplemented('DOWN');
                break;
            case 2: // SOLVE
                notImplemented('SOLVE');
                break;
            case 3: // Q
                doFn(16);
                break;
            default: // 7
                number(7);
                break;
        }
        break;
      case 19:
        switch (tmod) {
            case 1: // UP
                notImplemented('UP');
                break;
            case 2: // S (integral)
                notImplemented('Integral');
                break;
            case 3: // R
                doFn(17);
                break;
            default: // 8
                number(8);
                break;
        }
        break;
      case 20:
        switch (tmod) {
            case 1: // ISG
                notImplemented('ISG');
                break;
            case 2: // DSE
                notImplemented('DSE');
                break;
            case 3: // S
                doFn(18);
                break;
            default: // 9
                number(9);
                break;
        }
        break;
      case 21:
        switch (tmod) {
            case 1: // x?y
                notImplemented('x?y');
                break;
            case 2: // x?0
                notImplemented('x?0');
                break;
            case 3: // empty
                break;
            default: // /
                opDivide();
                break;
        }
        break;
      case 22:
        switch (tmod) {
            case 1: // empty
                break;
            case 2: // empty
                break;
            case 3: // empty
                break;
            default: // Orange (mod1)
                setMod(1);
                break;
        }
        break;
      case 23:
        switch (tmod) {
            case 1: // -> 0,r
                notImplemented('-> 0,r');
                break;
            case 2: // ->y,x
                notImplemented('->y,x');
                break;
            case 3: // T
                doFn(21);
                break;
            default: // 4
                number(4);
                break;
        }
        break;
      case 24:
        switch (tmod) {
            case 1: // ->HR
                opToHours();
                break;
            case 2: // ->HMS
                opToHoursAndMinutes();
                break;
            case 3: // U
                doFn(22);
                break;
            default: // 5
                number(5);
                break;
        }
        break;
      case 25:
        switch (tmod) {
            case 1: // ->DEG
                opToDeg();
                break;
            case 2: // ->RAD
                opToRad();
                break;
            case 3: // V
                doFn(23);
                break;
            default: // 6
                number(6);
                break;
        }
        break;
      case 26:
        switch (tmod) {
            case 1: // BASE
                notImplemented('BASE');
                break;
            case 2: // FLAGS
                notImplemented('FLAGS');
                break;
            case 3: // empty
                break;
            default: // 6
                opMultiply(6);
                break;
        }
        break;
      case 27:
        switch (tmod) {
            case 1: // empty
                break;
            case 2: // empty
                break;
            case 3: // empty
                break;
            default: // Blue (mod2)
                setMod(2);
                break;
        }
        break;
      case 28:
        switch (tmod) {
            case 1: // ->kg
                opToKg();
                break;
            case 2: // ->lb
                opToLb();
                break;
            case 3: // W
                doFn(24);
                break;
            default: // 1
                number(1);
                break;
        }
        break;
      case 29:
        switch (tmod) {
            case 1: // ->°C
                opToGC();
                break;
            case 2: // ->°F
                opToGF();
                break;
            case 3: // X
                doFn(25);
                break;
            default: // 2
                number(2);
                break;
        }
        break;
      case 30:
        switch (tmod) {
            case 1: // ->cm
                opToCm();
                break;
            case 2: // ->in
                opToIn();
                break;
            case 3: // Y
                doFn(26);
                break;
            default: // 3
                number(3);
                break;
        }
        break;
      case 31:
        switch (tmod) {
            case 1: // ->l
                opToL();
                break;
            case 2: // ->gal
                opToGal();
                break;
            case 3: // empty
                break;
            default: // 1
                opSub();
                break;
        }
        break;
      case 32:
        switch (tmod) {
            case 1: // OFF
                notImplemented('OFF');
                break;
            case 2: // empty
                break;
            case 3: // empty
                break;
            default: // C
                doClear();
                break;
        }
        break;
      case 33:
        switch (tmod) {
            case 1: // INPUT
                notImplemented('INPUT');
                break;
            case 2: // VIEW
                notImplemented('VIEW');
                break;
            case 3: // Z
                doFn(25);
                break;
            default: // 0
                number(0);
                break;
        }
        break;
      case 34:
        switch (tmod) {
            case 1: // FDISP
                toggleFdisp();
                break;
            case 2: // /c
                notImplemented('/c');
                break;
            case 3: // i
                notImplemented('i');
                break;
            default: // .
                point();
                break;
        }
        break;
      case 35:
        switch (tmod) {
            case 1: // PRGM
                notImplemented('PRGM');
                break;
            case 2: // PSE
                notImplemented('PSE');
                break;
            case 3: // Space
                notImplemented('SPACE');
                break;
            default: // R/S
                notImplemented('R/S');
                break;
        }
        break;
      case 36:
        switch (tmod) {
            case 1: // LBL
                notImplemented('LBL');
                break;
            case 2: // RTN
                notImplemented('RTN');
                break;
            case 3: // empty
                break;
            default: // +
                opAdd();
                break;
        }
        break;
      default:
        alert("ERROR");
        break;
    }
}

function updateOrientation() {
//  window.orientation
    setTimeout(function(){window.scrollTo(0, 1);}, 50);
}