// This file contains code in connection with the WMI2 calculator

var ifv = new String("..#");	// variables in connection with the
var ifv_bak = false;		// input field value
var ifvs = new Array();
ifvs.push(ifv);
var ifvprev = 0;
var ifvlast = 0;

var cinput = "calcin";		// in which div...
var buttons;		// array of 40				from ajax
var groupby;		// how many elements in a row		from ajax
var groupcount;		// how many elements altogether		from ajax
var group;		// array of group			from ajax
var grouplock = false;  // if true, no group-loader ajax call can be done
var grouplock2 = false; // if true, group-loader ajax calls have no effect
var timer;		// for display/destroy group
var groupindisplay = -1;// which of 40 for d/d group
var buttoncolor;
var buttonbackground;
var introtext;	// this text comes from database when a new layout loads
var language;
var theinputispink = false;
var wmibear = false;
var worksheetnew = 1;
var lastaction = "button"; // "button"/"key"

// This function counts the parameters of a maxima button from its changestring
function maximaparams(changestring)
{    
    var cs = changestring;
    var cs_l = cs.length;
    var cs_c = 0;
    
    if (cs.indexOf('[#]') != -1)
    {
	return 'list';
    }
    
    var cs_i = cs.indexOf('#');
    while (cs_i != -1)
    {
	cs_c++;
	if (cs_i+1 < cs_l) {
	    cs_i = cs.indexOf('#',cs_i+1);
	} else {
	    cs_i = -1;
	}
    }
    return cs_c;
}

// This function counts the input parameters (','s which are not between [])
function calcparams(ifield)
{
    var opening = 0;
    var commas = 0;
    var inputf = ifield;
    for (lv = 0; lv < inputf.length; lv++)
    {
	switch (inputf[lv])
	{
	    case '[':
		opening++;
		break;
	    case ']':
		if (opening > 0) {
		    opening--;
		} else {
		    return -1;
		}
		break;
	    case ',':
		if (opening == 0) {
		    commas++;
		}
		break;
	    default:
		break;
	}
    }
    return commas+1;
}

// FIXME: is it necessary?
function phperror(message)
{
    var errordiv = document.createElement("div");
    var messagenode = document.createTextNode(message);
    errordiv.appendChild(messagenode);
}

// This function returns true if a character is a digit
function isDigit(character)
{
    if ((character >= "0")&&(character <= "9")) 
    { 
	return true;
    } else { 
	return false;
    }
}

// FIXME: is it necessary?
function mathML()
{
    var converted_value = hideValue(ifv);
    converted_value = converted_value.replace("_","");
    document.getElementById("codiv"+worksheetnew).innerHTML = "`"+converted_value+"`";
    AMtranslated = false;
    AMnoMathML = false;
    mathcolor = "";
    translate();
}

// Because of network communication, and formconv compatibility
// the value should be coded before sent to the server
function codeValue(value)
{
    value = value.replace(".|",".0");
    value = value.replace("|","");
    value = value.replace(/\.\./g," aa ");
    if (value.indexOf("aa") == -1) {
        value = value.replace("#"," bb ");
    }
    value = value.replace(/#/g,"");
    value = escape(value);
    value = value.replace(/\+/g,"%2B");
    return value;
}

// Maxima operations should be coded, too, for the network communication
function codeOperation(operation)
{	// FIXME: can this be replaced by escapeValue
    operation = escape(operation);
    operation = operation.replace(/\+/g,"%2B");
    return operation;
}

// A general function to escape a value for the network communication
function escapeValue(value)
{
    value = escape(value);
    value = value.replace(/\+/g,"%2B");
    return value;
}

// Some parts of the formula string should not be seen on the screen
function hideValue(value)
{
    value = value.replace(".|",".0");
    value = value.replace("|","");
    value = value.replace(/\.\.#/g,"..");
    value = value.replace(/#$/,"");
    value = value.replace(/#/g,"_");
    return value;
}

// FIXME: is it necessary?
function loadModule(modulename)
{
    ajaxHTML("workspace","module="+modulename);
}

// This function is called on the calculator erase button (ce)
function eraseInput()
{
    ifv = new String("..#");
    ifvprev = 0;
    ifvlast = 0;
    ifvs[ifvprev] = new String("..#");
    document.getElementById("theinput").value = hideValue(ifv);

    lastaction = "button";
    var converted_value = codeValue(ifv);
//    document.getElementById("codiv"+worksheetnew).innerHTML = "";
    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"true");
//    document.getElementById("codiv"+worksheetnew).scrollIntoView(true);
}

// This function starts a new entry on the worksheet
function newInput()
{
    ifv = new String("..#");
    ifvprev = 0;
    ifvlast = 0;
    ifvs[ifvprev] = new String("..#");
    document.getElementById("theinput").value = hideValue(ifv);

    lastaction = "button";
    worksheetnew++;
    
    ajaxLoadNew(buttons[0][0],worksheetnew);
}

// This function refreshes the input formula (image) on the worksheet
function refreshInput()
{
    document.getElementById("theinput").value = hideValue(ifv);
    lastaction = "button";
    var converted_value = codeValue(ifv);
    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"true");
    document.getElementById("codiv"+worksheetnew).scrollIntoView(true);
    document.getElementById("uidivt"+worksheetnew).innerHTML = ifv;
    document.getElementById("theinput").focus();
}

// This runs when syntactically wrong button is pressed on the calculator
function wrongsyntax()
{
    var fres = function(restext) {
	alert(restext);
    }
    ajaxMessage("calc_wrongbutton",fres);
}

// variables in connection with maxima button pressing
var prevaction = false;
var prevbutton = false;
// This runs when a maxima button is pressed and produces an output formula
function theAction(operation,opbutton)
{
    prevaction = operation;
    prevbutton = opbutton;
    
    var converted_value = codeValue(ifv);
    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"false");
    if (converted_value.indexOf("aa") == -1) {
	var conv_op = codeOperation(operation);
        ajaxLoadImage(worksheetnew,converted_value,150,conv_op,opbutton);
	document.getElementById("codiv"+worksheetnew).scrollIntoView(true);
        newInput();
        document.getElementById("theinput").focus();
    } else {
	wrongsyntax();
    }
}

// This funtion starts refreshing the input formula
function theAction2()
{
    ifv = document.getElementById("theinput").value;
    ifvprev++;
    ifvs[ifvprev] = ifv;
    ifvlast = ifvprev;
    refreshInput();
}

// This function runs if an ENTER key is pressed on the calculator input field
function theAction3()
{
    if (prevaction == false)
    {
        if (ongoingrefresh == false && theinputispink == false) {
            var maxpar = maximaparams('ev(#)');
	    if (maxpar == calcparams(hideValue(ifv)) || maxpar == 'list') {
		if (wmibear == true)
		    document.getElementById("topleft").style.backgroundImage = 
			"url(./image/tlbba.png)";
		theAction('ev(#)','ev');
	    } else {
	        if (maxpar == -1) {
		    wrongsyntax();
		} else {
	    	    var funcres = function(restext) {
		        alertcont = restext.replace("[PAR]",maxpar);
			alert(alertcont);
		    }
		    ajaxMessage("calc_params",funcres);
		}
	    }	    
	}
    }
    else
    {
        if (ongoingrefresh == false && theinputispink == false) {
            var maxpar = maximaparams(prevaction);
	    if (maxpar == calcparams(hideValue(ifv)) || maxpar == 'list') {
		if (wmibear == true)
		document.getElementById("topleft").style.backgroundImage = "url(./image/tlbba.png)";
		theAction(prevaction,prevbutton);
	    } else {
	        if (maxpar == -1) {
		    wrongsyntax();
		} else {
	    	    var funcres = function(restext) {
		        alertcont = restext.replace("[PAR]",maxpar);
			alert(alertcont);
		    }
		    ajaxMessage("calc_params",funcres);
		}
	    }
	}
    }
}

// This function refreshes the input formula on the worksheet on a keypress
function refreshInputKey(unicode)
{
    var value = document.getElementById("theinput").value;
    value = value.replace(/\.\./g,"");
    ifv = value;

    if(lastaction == "button") {
      document.getElementById("theinput").value = hideValue(ifv);
    }
    switch (ifv.charAt(ifv.length-1))
    {
    case '+': case '-': case '*': case '/': case '^':
	ifv = ifv+"..#";
    break;
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
	ifv = ifv+"|#";
	break;
    default:
	ifv = ifv+"#";
	break;
    }

    ifvprev++;
    ifvs[ifvprev] = ifv;
    ifvlast = ifvprev;

    lastaction = "key";

    var converted_value = codeValue(ifv);
    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"true");
    document.getElementById("codiv"+worksheetnew).scrollIntoView(true);
    document.getElementById("uidivt"+worksheetnew).innerHTML = ifv;
}

// This function is for creating a button in group div
function groupButton(id,button,label)
{
    var newbutton = document.createElement("a");
    newbutton.setAttribute("class","groupbutton");
    newbutton.setAttribute("className","groupbutton");
    if (groupcount > id) {
        if (group[id][5] != "") {
            newbutton.setAttribute("title",group[id][5]);
        }
    }
    var ds = function(event) {
	    window.defaultStatus = '';
    }
    var nboc = function(event) {
	groupClick(id,button);
    }
    newbutton.onclick = nboc;
    
    var content = document.createElement("div");
    content.setAttribute("class","button");
    content.setAttribute("className","button");
    content.innerHTML = 
    "<font face='Arial, Verdana, sans-serif'>"+
    label
    +"</font>"
    ;
    content.style.cursor = "pointer";
    
    if (id < groupcount) {
        newbutton.style.color = buttoncolor[group[id][2]];
        newbutton.style.backgroundColor = buttonbackground[group[id][2]];
    } else {
	newbutton.style.color = "#00156c";
	newbutton.style.backgroundColor = "#00156c";
    }
    
    newbutton.appendChild(content);
    this.dom = newbutton;
}

// This function is for creating a visible button on the calculator
function calcButton(id)
{
    var newbutton = document.createElement("a");
    newbutton.setAttribute("id","btn"+id);
    newbutton.setAttribute("class","button");
    newbutton.setAttribute("className","button");
    if (buttons[id][5] != "") {
        newbutton.setAttribute("title",buttons[id][5]);
    }
    var ds = function(event) {
	    window.defaultStatus = '';
    }
    newbutton.onmouseover = ds;
    newbutton.onmouseout = ds;
    var nboc = function(event) {
	buttonClick(id);
    }
    newbutton.onclick = nboc;

    var content1 = document.createElement("div");
    if (buttons[id][3] != "") {
	var content2 = document.createElement("div");
        content2.setAttribute("class","buttonimg");
        content2.setAttribute("className","buttonimg");

	var groupimg = document.createElement("img");
	groupimg.setAttribute("id","btnimg"+id);
	groupimg.setAttribute("name","btnimg"+id);
        groupimg.setAttribute("class","group");
        groupimg.setAttribute("className","group");
	groupimg.setAttribute("src","./image/groupsign.gif");
	groupimg.onmouseover = displayGroup;
	groupimg.onmouseout = hideGroup;

	content2.appendChild(groupimg);
	content2.style.cursor = "pointer";
	newbutton.appendChild(content2);
    }
    var content1 = document.createElement("div");    
    content1.setAttribute("class","button");
    content1.setAttribute("className","button");
    content1.innerHTML = 
    "<font face='Arial, Verdana, sans-serif'>"+
    buttons[id][4]
    +"</font>"
    ;
    content1.style.cursor = "pointer";
    newbutton.appendChild(content1);
    
    if (buttons[id][0] != "") {
        newbutton.style.color = buttoncolor[buttons[id][2]];
        newbutton.style.backgroundColor = buttonbackground[buttons[id][2]];
    } else {
        newbutton.style.color = "#00156c";
        newbutton.style.backgroundColor = "#00156c";
    }
    
    newbutton.style.cursor = "pointer";
    this.dom = newbutton;
}

// This function creates a layout HTML (the buttons variable describes it)
function createFirst(indiv)
{
    var calcform = document.createElement("form");
    calcform.setAttribute("id","calcform");
    calcform.setAttribute("name","calcform");
    calcform.setAttribute("action","javascript:theAction3()");

    var theinput = document.createElement("input");
    theinput.setAttribute("class","input");
    theinput.setAttribute("className","input");
    theinput.setAttribute("type","text");
    theinput.setAttribute("id","theinput");
    theinput.setAttribute("name","theinput");
    var tikp = function(ev) {
	ifv_bak = false;
	var eventobj = window.event ? event : ev;
	var unicode = eventobj.charCode ? eventobj.charCode : eventobj.keyCode;
//	var key = String.fromCharCode(unicode);
	switch (unicode)
	{
	case 37:case 38:case 39:case 40:case 13://case 8:
	    break;
	default:
	    refreshInputKey(unicode);
	    break;
	}
    }
    theinput.onkeyup = tikp;
    var alertmy = function(ev) {
	ifv_bak = ifv;
	ifv = ifv.replace(/\.\./g,"");
	ifv = ifv.replace(/#/g,"");
	document.getElementById("theinput").value = hideValue(ifv);
	lastaction = "key";
    }
    theinput.onclick = alertmy;
    calcform.appendChild(theinput);

    var thetable = document.createElement("table");
    thetable.setAttribute("id","thetable");
    thetable.setAttribute("name","thetable");
    thetable.setAttribute("cellPadding","0px");
    thetable.setAttribute("cellSpacing","0px");
    thetable.insertRow(-1);
    thetable.rows[0].insertCell(-1);
    thetable.rows[0].cells[0].setAttribute("colSpan","5");
    thetable.rows[0].cells[0].appendChild(calcform);
    
    for (i = 0; i < 8; i++) {
        thetable.insertRow(-1);
	for (j = 0; j < 5; j++) {
            thetable.rows[i+1].insertCell(-1);	    
            thetable.rows[i+1].cells[j].appendChild(
	    new calcButton(i*5+j).dom);
	}
    }
    document.getElementById(indiv).appendChild(thetable);
    document.getElementById("theinput").value = hideValue(ifv);
}

// variable for the showLayout function
var created = 0;
// This function shows a calculator layout (after it is loaded with images)
function showLayout()
{
    created++;
    if (created == 2) {
	document.getElementById("calcdiv").style.visibility = "visible";
        document.getElementById("theinput").focus();
    }
}

// This function loads a new calculator layout
function loadLayout(indiv)
{
    if (document.getElementById(indiv).hasChildNodes())
    {
	var thetablex = document.getElementById("thetable");
        var remn = document.getElementById(indiv).removeChild(thetablex);
    }
    createFirst(indiv);
    showLayout();
}

// This function hides a calculator layout
function hideLayout()
{
    created = 0;
    document.getElementById("calcdiv").style.visibility = "hidden";
}

// This should decide if a position in ifv is inside a vector or matrix
function invector(position)
{
// FIXME: this function is not written yet!?
    return true;
}

// This function controls the effects of clicks from the 40 visible buttons
// It identifies the button type and/or label, and does the effect
function buttonClick(id)
{
    clearTimeout(timer);
    if (ifv_bak != false) {
	ifv = ifv_bak;
	ifv_bak = false;
    }
    var concat = ifv.indexOf("#");
    var empty = ifv.indexOf("..");
    var cursorplace = ifv.indexOf("|");
    
    var val = document.getElementById("theinput").value;
    if ((concat == -1)&&(empty == -1)) {
        if (val.charAt(val.length-1) == "+" || val.charAt(val.length-1) == "*" ||
	val.charAt(val.length-1) == "-" || val.charAt(val.length-1) == "/" ||
	val.charAt(val.length-1) == "^") {
            ifv = document.getElementById("theinput").value+"..#";
	    concat = ifv.indexOf("#");
	    empty = ifv.indexOf("..");	    
        } else {
            ifv = document.getElementById("theinput").value+"#";
	    concat = ifv.indexOf("#");
	}
    }
        
    var cv;
    switch (buttons[id][2])
    {
    case "maxima":
    case "maple":
    case "mupad":
	break;
    case "gnuplot":
    case "complex":
	break;
    case "relation":
    case "special":
    case "control":
	switch (buttons[id][0])
	{
	case "ce":
	    grouplock = false;
	    grouplock2 = false;
	    ongoingrefresh = false;
	    nextrefresh = false;
	    eraseInput();
	    break;
	case "off":
	    document.getElementById("calcdiv").style.display = "none";
	    document.getElementById("menudiv").style.display = "block";
	    break;
	case "back":
	    if (ifvprev > 0) {
		ifvprev--;
	    }
	    ifv = ifvs[ifvprev];
	    break;
	case "redo":
	    if (ifvprev < ifvlast) {
	        ifvprev++;
	    }
	    ifv = ifvs[ifvprev];
	    break;
	case "solve":
	    break;
	case "eval":
	    break;
	case "cycle":
	    break;
	case "]":
	case ")":
	    if (cursorplace != -1) {
		ifv = ifv.replace("|#","");
	        ifv = ifv.replace("|","");
	    } else if (concat < ifv.length-1) 
	        ifv = ifv.replace("#","");
	    break;
	case "(":
	    if (empty != -1) {
		ifv = ifv.replace("..","(..#)");
	    } else {
		wrongsyntax();
	    }
	    break;
	case "[":
	    if (empty != -1) {
		ifv = ifv.replace("..","[..#]");
	    } else {
		wrongsyntax();
	    }
	    break;
	case "(-)": 
	    if (empty != -1) {
		ifv = ifv.replace("..","(-..)");
	    } else {
		wrongsyntax();
	    }
	    break;
	case ".":
	    if (cursorplace != -1) {
		cv = cursorplace-1;
		while (cv>=0) {
		    if (!isDigit(ifv.charAt(cv))) break;
		    --cv;
		}
		if (((cv < 0)||((ifv.charAt(cv) != ".")&&(ifv.charAt(cv) != "e")))
		    &&(cursorplace-1>cv)) {
		    ifv = ifv.replace("|",".|");
		} else {
		    wrongsyntax();
		}
	    } else {
		wrongsyntax();
	    }
	    break;
	case "EXP":
	    ifv = ifv.replace("|",buttons[id][1]);
	    break;
	case "%":
	    ifv = ifv.replace("|",buttons[id][1]);
	    break;
	case "equality":
	    var commaind = ifv.lastIndexOf(",");
	    var equalind = ifv.lastIndexOf("=");
	    if ((concat == ifv.length-1)&&(empty == -1)&&(commaind >= equalind)) {
		ifv=ifv.replace("#","=..#");
	    } else {
		wrongsyntax();
	    }
	    break;
	case ",":
	    if ((concat == ifv.length-1)&&(empty == -1)) {
	        ifv=ifv.replace("#",",..#");
	    } else if (invector(concat)&&(empty == -1)) {
	        ifv=ifv.replace("#",",..#");
	    } else {
		wrongsyntax();
	    }
	    break;
	default:
	    if (buttons[id][3] == "layout") {
		ajaxLIPreload(buttons[id][0]);
		hideLayout();
		ajaxLoadLayout(buttons[id][0]);
		if (worksheetnew == 1) 
		if (document.getElementById("uidivt"+worksheetnew).innerHTML == "..#")
		{
		    ajaxLayoutMessage(buttons[id][0]);
		    var remv = document.getElementById("uidiv1");
		    document.getElementById("workspace").removeChild(remv);
		    remv = document.getElementById("codiv1");
		    document.getElementById("workspace").removeChild(remv);
		    ajaxLoadNew(buttons[id][0],1);
		    var converted_value = codeValue("..#");
		    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"true");
		}
	    } else if (buttons[id][3] == "lang") {
		ajaxSetLanguage(buttons[id][0]);
	    }
	    break;
	}
        break;
    case "digit":
	if (cursorplace != -1) {
	    ifv = ifv.replace("|",buttons[id][1]);
	} else if (empty != -1) {
	    ifv = ifv.replace("..",buttons[id][1]);
	} else {
	    wrongsyntax();
	}
	break;
    case "fun1":
    case "fun2":
    case "var":
    case "const":
	if (empty != -1) {
	    ifv = ifv.replace("..",buttons[id][1]);
	} else {
	    wrongsyntax();
	}
	break;
    case "op1":
    case "op2":
	if ((concat != -1)&&((empty == -1)||(empty > concat))) {
	    ifv = ifv.replace("#",buttons[id][1]);
	} else {
	    wrongsyntax();
	}
	break;
    case "test":
	ajaxHTML("codiv"+worksheetnew,"ctext="+codeValue(ifv)+"&operation=ev(#)");
	break;
    default:
    //ajaxHTML('codiv'+worksheetnew,'ctext='+codeValue(ifv)); //FIXME
    break;
    }

    if (buttons[id][3] != "layout") {
        // Destroy cursor when digit typing ends
        if ((buttons[id][2] != "digit")&&(buttons[id][2] != "control")&&(buttons[id][0] != ".")&&(buttons[id][0] != "EXP")) {
	    if (!(ongoingrefresh == true && buttons[id][2] == "maxima")) {
            if (ifv.charAt(cursorplace-1) == ".") ifv = ifv.replace("|","0");
	    else ifv = ifv.replace("|","");
	    }
        }
	
	if (buttons[id][2] == "gnuplot") {
	if (ongoingrefresh == false && theinputispink == false) {
	if (buttons[id][0] == "funpl") {
            if (document.getElementById("theinput").value != hideValue(ifv)) {
		theAction2();
            }
	    if (wmibear == true)
            document.getElementById("topleft").style.backgroundImage = "url(./image/tlbba.png)";
	    var converted_value = codeValue(ifv);
	    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"false");
	    if (converted_value.indexOf("aa") == -1) {
                ajaxLoadPlot(worksheetnew,converted_value,-10,10,-10,10,'on','false');
                document.getElementById("codiv"+worksheetnew).scrollIntoView(true);
    		newInput();
	        document.getElementById("theinput").focus();
	    } else {
		wrongsyntax();
	    }
	} else if (buttons[id][0] == "plot3") {
            if (document.getElementById("theinput").value != hideValue(ifv)) {
		theAction2();
            }
	    if (wmibear == true)
            document.getElementById("topleft").style.backgroundImage = "url(./image/tlbba.png)";
	    var converted_value = codeValue(ifv);
	    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"false");
	    if (converted_value.indexOf("aa") == -1) {
                ajaxLoad3DPlot(worksheetnew,converted_value,-10,10,-10,10,'on','false',60,30);
                document.getElementById("codiv"+worksheetnew).scrollIntoView(true);
    		newInput();
	        document.getElementById("theinput").focus();
	    } else {
		wrongsyntax();
	    }
	}
	}
	} else if (buttons[id][2] == "complex") {
	if (ongoingrefresh == false && theinputispink == false) {
	if (buttons[id][0] == "cplot") {
            if (document.getElementById("theinput").value != hideValue(ifv)) {
		theAction2();
            }
	    if (wmibear == true)
            document.getElementById("topleft").style.backgroundImage = "url(./image/tlbba.png)";
	    var converted_value = codeValue(ifv);
	    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"false");
	    if (converted_value.indexOf("aa") == -1) {
//                ajaxLoadCPlot(worksheetnew,converted_value);
                ajaxLoadCPlot(worksheetnew,converted_value,-10,10,-10,10);
                document.getElementById("codiv"+worksheetnew).scrollIntoView(true);
    		newInput();
	        document.getElementById("theinput").focus();
	    } else {
		wrongsyntax();
	    }
	}
	}
    	} else 
	if (buttons[id][2] == "maxima" || buttons[id][2] == "maple" || 
	    buttons[id][2] == "mupad")
        {
	    if (ongoingrefresh == false && theinputispink == false) {
	    var maxpar = maximaparams(buttons[id][1]);
	    if (maxpar == calcparams(hideValue(ifv)) || maxpar == 'list') {
	    if (document.getElementById("theinput").value != hideValue(ifv)) {
		theAction2();
	    }
	    if (wmibear == true)
	    document.getElementById("topleft").style.backgroundImage = "url(./image/tlbba.png)";
	    theAction(buttons[id][1],buttons[id][0]);
	    } else {
		if (maxpar == -1) {
		    wrongsyntax();
		} else {
		    if (buttons[id][6] != '') {
		        alert(buttons[id][6]);
		    } else {
		        var funcres = function(restext) {
			    alertcont = restext.replace("[PAR]",maxpar);
			    alert(alertcont);
			}
			ajaxMessage("calc_params",funcres);
		    }
		}
	    }
	    }
	} else
	if (buttons[id][0] == "back" || buttons[id][0] == "redo") {
	    refreshInput();
	}
	else {
	    if (wmibear == true)
	    document.getElementById("topleft").style.backgroundImage = "url(./image/tlbbq.png)";
	    ifvprev++;
	    ifvs[ifvprev] = ifv;
	    ifvlast = ifvprev;
	    refreshInput();
	}
    }
}

// This function loads the button group of a visible button into a place
function loadGroup(button,cx,cy)
{
    var groupdiv = document.createElement("div");
    groupdiv.setAttribute("id","groupdiv");
    groupdiv.setAttribute("class","groupdiv");
    groupdiv.setAttribute("className","groupdiv");
    groupdiv.onmouseover = displayGroup;
    groupdiv.onmouseout = hideGroup;
    
    var grouptable = document.createElement("table");
    grouptable.setAttribute("id","grouptable");
    grouptable.setAttribute("name","grouptable");
    grouptable.setAttribute("cellPadding","0px");
    grouptable.setAttribute("cellSpacing","0px");
    
    var grouprow, groupcol, count;
    for (count = 0; count < groupcount; count++)
    {
	grouprow = Math.floor(count/groupby);
	groupcol = count%groupby;
	if (count%groupby == 0) grouptable.insertRow(-1);
	grouptable.rows[grouprow].insertCell(-1);
	grouptable.rows[grouprow].cells[groupcol].appendChild(
	new groupButton(count,button,group[count][4]).dom);
    }
    while (count%groupby!=0)
    {
	grouprow = Math.floor(count/groupby);
	groupcol = count%groupby;
	grouptable.rows[grouprow].insertCell(-1);
	grouptable.rows[grouprow].cells[groupcol].appendChild(
	new groupButton(count,button,group[groupcount][4]).dom);
	count++;
    }
    groupdiv.appendChild(grouptable);
    
    var gdwidth = groupby*56+8;
    var gdheight = Math.floor((groupcount+groupby-1)/groupby)*36+8;

    groupdiv.style.top = cy - gdheight;
    groupdiv.style.left = cx;

    document.body.appendChild(groupdiv);
    groupindisplay = button;
}

// This function destroys the div with the button group
function destroyGroup(button)
{
    var grpdiv = document.getElementById("groupdiv");
    document.body.removeChild(grpdiv);
    groupindisplay = -1;
}

// This function controls the effects of clicks from the group buttons
function groupClick(grp,btn)
{
    if (grp < groupcount) {
        buttons[btn] = group[grp];
        destroyGroup(btn);
        document.getElementById("thetable").rows[Math.floor(btn/5)+1].cells[btn%5].removeChild(document.getElementById("btn"+btn));
        document.getElementById("thetable").rows[Math.floor(btn/5)+1].cells[btn%5].appendChild(new calcButton(btn).dom);
        buttonClick(btn);
    }
}

// This tells if a HTML element is an ancestor of an other in the DOM tree
function isin(big,little)
{
try {
    if (little == big) return true;
    while (little.parentNode) {
	little = little.parentNode;
	if (little == big) {
	    return true;
	}
    }
    return false;
} catch (ex) {
    return false;
}
}

// This function is for the timing of the loading of the button group
function loadGroupL(button,cx,cy)
{
    if (grouplock == false) {
	grouplock = true;
	grouplock2 = false;
        ajaxLoadGroup(buttons[button][3],button,cx,cy);
    } else {
    }
}

// This function issues displaying a button group
function displayGroup(event)
{
    var cx,cy,src;
    if (window.event) {
        cx = window.event.clientX - window.event.offsetX;
	cy = window.event.clientY - window.event.offsetY;
	src = window.event.srcElement;
//	window.event.cancelBubble = true;
    } else {
	cx = event.clientX - event.layerX;
	cy = event.clientY - event.layerY;
	src = event.target;
//        event.stopPropagation(true);
    }
    var groupdiv = document.getElementById("groupdiv");
    var button = new String(src.id).substr(6);	// FIXME: src can be div, img !
    if ((groupindisplay == button)||(isin(groupdiv,src))) {
    } else {
        timer = setTimeout("loadGroupL("+button+","+cx+","+cy+")",1000);
    }
}

// This function issues destroying the div with a button group
function hideGroup(event)
{
    var ct, rt;
    if (window.event) {
	ct = this;  // FIXME
	rt = window.event.toElement;
//	window.event.cancelBubble = true;
    } else {
	ct = event.target;
	rt = event.relatedTarget;
//	event.stopPropagation(true);
    }
    var button = -1;
    if (ct.id != "") button = new String(ct.id).substr(6);

    var groupdiv = document.getElementById("groupdiv");
    if (groupindisplay == button) {
	if (!isin(groupdiv,rt)) {
	    destroyGroup(button);
	} else {
	}
    } else if (isin(groupdiv,ct)) {
	if (isin(groupdiv,rt)) {
	} else {
	    var butt = -2;
	    try {
	        if (rt.id != "") butt = new String(rt.id).substr(6);
	    } catch (ex) {
		butt = -2;
	    }
	    if (groupindisplay == butt) {
	    } else {
	        destroyGroup(groupindisplay);
	    }
	}
    } else {
	clearTimeout(timer);
        grouplock2 = true;
    }
}

// This can change the display of intro and WMI2 bear on some conditions
function setwmibear(force,forceto,switching)
{
    var fromcookie;
    var bearcookie;
    if (switching == true) {
	forceto = !wmibear;
    }
    if (force == true) {
	fromcookie = false;
	bearcookie = true;
    } else {
        var start = document.cookie.indexOf("bear");
        if (start != -1) {
	    start += 5;
    	    var end = document.cookie.indexOf(";",start);
    	    var cookiestring = document.cookie.substr(start,end-start);
    	    if (cookiestring == "true") {
    		bearcookie = true;
    		fromcookie = true;
    	    } else if (cookiestring == "false") {
    		bearcookie = false;
    		fromcookie = true;
    	    } else {
		fromcookie = false;
    	    }
	} else {
	    fromcookie = false;
	}
    }
    var smallwindow;
    // if the height of the window is too small
    if (document.body.clientHeight <= 538)
	smallwindow = true;
    else
	smallwindow = false;
    if (((fromcookie && !bearcookie) || (!fromcookie && smallwindow)) &&
	    forceto == null || forceto == false) {
	document.getElementById("topleft").style.background = "none";
	document.getElementById("topleft").style.height = "30px";
	document.getElementById("titletext").style.top = "10px";
	document.getElementById("wtop").style.display = "none";
	wmibear = false;
	if (!fromcookie) {
	    var xdate = new Date();
	    xdate.setTime(xdate.getTime()+30*24*3600*1000);
	    document.cookie = "bear=false; expires="+xdate.toGMTString();
	}
    } else {
	document.getElementById("topleft").style.height = "200px";
	document.getElementById("topleft").style.backgroundImage = "url(./image/tlbbq.png)";
	document.getElementById("topleft").style.backgroundRepeat = "no-repeat";
	document.getElementById("topleft").style.backgroundPosition = "top left";
	document.getElementById("titletext").style.top = "180px";
	document.getElementById("wtop").style.display = "block";
	wmibear = true;
	if (!fromcookie) {
	    var xdate = new Date();
	    xdate.setTime(xdate.getTime()+30*24*3600*1000);
	    document.cookie = "bear=true; expires="+xdate.toGMTString();
	}
    }
}

// Loads WMI2 calculator at the first time
function loadFirst(module,layout)
{
    setwmibear(false,null,null);
    var formulamf = function(restext) {
    	formulamessage = restext;
    }
    ajaxMessage("ws_formula",formulamf);

    ajaxButtonType();

    ajaxLIPreload("default");
    hideLayout();
    ajaxLoadLayout("default");
    
    ajaxLayoutMessage("default");
    
    ajaxLoadNew("default",1);
    var converted_value = codeValue("..#");
    ajaxRefreshImage("ui"+worksheetnew,converted_value,150,"true");
}

// copies a former input formula back to the calculator
function tocalc(whichid) 
{
    var textformula = document.getElementById("uidivt"+whichid).innerHTML;
    if (ifv.indexOf("..") == -1) {
        ifv = textformula;
    } else {
	if (ifv.indexOf("..#") == -1) {
            ifv = ifv.replace("..",textformula);
	} else {
	    ifv = ifv.replace("..#",textformula);
	}
    }
    ifv = ifv.replace("&gt;", ">");
    ifv = ifv.replace("&lt;", "<");
    ifvprev++;
    ifvs[ifvprev] = ifv;
    ifvlast = ifvprev;
    refreshInput();
}

// copies a former output formula back to the calculator
function tocalcRes(whichid)
{
    var textformula = document.getElementById("codivt"+whichid).innerHTML;        
    if (ifv.indexOf("..") == -1) {
        ifv = textformula;
    } else {
	if (ifv.indexOf("..#") == -1) {
            ifv = ifv.replace("..",textformula);
	} else {
	    ifv = ifv.replace("..#",textformula);
	}
    }
    ifv = ifv.replace("&gt;", ">");
    ifv = ifv.replace("&lt;", "<");
    ifvprev++;
    ifvs[ifvprev] = ifv;
    ifvlast = ifvprev;
    refreshInput();
}
