
var actualExercise = null;
var asyncCanLoad = true;
var clockTimeout = null;
var cdTries = 10;
var jumpToNextID = null;
var loadSolution = true;
var examMode = false;

function clearCompositionMsg () {
	HTML_AJAX_Util.setInnerHTML ('btnSave', '');
}

var exercise = {
	modifyAnswers: function(selector, value) {
		$(selector).each(function(){
			var c = $(this);
			var v = parseInt(c.text());
			if (!isNaN(v)) {
				c.text(v + value);
			}
		});
	},
	drag_rearrange: function (obj) {
		// re-arrange slot and player
		DRAGDROP[obj.slot].player = obj.player;
		if (DRAGDROP[obj.player].slot) {
			DRAGDROP[DRAGDROP[obj.player].slot].player = null;
			// drop previous slot's data
			if (DRAGDROP[DRAGDROP[obj.player].slot].hdn) {
				document.getElementById(DRAGDROP[DRAGDROP[obj.player].slot].hdn).value = '';
			}
		}
		// enable previous slot
		$('#' + DRAGDROP[obj.player].slot).droppable('option', 'disabled', false);
		DRAGDROP[obj.player].slot = obj.slot;
		DRAGDROP[obj.player].moved = obj.moved;
		// disable actual slot
		$('#' + obj.slot).droppable('option', 'disabled', true);
		// fill actual slots hidden if any
		if (DRAGDROP[obj.slot].hdn) {
			document.getElementById(DRAGDROP[obj.slot].hdn).value = DRAGDROP[obj.player].md5sol;
		}
		$('#' + obj.player).offset($('#' + obj.slot).offset());
	},
	droppable_target: function (event, ui) {
		var $actual_slot = $(this).attr('id');
		var $actual_player = $(ui.draggable).attr('id');
		exercise.drag_rearrange({slot:$actual_slot, player:$actual_player, moved: true});
	},
	droppable_source: function (event, ui) {
		var $actual_slot = $(this).attr('id');
		var $actual_player = $(ui.draggable).attr('id');
		exercise.drag_rearrange({slot:$actual_slot, player:$actual_player, moved: false});
	},
    // Initializes editing lines (word association, for example)
    initializeEditlines: function(exid) {
        // focus workaround to trigger blur aswell
        function realFocus(el) {
            if (typeof el == 'object' && typeof el.focus != 'undefined') {
                el.focus();
            }
        }
        // set the focus to a line relatively to the current
        function lineFocus(current, offset) {
            var lines = $('.exercise .wordassoc_editline');
            var i = lines.index(current);
            while (true) {
                var j = i + offset;
                if (i == j || j < 0 || j >= lines.size()) {
                    break;
                } else {
                    var line = lines.eq(j);
                    if (line.find('input[type="hidden"]').attr('disabled')) {
                        offset += (offset < 0 ? -1 : 1);
                        continue;
                    } else {
                        lines.eq(j).click();
                        break;
                    }
                }
            }
        }
        // on click, put the focus on the first empty field
        $('.wordassoc_editline').data('exid', exid).click(function(e){
            e.preventDefault();
            var line = $(this);
            // if none of the fields has focus in the line
            if (line.find('input.focused').size() == 0) {
                line.find('input[type="text"]').each(function(i, e){
                    var el = $(e);
                    // only look for empty fields
                    if (el.val().length == 0) {
                        realFocus(e);
                        return false;
                    }
                });
            }
            // if there were no empty fields, pick the last
            if (line.find('input.focused').size() == 0) {
                realFocus(line.find('input[type="text"]:last').get(0));
            }
        });
        // input actions
        $('.wordassoc_editline input[type="text"]').focusin(function(){
            $(this).addClass('focused');
        }).focusout(function(){
            $(this).removeClass('focused');
        }).keydown(function(e){
            var field = $(this);
            var line = field.closest('.wordassoc_editline');
            switch (e.which) {
            case 13: // enter
                var hidden = line.find('input[type="hidden"]');
                exercise.chkOneGapWNext(
                    e, // event object
                    parseInt(line.data('exid')), // exercise id
                    parseInt(line.attr('id').substring(9)), // exercise line id
                    hidden.get(0), // input object
                    parseInt(line.closest('form').attr('id').substring(3)) // line number
                );
                break;
            case 8:  // backspace
                if (field.val().length > 0) {
                    field.val('');
                } else {
                    var prev = field.prevAll('input[type="text"]:first');
                    prev.val('');
                    realFocus(prev.get(0));
                }
                break;
            case 46: // delete
                if (field.val().length > 0) {
                    field.val('');
                } else {
                    var prev = field.nextAll('input[type="text"]:first');
                    prev.val('');
                    realFocus(prev.get(0));
                }
                break;
            case 35: // end
                realFocus(field.nextAll('input[type="text"]:last').get(0));
                break;
            case 36: // home
                realFocus(field.prevAll('input[type="text"]:last').get(0));
                break;
            case 37: // left
                realFocus(field.prevAll('input[type="text"]:first').get(0));
                break;
            case 38: // up
                lineFocus(field.closest('.wordassoc_editline'), -1);
                break;
            case 32: // space
            case 39: // right
                realFocus(field.nextAll('input[type="text"]:first').get(0));
                break;
            case 9:  // tab
            case 40: // down
                lineFocus(line, 1);
                break;
            default:
            }
        }).keypress(function(e){
            var field = $(this);
            // get and pressed combination if allowed
            var val = String.fromCharCode(e.which).toUpperCase();
            if (/[\w\._\(\)\[\]&\$\|'"\/\\=\+\*,\?!<>#@\{\};:-]/.test(val)) {
                field.val(val);
                realFocus(field.nextAll('input[type="text"]:first').get(0));
            }
            // update the real field
            var line = field.closest('.wordassoc_editline');
            var parts = [];
            var ok = false;
            line.find('.solution_1').each(function(i, e){
                var el = $(e);
                var part;
                if (el.is('input')) {
                    part = el.val();
                    if (part.length > 0) {
                        ok = true;
                    }
                } else {
                    part = el.text();
                }
                parts.push(part);
            });
            line.find('input[type="hidden"]').val(ok ? parts.join('') : '');
            e.preventDefault();
        });
    },
    // Inserts the parts of the retreived solution into the text fields
    // This for layout "ListeningWordAssoc"
    insertParts: function(id) {
        var line = $('#editline_' + id);
        var hidden = line.find('input[type="hidden"]');
        var val = hidden.val();
        var varId = hidden.attr('id');
        for (i = 0; i < val.length; ++i) {
            var el = $('#' + varId + '_char_' + i);
            if (el.is('input')) {
                el.val(val.substring(i, i + 1));
            } else {
                el.text(val.substring(i, i + 1));
            }
        }
    },
	// Adds red-crossing to the substrings specified in column
	// 'solution' by adding the 's' parameter to the image url
	addRedCrossing: function(id) {
		var img = $('#ex_'+id+'_tbl img[src^="/image.php"]');
		img.attr('src', img.attr('src').replace(/&s=[^&]*/, '') + '&s=solution');
	},
	// Removes all gaps from the specified exercise line by removing the
	// 'c2' parameter and filtering the 'r' character from the 'e' parameter
	removeGaps: function(id) {
		var img = $('#ex_'+id+'_tbl img[src^="/image.php"]');
		var src = img.attr('src');
		img.attr('src', src.replace(/&c2=[^&]*/, '').replace(/&e=[^&]*/, '')
			+ '&e=' + $.url.setUrl(src).param('e').replace('r', ''));
	},
	// Replaces wrong words (marked up with &&) in the text by adding x to
	// the 'e' parameter and specifying the solution column with the 'c2'
	// parameter
	replaceHighlightWrong: function(id) {
		var img = $('#ex_'+id+'_tbl img[src^="/image.php"]');
		var src = img.attr('src');
		img.attr('src', src.replace(/&c2=[^&]*/, '').replace(/&e=[^&]*/, '') + '&c2=solution' + '&e=xi');
	},
	// Moves the DIV element that belongs to the specified
	// exercise line by swapping it with the DIV element taking
	// the correct position of the former DIV
	reorderItem: function(id) {
		var list = $('.fullw');
		var item = $('#el-' + id);
		var oldPos = list.index(item);
		var newPos = parseInt(item.find('input[name="solution"]').val());
		if (!isNaN(newPos)) {
			newPos--;
			if (newPos != oldPos) {
				if (oldPos < newPos) {
					var temp = newPos;
					newPos = oldPos;
					oldPos = temp;
				}
                list.eq(oldPos).insertAfter(list.eq(newPos));
                list = $('.fullw');
                list.eq(newPos).insertAfter(list.eq(oldPos));
                list = $('.fullw');
                list.find('table.exc').removeClass('first last')
                	.filter(':first').addClass('first').end()
                	.filter(':last').addClass('last');
                list.find('td.leftborder, td.help').removeClass('topborder');
                list.find('td.leftborder, td.help')
                	.not('td.leftborder:first, td.help:first').addClass('topborder');
			}
		}

	},
	// Looks for pre-defined flags in the request result,
	// and performs the appropriate action
	postProcess: function(result) {
    	// red-crossing
    	if (typeof result.f_add_red_crossing != 'undefined' && result.f_add_red_crossing) {
    		exercise.addRedCrossing(result.exercise_line);
    	}
    	// removing gaps
    	if (typeof result.f_remove_gaps != 'undefined' && result.f_remove_gaps) {
    		exercise.removeGaps(result.exercise_line);
    	}
    	// removing gaps
    	if (typeof result.f_reorder_item != 'undefined' && result.f_reorder_item) {
    		exercise.reorderItem(result.exercise_line);
    	}
        // inserting parts
        if (typeof result.f_insert_parts != 'undefined' && result.f_insert_parts) {
            exercise.insertParts(result.exercise_line);
        }
        // replace and highlight wrong words
        if (typeof result.f_replace_highlight_wrong != 'undefined' && result.f_replace_highlight_wrong) {
            exercise.replaceHighlightWrong(result.exercise_line);
        }
	},
    // Loads the videofiles on *Wathing* layouts
    loadVideos: function(videos) {
	    if(examMode) {
	   		$.each(videos, function(id, file) {
	           jwplayer('flvvidplayer_' + id).setup({
				    'flashplayer': '/core/javascript/embed/player.swf',
				    'file': '../../../videofiles/' + file,
				    'controlbar': 'none',
				    'autostart': true,
				    'width': '720px',
	                'height': '596px',
				    'wmode':'transparent',
				    'class':'flvplay',
				    'displayclick':'none'
				  });

	        });
	    } else {
	        $.each(videos, function(id, file) {
	           jwplayer('flvvidplayer_' + id).setup({
				    'flashplayer': '/core/javascript/embed/player.swf',
				    'file': '../../../videofiles/' + file,
				    'controlbar': 'bottom',
				    'autostart': false,
				    'width': '720px',
	                'height': '596px',
				    'wmode':'transparent',
				    'class':'flvplay',
				    'displayclick':'none'
				  });
	        });
        }
    },
	delSubscription: function (id_subscription) {
		asyncExercise.ajaxDelSubscription (id_subscription);
	},
	getHtml: function (p_sType, p_aArgs, p_oValu){
		asyncExercise.getHtml(p_oValu);
	},
	checkAnswer: function (ex_id, ex_line_id, solution) {
		tar = solution;
		while(!HTML_AJAX_Util.hasClass (tar, 'form')) {
			tar = tar.parentNode;
		}
		if (HTML_AJAX_Util.hasClass (tar, 'allready_checked')) {
			var first_check = false;
		} else {
			HTML_AJAX_Util.addClass (tar, 'allready_checked');
			var first_check = true;
		}
		asyncExercise.checkAnswer (ex_id, ex_line_id, HTML_AJAX.formEncode(tar, 'PHP'), first_check);
		return false;
	},
	getExam: function (p_sAction, p_aArgs, p_oValue) {
		asyncExercise.ajaxExamMode(p_oValue.id_menu);
	},
	endExam: function (p_sAction, p_aArgs, p_oValue) {
		asyncExercise.ajaxExamMode(0);
	},
	switchExamExercise: function (id_menu) {
		asyncExercise.ajaxExamMode(id_menu, true);
	},
	getExercise: function (p_sAction, p_aArgs, p_oValue) {
		asyncExercise.ajaxExerciseMode(p_oValue.id_menu);
	},
	updateClock: function () {
		var remains = Math.round((clockEndTime - new Date().getTime()) / 1000);
		var min = Math.floor(remains / 60);
		if (min < 10) {
			min = '0' + min;
		}
		var sec = remains % 60;
		if (sec < 10) {
			sec = '0' + sec;
		}
		$('#exercise_status #timer .minutes').text(min);
		$('#exercise_status #timer .seconds').text(sec);
		if (remains > 0) {
			clockTimeout = setTimeout(exercise.updateClock, 1000);
		} else {
			asyncExercise.ajaxExamMode(-1);
		}
	},
	hideMenu: function () {
		oMenuBar.hide ();
	},
	showMenu: function () {
		oMenuBar.show ();
	},
	getHelp: function (p_sAction, p_aArgs, p_oValue) {
		if (p_oValue.length > 0) asyncExercise.ajaxGetHelp (p_oValue);
	},
	getSubscriptions: function (p_sAction, p_aArgs, p_oValue) {
		asyncExercise.ajaxGetSubscriptions ();
	},
	getHelpFromFile: function (id) {
		asyncExercise.ajaxGetHelp (id, true);
	},
	chkAnswerBody: function (ex_id, ex_line_id, solution) {
		help.setHelpId(ex_line_id);
		tar = solution;
		while(!HTML_AJAX_Util.hasClass (tar, 'form')) {
			tar = tar.parentNode;
		}
		if (HTML_AJAX_Util.hasClass (tar, 'allready_checked')) {
			var first_check = false;
		} else {
			HTML_AJAX_Util.addClass (tar, 'allready_checked');
			var first_check = true;
		}
		el = tar.getElementsByTagName('input');
		for (var i=0; i< el.length; i++) { /*>*/
			if (el[i].name == 'solution') {
				id = el[i].id;
			}
		}
		var encodedString = HTML_AJAX.formEncode(tar, 'PHP');
		if (encodedString.solution) {
			if (encodedString.solution.length > 0) asyncExercise.ajaxChkAnswer (id, ex_id, ex_line_id, encodedString, first_check);
			if (encodedString.solution.length == 0) if (loadSolution == true) asyncExercise.ajaxGetSolution (id, ex_line_id, encodedString, first_check);
		} else {
			if (loadSolution == true) {
				asyncExercise.ajaxGetSolution (id, ex_line_id, encodedString, first_check);
				exercise.modifyAnswers('#bad_answers', 1);
			}
		}
	},
	chkAnswerMC: function(ex_id, ex_line_id, solution) {
		jumpToNextID = parseInt($(solution).closest('form').attr('id').substr(3));
		exercise.chkAnswerBody(ex_id, ex_line_id, solution);
	},
	chkAnswerSSSS: function (ex_id, ex_line_id, solution, number, event) {
        jumpToNextID = number;
        if (typeof event == 'object') { // keypress in field
            var field = $(solution);
            if (event.which == 13) {
                if (field.attr('name') == 'field_2') {
                    field.closest('tr').find('input[name="field_3"]').get(0).focus();
                    return false;
                }
                loadSolution = false;
            } else {
                loadSolution = true;
                return false;
            }
        } else {
            loadSolution = true;
        }
		help.setHelpId(ex_line_id);
		tar = solution;
		while(!HTML_AJAX_Util.hasClass (tar, 'form')) {
			tar = tar.parentNode;
		}
		if (HTML_AJAX_Util.hasClass (tar, 'allready_checked')) {
			var first_check = false;
		} else {
			HTML_AJAX_Util.addClass (tar, 'allready_checked');
			var first_check = true;
		}
		el = tar.getElementsByTagName('input');
		for (var i=0; i< el.length; i++) { /*>*/
			if (el[i].name == 'field_2') {
				id2 = el[i].id;
			}
			if (el[i].name == 'field_3') {
				id3 = el[i].id;
			}
		}
		var id = id2 + "@@@@" + id3;
		var encodedString = HTML_AJAX.formEncode(tar, 'PHP');
        if (loadSolution) {
            if (encodedString.field_2 && encodedString.field_3 && encodedString.field_2.length && encodedString.field_3.length) {
                encodedString.solution = encodedString.field_2 + "@@@@" + encodedString.field_3;
                asyncExercise.ajaxChkAnswer (id, ex_id, ex_line_id, encodedString, first_check);
            } else {
                asyncExercise.ajaxGetSolution (id, ex_line_id, encodedString, first_check);
            }
        } else {
            encodedString.solution = encodedString.field_2 + "@@@@" + encodedString.field_3;
            asyncExercise.ajaxChkAnswer (id, ex_id, ex_line_id, encodedString, first_check);
        }
	},
	chkAnswerSSSD: function (ex_id, ex_line_id, solution, number, event) {
        jumpToNextID = number;
        if (typeof event == 'object') { // keypress in field
            var field = $(solution);
            if (event.which == 13) {
                var fields = field.closest('tr').find('input[type!="hidden"]');
                if (fields.last().get(0) != field.get(0)) {
                    fields.eq(fields.index(field) + 1).get(0).focus();
                    return false;
                }
                loadSolution = false;
            } else {
                loadSolution = true;
                return false;
            }
        } else {
            loadSolution = true;
        }
		help.setHelpId(ex_line_id);
		tar = solution;
		while(!HTML_AJAX_Util.hasClass (tar, 'form')) {
			tar = tar.parentNode;
		}
		if (HTML_AJAX_Util.hasClass (tar, 'allready_checked')) {
			var first_check = false;
		} else {
			HTML_AJAX_Util.addClass (tar, 'allready_checked');
			var first_check = true;
		}
		el = tar.getElementsByTagName('input');
		for (var i=0; i< el.length; i++) { /*>*/
			if (el[i].name == 'question') {
				id1 = el[i].id;
			}
			if (el[i].name == 'field_2') {
				id2 = el[i].id;
			}
			if (el[i].name == 'field_3') {
				id3 = el[i].id;
			}
		}
		var id = id1 + ";;;;" + id2 + ";;;;" + id3;
		var encodedString = HTML_AJAX.formEncode(tar, 'PHP');
        if (loadSolution) {
            if (encodedString.question && encodedString.field_2 && encodedString.field_3
                && encodedString.question.length && encodedString.field_2.length && encodedString.field_3.length) {
                encodedString.solution = encodedString.question + ";;;;" + encodedString.field_2 + ";;;;" + encodedString.field_3;
                asyncExercise.ajaxChkAnswer (id, ex_id, ex_line_id, encodedString, first_check);
            } else {
                asyncExercise.ajaxGetSolution (id, ex_line_id, encodedString, first_check);
            }
        } else {
            encodedString.solution = encodedString.question + ";;;;" + encodedString.field_2 + ";;;;" + encodedString.field_3;
            asyncExercise.ajaxChkAnswer (id, ex_id, ex_line_id, encodedString, first_check);
        }
	},
	chkAnswerLBF: function (ex_id, ex_line_id, solution, number) {
		help.setHelpId(ex_line_id);
		tar = solution;
		while(!HTML_AJAX_Util.hasClass (tar, 'form')) {
			tar = tar.parentNode;
		}
		if (HTML_AJAX_Util.hasClass (tar, 'allready_checked')) {
			var first_check = false;
		} else {
			HTML_AJAX_Util.addClass (tar, 'allready_checked');
			var first_check = true;
		}
		el = tar.getElementsByTagName('input');
		id1 = id2 = id3 = '';
		for (var i=0; i< el.length; i++) { /*>*/
			if (el[i].name == 'solution') {
				id1 = el[i].id;
			}
			if (el[i].name == 'field_2') {
				id2 = el[i].id;
			}
			if (el[i].name == 'field_3') {
				id3 = el[i].id;
			}
		}
		var id = id1 + "____" + id2 + "____" + id3;
		var encodedString = HTML_AJAX.formEncode(tar, 'PHP');
		if (encodedString.solution == undefined) encodedString.solution = '';
		if (encodedString.field_2 == undefined) encodedString.field_2 = '';
		if (encodedString.field_3 == undefined) encodedString.field_3 = '';
		if ((encodedString.solution)
			|| (encodedString.field_2)
			|| (encodedString.field_3)) {
				if ((encodedString.solution.length)
					|| (encodedString.field_2.length)
					|| (encodedString.field_3.length)) {
//						encodedString.solution = encodedString.solution + "____" + encodedString.field_2 + "____" + encodedString.field_3;
						asyncExercise.ajaxChkAnswer (id, ex_id, ex_line_id, encodedString, first_check);
				} else
					if (loadSolution == true) asyncExercise.ajaxGetSolution (id, ex_line_id, encodedString, first_check);
		} else {
			if (loadSolution == true) asyncExercise.ajaxGetSolution (id, ex_line_id, encodedString, first_check);
		}
	},
	chkAnswerWNext: function (ex_id, ex_line_id, solution, number) {
        jumpToNextID = number;
        loadSolution = true;
		exercise.chkAnswerBody (ex_id, ex_line_id, solution);
//		exercise.jumpToNext (++number);
		return false;
	},
	chkOneGap: function (e, ex_id, ex_line_id, solution) {
	    if (null == e)
				e = window.event;
	    if (e.keyCode == 13)  {
	    		loadSolution = false;
				exercise.chkAnswerBody (ex_id, ex_line_id, solution);
				return false;
	    } else loadSolution = true;
	},
	chkOneGapWNext: function (e, ex_id, ex_line_id, solution, number) {
        jumpToNextID = number;
	    if (null == e)
				e = window.event;
	    if (e.keyCode == 13)  {
	    	loadSolution = false;
            exercise.chkAnswerBody (ex_id, ex_line_id, solution);
//          exercise.jumpToNext (++number);
            return false;
	    } else loadSolution = true;
	},
	jumpToNext: function(number) {
        var form = $('#frm' + (number >= 0 ? number : jumpToNextID));
        if (form.size() == 0) {
            form = $('#frm1');
        }
        var el = form.find('input[type!="hidden"][type!="radio"][type!="checkbox"]:visible, select:visible, textarea:visible').get(0);
        if (el && el.select) el.select();
        if (el && el.focus) el.focus();
	},
    disableFields: function (number) {
        var form = $('#frm' + (number >= 0 ? number : jumpToNextID));
        if (form.size() == 0) {
            form = $('#frm1');
        }
        form.find('input, select, textarea').attr('disabled', 'disabled');
    },
	getAnswer: function (base_path, table_name, imagewidth, exlineid, number) {
		HTML_AJAX_Util.setInnerHTML('sol' + number,'<img src="' + base_path + 'image.php?t=' + table_name + '&amp;w=' + imagewidth + '&amp;c=solution&amp;i=' + exlineid + '">');
	},
	saveComposition: function (id, textarea) {
		if (id != '') {
			var txt = document.getElementById (textarea);
			txt = txt.value;
			if (txt.length)
					asyncExercise.ajaxSaveComposition (id, txt);
				else
					HTML_AJAX_Util.setInnerHTML ('btnSave', '<span>Cannot save empty exercise</span>');
		} else {
			HTML_AJAX_Util.setInnerHTML ('btnSave', '<span>Cannot save exercise, notice admin</span>');
		}
		setTimeout ('clearCompositionMsg()', 5000);
	},
	saveCompositionMulti: function(id,textarea){
		if (id != '') {
			var $radio=$('#frm0 input[name="selected_choice"]:checked');
			if($radio.length){
				var choiceVal=$radio.val();
			}else{
				var choiceVal=0;
			}
			
			if(choiceVal > 0 && choiceVal < 5){
				var txt = document.getElementById (textarea);
				txt = txt.value;
				if (txt.length)
						asyncExercise.ajaxSaveCompositionMulti (id, txt, choiceVal);
					else
						HTML_AJAX_Util.setInnerHTML ('btnSave', '<span>Cannot save empty exercise</span>');
			}else{
				HTML_AJAX_Util.setInnerHTML ('btnSave', '<span>Cannot save exercise, please select topic</span>');
			}
		} else {
			HTML_AJAX_Util.setInnerHTML ('btnSave', '<span>Cannot save exercise, notice admin</span>');
		}
		setTimeout ('clearCompositionMsg()', 5000);
	},
	cdPlayAgain: function(exercise_id, menu_id) {
		var answrs = [$('#correct_answers').html(), $('#bad_answers').html()];
		var result = syncExercise.ajaxGetExercise(exercise_id, menu_id);
		ecallback.prototype.ajaxGetExercise(result);
		$('#correct_answers').html(answrs[0]);
		$('#bad_answers').html(answrs[1]);
	},
	cdCheckLetter: function (id_exercise_line, letter) {
		if (cdTries > 0 && $('#l' + id_exercise_line + letter).is('.active')) {
			asyncExercise.ajaxCDCheckLetter(id_exercise_line, letter);
		}
	}
}

function ecallback() {}
ecallback.prototype = {
	ajaxDelSubscription: function (result) {
		asyncExercise.ajaxGetSubscriptions ();
	},
	getHtml: function(result) {
		HTML_AJAX_Util.addClass ('exercise_status_inner', 'hidden');
		HTML_AJAX_Util.setInnerHTML('exercise_title',result.exercise_title);
		if (result.container_info_short_help.length > 0)
			HTML_AJAX_Util.setInnerHTML('container_info_short_help',result.container_info_short_help);
		else
			HTML_AJAX_Util.setInnerHTML('container_info_short_help','&nbsp;');
		HTML_AJAX_Util.setInnerHTML('container_text',result.html);
	},
	checkAnswer: function(result) {
		//jo lenne tudni, hogy milyen modban vagyunk (exam, vagy sima)
		//ha nincsenek kinn az arcok akkor exam mod-ban vagyunk
		var examMode = false;
		if($('#exercise_status_inner').hasClass('hidden')) {
			examMode = true;
		};
		if(!examMode) {
			var parentElement = document.getElementById('exercise_element_'+result.exercise_line);
			var helpImg = HTML_AJAX_Util.getElementsByClassName('exercise_help_img',parentElement);
			HTML_AJAX_Util.addClass(helpImg[0].parentNode,result.exercise_help_extra_class);
			helpImg[0].src = result.exercise_face;
			if(result.setRadio !=undefined) {
				var radio = HTML_AJAX_Util.getElementsByClassName('solution_'+result.setRadio,parentElement);
				radio[0].checked = true;
			}
			if (result.first_check == true) {
				if (result.correct == true) {
					exercise.modifyAnswers('#correct_answers', 1);
				}
				if (result.correct == false) {
					exercise.modifyAnswers('#bad_answers', 1);
				}
			}
		}
	},
	ajaxExerciseMode: function(result) {
		ecallback.prototype.ajaxGetExercise(result);
	},
	ajaxGetExercise: function(result) {
		cdTries = 10;
		loadSolution = true;
		$('#exercise_status_inner').removeClass('hidden');
		if (result.error) {
			alert (result.error);
		} else if (asyncCanLoad) {
			HTML_AJAX_Util.setInnerHTML ('exercise_help_text', (result.exercise_help) ? result.exercise_help : '');
			var hsdiv = document.getElementById ('help_text_select');
			HTML_AJAX_Util.setInnerHTML ('help_text_select', '');
			HTML_AJAX_Util.setInnerHTML ('help_text', '');
			var sel = document.createElement ('select');
			sel.onchange = function () {
				HTML_AJAX_Util.setInnerHTML ('help_text', this.options[this.selectedIndex].value);
				help.setHeight ('container_help_text');
			}
			sel[sel.length] = new Option ('select help', '');
			if (result.lineHelps != undefined)
					for (x = 1; x <= result.lineHelps.length; x++) { /* > */
						if (result.lineHelps[x - 1] != null && result.lineHelps[x - 1].length > 0) {
							sel[sel.length] = new Option ('Question ' + x, result.lineHelps[x - 1]);
						}
					}
			if (sel.length > 1) {
//				hsdiv.appendChild (document.createElement ('br'));
				hsdiv.appendChild (sel);
				hsdiv.appendChild (document.createElement ('br'));
				hsdiv.appendChild (document.createElement ('br'));
			}
			if (result.hasLineHelp == 1
					|| (result.exercise_help != undefined
						&& result.exercise_help.length > 0
						&& result.exercise_help != 'DISABLED')
				) {
				help.enableHelp ();
			} else {
				help.disableHelp ();
			}
			actualExercise = result.exercise_id;
			$('#exercise_title').html(result.exercise_title ? result.exercise_title : '&nbsp;');
			$('#container_info_short_help').html(result.container_info_short_help ? result.container_info_short_help : '&nbsp;');
			$('#navigation_line').html(result.navigation_line ? result.navigation_line : '&nbsp;');
			$('#container_text').html(result.html ? result.html : '&nbsp;');
			$('#correct_answers').html(0);
			$('#bad_answers').html(0);
			$('.exercise label img').click(function() {
				$(this).parents('label').click();
			});
		}
	},
	ajaxGetSubscriptions: function (result) {
		HTML_AJAX_Util.addClass ('exercise_status_inner', 'hidden');
		help.disableHelp ();
		if (result.error) {
			alert (result.error);
		} else if (asyncCanLoad) {
			HTML_AJAX_Util.setInnerHTML ('exercise_help_text', result.exercise_help);
			HTML_AJAX_Util.setInnerHTML ('exercise_title', result.exercise_title);
			if (result.container_info_short_help.length > 0)
					HTML_AJAX_Util.setInnerHTML('container_info_short_help',result.container_info_short_help);
				else
					HTML_AJAX_Util.setInnerHTML('container_info_short_help','&nbsp;');
			HTML_AJAX_Util.setInnerHTML ('container_text', '<div id="dHelpDiv">' + result.html + '</div>');
			$('#correct_answers').html(0);
			$('#bad_answers').html(0);

			help.setHeight ('dHelpDiv');
		}
	},
	ajaxGetHelp: function (result) {
		HTML_AJAX_Util.addClass ('exercise_status_inner', 'hidden');
		help.disableHelp ();
		if (result.error) {
			alert (result.error);
		} else if (asyncCanLoad) {
			HTML_AJAX_Util.setInnerHTML ('exercise_help_text', result.exercise_help);
			HTML_AJAX_Util.setInnerHTML ('exercise_title', result.exercise_title);
			if (result.container_info_short_help.length > 0)
					HTML_AJAX_Util.setInnerHTML('container_info_short_help',result.container_info_short_help);
				else
					HTML_AJAX_Util.setInnerHTML('container_info_short_help','&nbsp;');
			HTML_AJAX_Util.setInnerHTML ('container_text', '<div id="dHelpDiv">' + result.html + '</div>');
			$('#correct_answers').html(0);
			$('#bad_answers').html(0);

			help.setHeight ('dHelpDiv');
		}
	},
	ajaxGetSolution: function (result) {
		if (result.error) {
			alert (result.error);
		} else if (asyncCanLoad) {
			if (result.dragdrop == true) {
				var key = null,
					actual_player = null,
					actual_slot = null;
				for (var kl = 0; kl < DRAGDROP.solutions.length; kl += 1) {
					key = DRAGDROP.solutions[kl];
					if (DRAGDROP.hasOwnProperty(key)) {
						if (DRAGDROP[key].solution && !DRAGDROP[key].moved && DRAGDROP[key].solution == result.md5sol) {
							actual_player = key;
							actual_slot = result.divid;
							break;
						}
					}
				}
				// move into position
				if (actual_player == null || actual_slot == null) {
					return false;
				}
				exercise.drag_rearrange({slot: actual_slot, player: actual_player, moved: true});
			} else {
				if (result.id.match ('@@@@')) {
					var ids = result.id.split ('@@@@');
					var id2 = document.getElementById(ids[0]);
					var id3 = document.getElementById(ids[1]);
					id2.value = result.field_2;
					id3.value = result.field_3;
				} else if (result.id.match (';;;;')) {
					var ids = result.id.split (';;;;');
					var id1 = document.getElementById(ids[0]);
					var id2 = document.getElementById(ids[1]);
					var id3 = document.getElementById(ids[2]);
					id1.value = result.question;
					id2.value = result.field_2;
					id3.value = result.field_3;
				} else if (result.id.match ('____')) {
					var ids = result.id.split ('____');
					var id1 = document.getElementById(ids[0]);
					var id2 = document.getElementById(ids[1]);
					var id3 = document.getElementById(ids[2]);
					if (id1 != null) id1.value = result.solution;
					if (id2 != null) id2.value = result.field_2;
					if (id3 != null) id3.value = result.field_3;
				} else if(result.id.match('_')){
					var id1 = document.getElementById(result.id);
					var id2 = document.getElementById(result.id.replace('_2','_1'));
					if (id1 != null) id1.value = result.solution;
					if (id2 != null) id2.value = result.question;
				} else {
					var inp = document.getElementById(result.id);
					if (inp.type != 'radio') {
						inp.value = result.solution;
					}
				}
			}
			if (result.solution != undefined &&
			    result.exercise_line != undefined && /[0-9]+/.test(result.exercise_line)) {
				$('[id^="ex_'+result.exercise_line+'"] input[value="'+result.solution+'"]').attr('checked', true);
			}
			var helpImg = document.getElementById ('help_img_' + result.exercise_line);
			HTML_AJAX_Util.addClass (helpImg.parentNode, result.exercise_help_extra_class);
			HTML_AJAX_Util.addClass (helpImg.parentNode.parentNode, result.exercise_help_extra_class);
			helpImg.src = result.exercise_face;
			// post-process result
			exercise.postProcess(result);
			// disable and go to next
            exercise.disableFields(jumpToNextID);
            exercise.jumpToNext(++jumpToNextID);
            helpImg.parentNode.onclick = function () {};
		}
	},
	ajaxChkAnswer: function (result) {
		//jo lenne tudni, hogy milyen modban vagyunk (exam, vagy sima)
		//ha nincsenek kinn az arcok akkor exam mod-ban vagyunk
		var examMode = false;
		if($('#exercise_status_inner').hasClass('hidden')) {
			examMode = true;
		};
		if(!examMode) {
			if (result.getSolution) {
				if (loadSolution == true) asyncExercise.ajaxGetSolution (result.id, result.ex_line_id, result.encodedString, result.first_check);
			} else if (asyncCanLoad) {
				loadSolution = true;
				if (result.error) {
					alert (result.error);
				}
				var helpImg = document.getElementById ('help_img_' + result.exercise_line);
				HTML_AJAX_Util.addClass (helpImg.parentNode, result.exercise_help_extra_class);
				HTML_AJAX_Util.addClass (helpImg.parentNode.parentNode, result.exercise_help_extra_class);
				helpImg.src = result.exercise_face;
				if (result.first_check == true) {
					exercise.modifyAnswers(result.correct ? '#correct_answers' : '#bad_answers', 1);
				}
	            if (result.correct == 1) {
	            	// post-process result
	    			exercise.postProcess(result);
	    			// disable and go to next
	                exercise.disableFields (jumpToNextID);
	                exercise.jumpToNext (++jumpToNextID);
	                helpImg.parentNode.onclick = function () {}; /* */
	                var drag = $('#id_sol_' + result.md5);
	                drag.draggable('option', 'disabled', true);
	            } else {
	                exercise.jumpToNext (-1);
	            }
			}
		}
	},
	ajaxExamMode: function (result) {
		// eval exam menu
		var submenus = eval(result.menu);
		if (submenus.length > 0) {
			// init exam menu
			var menus = [];
		    for (var i in submenus) {
		    	menus.push(submenus[i].id);
		    }
		    initNavigation('#nav-menu', menus, submenus);
		} else {
			// restore defaults
			initNavigation('#nav-menu', defaultMenus, defaultSubmenus);
		}
		// perform requested operations
		for (var i in result.operations) {
			switch (result.operations[i]) {
				case 'start_exam': {
					help.disableHelp();
					helpEnabled = false;
					$(window).bind('beforeunload.exam', function () {
						return 'You should not leave this page until you finish the whole exam! Do you want to leave?';
					});
					$(window).bind('unload.exam', function () {
						syncExercise.ajaxExamMode(0);
					});
					$('#exercise_status_inner').addClass('hidden');
					$('#exercise_status_timer').removeClass('hidden');
					examMode = true;
					break;
				}
				case 'end_exam': {
					$(window).unbind('beforeunload.exam');
					$(window).unbind('unload.exam');
					$('#exercise_status_timer').addClass('hidden');
					$('#exercise_status #timer .minutes').text('00');
					$('#exercise_status #timer .seconds').text('00');
					$('#exercise_title').html('&nbsp;');
					$('#container_info_short_help').html('&nbsp;');
					$('#navigation_line').html('&nbsp;');
					$('#container_text').html('&nbsp;');
					examMode = false;
					break;
				}
				case 'load_exercise': {
					ecallback.prototype.ajaxGetExercise(result.exercise);
					// force disable help and hide status
					$('#exercise_status_inner').addClass('hidden');
					help.disableHelp();
					//disable players
					$('.flvplay > *').remove();
					$('.flvplay').css('height','24px');
					if(playlist.length > 0) {
						createFlvPlayerExam(playlist);
					}
					
					
					helpEnabled = false;
					break;
				}
				case 'set_timer': {
					clearTimeout(clockTimeout);
					clockEndTime = new Date().getTime() + (result.timer * 1000);
					clockTimeout = setTimeout(exercise.updateClock, 1000);
					break;
				}
				case 'stop_timer': {
					clearTimeout(clockTimeout);
					break;
				}
				case 'show_dialog': {
					dialog.reset().setTitle(result.title).setContent(result.content);
					for (var i in result.buttons) {
						dialog.addButton(
							result.buttons[i][0],
							result.buttons[i][1],
							eval('(' + result.buttons[i][2] + ')')
						);
					}
					dialog.open();
					break;
				}
				case 'show_content': {
					$('#container_text').html(result.content);
					break;
				}
				default:
			}
		}
	},
	ajaxSaveComposition: function (result) {
		if (result.error) {
			alert (result.error);
		} else {
			HTML_AJAX_Util.setInnerHTML ('btnSave', result.msg);
			setTimeout ('clearCompositionMsg()', 5000);
			var ifr = document.getElementById ('btnIframe');
			ifr.src = '/downloadComposition.php?idel=' + result.id_exercise_line + '&idus=' + result.id_users;
		}
	},
	ajaxSaveCompositionMulti: function (result) {
		if (result.error) {
			alert (result.error);
		} else {
			HTML_AJAX_Util.setInnerHTML ('btnSave', result.msg);
			setTimeout ('clearCompositionMsg()', 5000);
			var ifr = document.getElementById ('btnIframe');
			ifr.src = '/downloadComposition.php?idel=' + result.id_exercise_line + '&idus=' + result.id_users;
		}
	},
	ajaxCDCheckLetter: function (result) {
		if (result.error) {
			alert(result.error);
		}
		if (result.data.length == 0) {
			cdTries--;
		}
		for (var i in result.data) {
			$('#sl' + result.id_exercise_line + result.data[i]).text(result.letter);
		}
		$('#l' + result.id_exercise_line + result.letter).removeClass('active').addClass('inactive');
		$('#cdCount').text(cdTries);
		if (cdTries == 0) {
			exercise.modifyAnswers('#bad_answers', 1);
			$('#letters div:not(.clear)').removeClass('active').addClass('inactive');
			$('#sCDSorry').html(syncExercise.ajaxGetCDSolution(result.id_exercise_line).toUpperCase());
			$('#dCDSorry').show();
		}
		if (result.finished == true) {
			exercise.modifyAnswers('#correct_answers', 1);
			$('#letters div:not(.clear)').removeClass('active').addClass('inactive');
			$('#dCDNext').show();
		}
	}
}

var syncExercise = new Exercise();
var asyncExercise = new Exercise(new ecallback());

var help = {
	sH: function() {
		if (helpEnabled) showHelp('container_help');
	},
	disableHelp: function () {
		helpEnabled = false;
		help.setHelpStyle (false);
	},
	enableHelp: function () {
			helpEnabled = true;
			help.setHelpStyle (true);
			var cht = document.getElementById('container_help_text');
			var ht = document.getElementById('help_text');
			cht.style.height = "auto";
			ht.style.height = "auto";
		showHelp ('container_help');
			var cht_height = cht.offsetHeight;
			var ht_height = ht.offsetHeight;
		hideHelp ('container_help');
			if (cht_height > 300) {
				cht.style.height = "300px";
			}
			if (ht_height > 300) {
				ht.style.height = "300px";
			}
	},
	setHelpStyle: function (enabled) {
		if (enabled) {
			HTML_AJAX_Util.replaceClass ('info_help_anchor', 'inactive', ' active');
		} else {
			HTML_AJAX_Util.replaceClass ('info_help_anchor', 'active', ' inactive');
		}
	},
	setHelpId: function (exercise_line_id) {
		if (exercise_line_id != '0') {
			this.setEvent ('info_help_anchor', 'click', this.sH);
			if (helpEnabled) HTML_AJAX_Util.replaceClass ('info_help_anchor', 'inactive', ' active');
			var ch = document.getElementById('container_help');
			var ht = document.getElementById('help_text');
			ht.style.height = "auto";
			ch.style.display = "block";
		//	HTML_AJAX_Util.setInnerHTML ('help_text', document.getElementById('hd_'+exercise_line_id).innerHTML);
			var height = ht.offsetHeight;
			ch.style.display = "none";
			if (height > 300) {
				ht.style.height = "300px";
			}
		} else {
			HTML_AJAX_Util.setInnerHTML ('help_text', '');
			this.removeEvent ('info_help_anchor', 'click', this.sH);
			HTML_AJAX_Util.replaceClass ('info_help_anchor', 'active', ' inactive');
		}
	},
	// Set the element event
	setEvent: function(element, event, handler) {
		element = HTML_AJAX_Util.getElement(element);
		if (typeof element.addEventListener != "undefined") {   //Dom2
			element.addEventListener(event, handler, false);
		} else if (typeof element.attachEvent != "undefined") { //IE 5+
			element.attachEvent("on" + event, handler);
		} else {
			element["on" + event] = handler;
		}
	},
	removeEvent: function (element, event, handler) {
		element = HTML_AJAX_Util.getElement(element);
		if (typeof element.removeEventListener != "undefined") {   //Dom2
			element.removeEventListener(event, handler, false);
		} else if (typeof element.detachEvent != "undefined") { //IE 5+
			element.detachEvent("on" + event, handler);
		} else {
			element["on" + event] = null;
		}
	},
	setHeight: function (formelementname) {
		var cht = document.getElementById(formelementname);
		cht.style.height = "auto";
		var cht_height = cht.offsetHeight;
		if (cht_height > 428) {
			cht.style.height = "428px";
		}
	}
};

var dialog = {
	elemDialog: null,
	elemTitle: null,
	elemClose: null,
	elemContent: null,
	elemButtons: null,
	buttons: {},
	onOpening: function () {},
	onOpened: function () {},
	onClosing: function () {},
	onClosed: function () {},
	init: function () {
		dialog.elemOverlay = $('#general-dialog-overlay');
		dialog.elemDialog = $('#general-dialog');
		dialog.elemTitle = dialog.elemDialog.find('.general-dialog-header span');
		dialog.elemClose = dialog.elemDialog.find('.general-dialog-header button');
		dialog.elemContent = dialog.elemDialog.find('.general-dialog-content');
		dialog.elemButtons = dialog.elemDialog.find('.general-dialog-buttons');
		dialog.elemClose.click(dialog.close);
		dialog.elemDialog.draggable({ handle: dialog.elemDialog.find('.general-dialog-header') });
		return dialog;
	},
	open: function () {
		var doit = dialog.onOpening();
		if (typeof doit != 'boolean' || doit) {
			dialog.elemOverlay.fadeIn();
			dialog.elemDialog.fadeIn();
			dialog.onOpened();
		}
		return dialog;
	},
	close: function () {
		var doit = dialog.onClosing();
		if (typeof doit != 'boolean' || doit) {
			dialog.elemOverlay.fadeOut();
			dialog.elemDialog.fadeOut();
			dialog.onClosed();
		}
		return dialog;
	},
	setTitle: function (title) {
		dialog.elemTitle.html(title);
		return dialog;
	},
	setContent: function (content) {
		dialog.elemContent.html(content);
		return dialog;
	},
	addButton: function (id, text, callback) {
		dialog.buttons[id] = $('<button class="button"></button>');
		dialog.buttons[id].text(text).click(callback);
		dialog.elemButtons.append(dialog.buttons[id]).contents().filter(function() { return this.nodeType == 3; }).remove();
		dialog.elemButtons.find('button:not(:last)').after('&#160;&#160;&#160;');
		return dialog;
	},
	removeButton: function (id) {
		dialog.buttons[id].remove();
		dialog.buttons[id] = null;
		return dialog;
	},
	closeVisible: function (visible) {
		if (visible) {
			dialog.elemClose.show();
		} else {
			dialog.elemClose.hide();
		}
	},
	reset: function () {
		dialog.elemOverlay.hide();
		dialog.elemDialog.hide();
		dialog.elemButtons.find('button').remove().html('');
		dialog.buttons = {};
		dialog.setTitle('').setContent('');
		dialog.elemClose.hide();
		dialog.onOpening = function () {};
		dialog.onOpened = function () {};
		dialog.onClosing = function () {};
		dialog.onClosed = function () {};
		return dialog;
	}
};

$(dialog.init);

function exec(eventname, event, param) {
	switch (param) {
		case 'exit':
			location.replace('?mod=logout');
			break;
		default:
			if (param.substr(0, 7) == 'http://') {
				window.location.replace(param);
			}
	}
	return true;
}
