function callServer(stp) {
	// Getting initial data
	var string = document.getElementById("stringInput").value;
	step = parseInt(stp); // must be global
	
	if (typeof(string) != "undefined" && string.length > 0) {
		// Reformatting the string: OK
		for (i = 0; i < string.length; i++) {
			if (string.charCodeAt(i) <= 32) string = string.substr(0, i) + "_" + string.substr(i+1, string.length);
		}
		string += "$";
		
		// Algorithm implementation: OK
		var pieces = new Array();
		var codes = new Array();
		var s = 0;
		i = 0;
		pieces[0] = "";
		codes[0] = "";
		
		while (i < string.length) {
			pieceString = string.charAt(i);
			i++;
			
			numBegin = 0;
			
			do {
				found = false;
				
				for (j = 0; j <= s; j++) {
					if (pieceString == pieces[j]) {
						found = true;
						numBegin = j;
						break;
					}
				}
				
				if (found && i < string.length) {
					pieceString += string.charAt(i);
					i++;
				}
				else {
					s++;
					pieces[s] = pieceString;
					codes[s] = numBegin + string.charAt(i-1);
					break;
				}
			} while (found);
		}
		
		lastStep = s;
		
		// Normalization of input values: OK
		if (step < 1) {
			step = 1;
		}
		if (step > lastStep) {
			step = lastStep;
		}
		
		// Calculating the lengths of resulting strings: OK
		lenArray = "";					
		for (i = 1; i <= step; i++) {
			if (lenArray != "") lenArray += ",";
			lenArray += pieces[i].length;
		}
							
		// Drawing control UI: OK		
		if (step == 1) {
			disableButton("navBeginBtn");
			disableButton("navBackBtn");
		}
		else {
			enableButton("navBeginBtn");
			enableButton("navBackBtn");
		}
		
		if (step == lastStep) {
			disableButton("navForwardBtn");
			disableButton("navEndBtn");
			document.getElementById("stepInput").value = 1;
		}
		else {
			enableButton("navForwardBtn");
			enableButton("navEndBtn");
			document.getElementById("stepInput").value = parseInt(step)+1;
		}
		
		// Drawing current step: OK
		document.getElementById("stepDiv").innerHTML = "Шаг " + step + " из " + lastStep + ": подстрока <b>" + pieces[step] + "</b> кодируется как <b>" + codes[step] + "</b>";
	
		// Drawing result: OK
		codeString = "";
		for (i = 1; i <= step; i++) codeString += codes[i];
		
		var len = codeString.length;		
		var ROW_LENGTH = 100;
		var rows = Math.floor(len / ROW_LENGTH) + ((len % ROW_LENGTH > 0) ? 1 : 0);
		
		var result = "";
		
		for (i = 0; i < rows; i++) {
			for (j = 0; j < ROW_LENGTH && (i*ROW_LENGTH + j) < len; j++) {
				result += codeString.charAt(i*ROW_LENGTH + j);
			}
			result += "<br />";
		}
		
		document.getElementById("resultCell").innerHTML = result;
		
		// Drawing step-by-step table
		var nCols = 20;
		var nRows = Math.floor(step / nCols) + ((step % nCols > 0) ? 1 : 0);
		
		var k = 0;
		numBegin = codes[step].substr(0, codes[step].length-1);
		
		var oldMainTbl = document.getElementById("mainTbl");
		if (oldMainTbl) oldMainTbl.parentNode.removeChild(oldMainTbl);
		
		var mainTbl = document.createElement("table");
		mainTbl.id = "mainTbl";
		mainTbl.setAttribute("border", "1");
		mainTbl.setAttribute("rules", "rows");
		mainTbl.setAttribute("cellspacing", "0");
		mainTbl.setAttribute("cellpadding", "2");
		
		var mainTblBody = document.createElement("tbody");
		
		for (i = 1; i <= nRows; i++) {
			var trElement = document.createElement("tr");
			for (j = 1; j <= nCols; j++) {
				k++;
				
				var tdElement = document.createElement("td");
				tdElement.className = "standardCell";
				
				if (k <= step) {
					var innerTbl = document.createElement("table");
					innerTbl.setAttribute("align", "center");
					innerTbl.setAttribute("width", "100%");
					innerTbl.setAttribute("border", "0");
					innerTbl.setAttribute("rules", "none");
					innerTbl.setAttribute("cellspacing", "0");
					innerTbl.setAttribute("cellpadding", "0");
					
					var innerTblBody = document.createElement("tbody");
					
					if (k == numBegin) innerTbl.className = "oldbordered";
					else if (k == step) innerTbl.className = "newbordered";
					else innerTbl.className = "nobordered";
					
					var innerTr, innerTd;
					innerTr = document.createElement("tr");
					innerTd = document.createElement("td");
					innerTd.className = "numberCell";
					innerTd.innerHTML = k;
					innerTr.appendChild(innerTd);
					innerTblBody.appendChild(innerTr);
					
					innerTr = document.createElement("tr");
					innerTd = document.createElement("td");
					innerTd.className = "codeCell";
					innerTd.innerHTML = pieces[k];
					innerTr.appendChild(innerTd);
					innerTblBody.appendChild(innerTr);
					
					innerTr = document.createElement("tr");
					innerTd = document.createElement("td");
					innerTd.innerHTML = codes[k];
					innerTr.appendChild(innerTd);
					innerTblBody.appendChild(innerTr);
					
					innerTbl.appendChild(innerTblBody);
					tdElement.appendChild(innerTbl);
				}
				else {
					tdElement.innerHTML = "&nbsp;";
				}
				
				trElement.appendChild(tdElement);
			}
			mainTblBody.appendChild(trElement);
		}
		
		mainTbl.appendChild(mainTblBody);
		document.getElementById("tableDiv").appendChild(mainTbl);
		
		// Drawing graphic
		document.getElementById("diagramImg").src = "drawpng.php?lenArray=" + lenArray;
	}
	
	document.getElementById("algoDiv").style.display = "block";	
}

function disableButton(buttonId) {
	document.getElementById(buttonId).disabled = true;
}

function enableButton(buttonId) {
	document.getElementById(buttonId).disabled = false;
}

function prevStep() {
	callServer(step - 1);
}

function nextStep() {
	callServer(step + 1);
}

function initPage() {
	body = document.getElementsByTagName("body")[0];
	document.getElementById("algoDiv").style.display = "none";
	step = 1;
}