var FFJS17 = 1;

function sleep(millis) {
	setTimeout((yield CONTINUATION), millis);
	yield SUSPEND;
}

function makeThreadedFunction(funcExec, funcArgs, newThread) {
	var origFunc;
	if (funcArgs.callee) {
		origFunc = funcArgs.callee;
	} else {
		origFunc = funcArgs;
	}
	var funcSrc = origFunc.toString();
	var funcName = origFunc.name;
	if (!eval('window.'+funcName+'Threaded')) {
		funcExec = '(' + funcExec + ')\\(';
		funcExecRegExp = new RegExp(funcExec);
		funcSrc = funcSrc.replace(/function (.*)\((.*)\) {(((\n|.)*?)makeThreadedFunction((\n|.)*?);((\n|.)*?)})?\n/i, 'window.$1Threaded = function $1Threaded($2) {\n');
		var funcIdx;
		var preventLoop=0;
		while((funcIdx = funcSrc.search(funcExecRegExp)) != -1 && preventLoop < 10000) {
			preventLoop++;
			funcSrc = funcSrc.substr(0, funcIdx) + '(yield ' + funcSrc.substr(funcIdx, funcSrc.indexOf('(', funcIdx) - funcIdx) + 'Threaded' + funcSrc.substr(funcSrc.indexOf('(', funcIdx));
			var funcCharStack = '';
			var i;
			var inQuote = 0;
			for(i = funcIdx; i < funcSrc.length - 1; i++) {
				switch (funcSrc.charAt(i)) {
					case '"':
					case '\'':
						if (inQuote == 0) {
							inQuote = 1;
							funcCharStack += funcSrc.charAt(i);
						} else if (inQuote == 1 && funcCharStack.charAt(funcCharStack.length - 1) == funcSrc.charAt(i)) {
							inQuote = 0;
							funcCharStack = funcCharStack.substr(0, funcCharStack.length - 1);
						} else {
							throw 'ERROR: function source rewrite (quotes)';
						}
						break;
					case '\\':
						i++;
						break;;
				}
				if (inQuote == 1)
					continue;
				switch (funcSrc.charAt(i)) {
					case '(':
					case '{':
						funcCharStack += funcSrc.charAt(i);
						break;
					case ')':
						if (funcCharStack.charAt(funcCharStack.length - 1) != '(') throw 'ERROR: function source rewrite (()brackets)';
						if (funcCharStack.length == 2) {
							funcCharStack = '';
						} else {
							funcCharStack = funcCharStack.substr(0, funcCharStack.length - 1);
						}
						break;
					case '}':
						if (funcCharStack.charAt(funcCharStack.length - 1) != '{') throw 'ERROR: function source rewrite ({} brackets)';
						funcCharStack = funcCharStack.substr(0, funcCharStack.length - 1);
						break;
				}
				if (funcCharStack == '') {
					break;
				}
			}
			if (funcCharStack != '' || i < funcIdx)
				throw 'ERROR: function source rewrite';
			i++;
			funcSrc = funcSrc.substr(0, i) + ')' + funcSrc.substr(i);
		}
		funcSrc = funcSrc.replace(/return /g, 'yield ');
		funcSrc = funcSrc.replace(/return;/g, 'yield;');
		eval(funcSrc);
	}
	if (newThread) {
		var funcArgsText = '';
		for(var i = 0; i < funcArgs.length; i++) {
			if (i > 0)
				funcArgsText += ', ';
			funcArgsText += 'funcArgs['+i+']';
		}
		var t = new Thread(eval('(function () { yield window.'+funcName+'Threaded('+funcArgsText+'); })')).start();
	}
}

var newDialogArguments;
var newDialogReturnValue;
function showModalDialogFFThreaded(url, dlgArg, dlgOpt) {
	var newDialogModalWin;
	newDialogArguments = dlgArg;
	newDialogReturnValue = null;
	newDialogModalWin = window.open(url, null, dlgOpt);
	var disableWindow = document.createElement('div');
	disableWindow.id = 'disableWindow';
	disableWindow.style.position = 'absolute';
	disableWindow.style.left = '0px';
	disableWindow.style.top = '0px';
	disableWindow.style.width = document.body.scrollWidth + 'px';
	disableWindow.style.height = document.body.scrollHeight + 'px';
	//disableWindow.style.cursor = 'progress';
	//disableWindow.style.backgroundColor = '#000000';
	//disableWindow.style.opacity = '0.2';
	document.body.appendChild(disableWindow);
	var tmpOnClick = window.onclick;
	var tmpOnKeyDown = window.onkeydown;
	window.onclick = function () {
		newDialogModalWin.focus();
	};
	window.onkeydown = function () {
		return false;
	};
	while(!newDialogModalWin.closed) {
		yield sleep(200);
	}
	disableWindow.parentNode.removeChild(disableWindow);
	window.onclick = tmpOnClick;
	window.onkeydown = tmpOnKeyDown;
	yield newDialogReturnValue;
}
