// locales
var separator = "internal error";
// use period as 000's separator
var decpoint = "internal error,";
// use comma as decimal point
var percent = "not implemented";
var currency = "not implemented";
// use ATS for currency
var opsjUriBase = null;

// The fixed html id of divs that can be used to display messages to the user.
var alertBoxId = "_alert_box";
var alertBoxTextId = "_alert_box_text";

var opsjLogWindow = null;

var curRichDt;
// format the time portion of a Date object as
//  hh:mm:ss.nnnn
function opsjTimeFormat(date)
{
  var dateStr = "";
  var hours = date.getHours();
  var mins = date.getMinutes();
  var secs = date.getSeconds();
  var millis = date.getMilliseconds();
  
  if (hours < 10) dateStr += "0";
  dateStr += hours;

  dateStr += ":";
  if (mins < 10) dateStr += "0";
  dateStr += mins;

  dateStr += ":";
  if (secs < 10) dateStr += "0";
  dateStr += secs;
  
  dateStr += ".";
  dateStr += millis;
  
  return dateStr;
}

// Turn on logging. All calls to opsjLog will be ignored unless this
// function has been called first. It is expected that calls to opsjLog
// will be left in production code, but that no call to this method is
// done by default. To enable logging output for a page, a developer
// just needs to add a single call to this method.
//
// Param windowName is the name of the window into which logging output
// is to be written. The name "debug" is suggested.
function opsjLogInit(windowName)
{
  opsjLogWindow = windowName;
}

// Write a message to a separate log window, for debugging purposes.
// Calls to this method are ignored unless function opsjLogInit has
// already been called, so it is safe to leave calls to this function
// in production code.
function opsjLog(msg)
{
  if (!opsjLogWindow) return;
  var win=window.open(
    '',
    opsjLogWindow,
    'width=200,height=400,scrollbars=yes,resizable=yes,location=no,menubar=no,status=no');
  var doc = win.document;
  var htmlNode = doc.documentElement;
  var bodyNode = htmlNode.lastChild;
  var p = doc.createElement("p");
  var dateStr = opsjTimeFormat(new Date());
  var txt = doc.createTextNode(dateStr + " - " + msg);
  p.appendChild(txt);
  bodyNode.insertBefore(p, bodyNode.firstChild);
}

function ou_thousandSeparator(thousandSeparator)
{
	separator = thousandSeparator;
}
function ou_decimalPoint(decimalPoint)
{
	decpoint = decimalPoint;
}
function ou_setOpsjUriBase(uriBase)
{
	opsjUriBase = uriBase;
}

var ou_emptyPage = "";
// empty page placeholder to make ie happy

/**
 * Create a submit-string for the given form
 */
function opsjGetSubmitString(theForm)
{
	var sOut = opsjCreateUrl(theForm.action);

	for (var e = 0; e < theForm.length; e++)
	{
		var el = theForm.elements[e];
		if (el.type == "select-multiple")
		{	// we have a multiple-selection select-element...
			var opt, n;
			for (n = 0; n < el.options.length; n++)
			{
				opt = el.options[n];
				if (opt.selected)
					sOut += "&" + el.name + "=" + opt.value;
			}
		}
		else if (el.type == "radio" || el.type == "checkbox")
		{	// for radios only the checked-ones count...
			if (el.checked)
				sOut += "&" + el.name + "=" + el.value;
		}
		else if (el.type != "submit")
		{
			if (el.name == "ACTION")
			{
				continue;
			}
			sOut += "&" + el.name + "=" + el.value;
		}
	}

	return opsjGetLocationPath(window) + "?" + sOut;
}

/**
 * returns the window.location.pathname including the jsessionid
 */
function opsjGetLocationPath(win)
{
	if (window.location.pathname.indexOf(";jsessionid") > -1)
	{
		return window.location.pathname;
	}

	var href = window.location.href;
	var startPos = href.indexOf(";jsessionid");
	if (startPos < 0)
	{
		// no jsessionid ... maybe using cookies
		return window.location.pathname;
	}

	var endPos = href.indexOf("?", startPos);
	if (endPos < 0)
	{
		endPos = href.length;
	}

	var location = window.location.pathname + href.substring(startPos, endPos);
	return location;
}

/**
 * Replace content of given window (reload)
 */
function opsjReload(win)
{
	//	var newurl = win.location.pathname + "?";
	//	newurl += opsjCreateUrl(win.location.search);

	if (win.doReload)
	{
		win.doReload();
	}
	else
	{
		win.location.reload();
	}
}

/**
 * Replace content of given window (reload). Stip off "Action"
 */
function opsjReloadWithoutAction(win)
{
	if (win.doReload)
	{
		win.doReload();
	}
	else
	{
		var newurl = opsjGetLocationPath(win) + "?";
		newurl += opsjCreateUrl(win.location.search);
		newurl = opsjRemoveUrlArgument(newurl, "ACTION");

		win.location.replace(newurl);
	}
}

/**
 * Replace content of given window (reload). Set new "Action"
 */
function opsjReloadAction(win, action)
{
	var newurl = opsjGetLocationPath(win) + "?";
	newurl += opsjCreateUrl(win.location.search);
	newurl = opsjReplaceUrlArgument(newurl, "ACTION", action);

	win.location.replace(newurl);
}

/**
 * Split url and recreate. This strip off all System-Args (start with _) except _A
 */
function opsjCreateUrl(sUrl)
{
	var newurl = "";

	var flds = opsjSplitUrl(sUrl);
	for (var i = 0; i < flds.length; i++)
	{
		newurl += "&" + flds[i];
	}

	return newurl;
}

/**
 * Remove an arg (xxx=yyy) in the urls search part
 * GS20020306
 */
function opsjRemoveUrlArgument(sUrl, sArg)
{
	var newurl = "";

	var location = opsjGetLocation(sUrl);

	var flds = opsjSplitUrl(sUrl);
	for (var i = 0; i < flds.length; i++)
	{
		var arg = opsjExtractArg(flds[i]);
		if (arg[0] == sArg)
		{
			continue;
		}

		if (!flds[i] || flds[i].length < 1)
		{
			continue;
		}

		newurl += "&" + flds[i];
	}

	return location + "?" + newurl;
}

/**
 * Replace value of arg with new value
 */
function opsjReplaceUrlArgument(sUrl, sArg, sValue)
{
	return opsjRemoveUrlArgument(sUrl, sArg) + "&" + sArg + "=" + sValue;
}

/**
 * Return location part of url (/opsjs/ops?xx=dd => /opsjs/ops)
 */
function opsjGetLocation(sUrl)
{
	var pos = sUrl.indexOf("?");
	if (pos > -1)
		return sUrl.substring(0, pos);

	return sUrl;
}

/**
 * Split argument into key/value
 */
function opsjExtractArg(arg)
{
	var pos = arg.indexOf("=");
	if (pos < 0)
		return arg;

	var args = new Array();
	args[0] = arg.substring(0, pos);
	args[1] = arg.substring(pos + 1);
	return args;
}

/**
 * Split url. This strip off all System-Args (start with _) expect _A
 */
function opsjSplitUrl(sUrl)
{
	// first strip "?" then split "&"
	var pos = sUrl.indexOf("?");
	if (pos > -1)
		sUrl = sUrl.substring(pos + 1);

	var flds = sUrl.split("&");
	var rets = new Array();
	for (var i = 0; i < flds.length; i++)
	{
		// unfold _A
		if (flds[i].indexOf("_A=") == 0 && flds[i].indexOf("_AE=") != 0)
		{
			var sUrlA = unescape(flds[i].substr(3));
			var fldsA = sUrlA.split(",");
			for (var j = 0; j < fldsA.length; j++)
			{
				rets[rets.length] = fldsA[j];
			}
			continue;
		}
			// delete all system-fields (except _A)
			// else if (flds[i].charAt(0) == '_' && flds[i].indexOf("_A") != 0)
		else if (flds[i].charAt(0) == '_')
			continue;

		rets[rets.length] = flds[i];
	}

	return rets;
}

function countChar(c, sString)
{
	var count = 0;
	var pos = -1;
	do
	{
		pos = sString.indexOf(c, pos + 1);
		if (pos < 0)
			return count;

		count++;
	}
	while (pos > 0);

	return count;
}

/**
 * Parse numbers using locale conventions that may differ from the ones set
 * for the current web browser.
 *
 * Example: parse 1.123,12 to 1123,12
 */
function opsjParseFloat(sString)
{
	sString = "" + sString;

	// ==> Need for Check of
	//     Thousand-Seperator: &nbsp (used like in french, czeck or hungarian)
	//     seems like Browser changes Seperator "&nbsp" into " " (Space)
	var nbsp = String.fromCharCode(160);
	if (separator == nbsp)
	{
		sString = replaceAll(sString," ",'');
	}
	// <==


	sString = replaceAll(sString, separator, '');
	sString = replaceAll(sString, decpoint, '.');
	return parseFloat(sString, 10);
}

/**
 * Parse 1.123,12 to 1123
 */
function opsjParseInt(sString)
{
	sString = "" + sString;

	// ==> Need for Check of
	//     Thousand-Seperator: &nbsp (used like in french, czeck or hungarian)
	//     seems like Browser changes Seperator "&nbsp" into " " (Space)
	var nbsp = String.fromCharCode(160);
	if (separator == nbsp)
	{
		sString = replaceAll(sString," ",'');
	}
	
	sString = replaceAll(sString, separator, '');
	sString = replaceAll(sString, decpoint, '.');
	return parseInt(sString, 10);
}

/**
 * Replace all occurences of sMatch by sReplace
 */
function replaceAll(sString, sMatch, sReplace)
{
	var sStringOld;

	do
	{
		sStringOld = sString;
		sString = sString.replace(sMatch, sReplace);
	}
	while (sString != sStringOld);

	return sString;
}

/**
 * Format Number 1123.1 to 1.123,1 (depeding on locales, see header of script)
 */
function toNumber(val)
{
	return formatNumber(val, "#,##0.####");
}

/**
 * Format Number 1123.1 to 1.123,10 (depeding on locales, see header of script)
 */
function toNumber2NK(val)
{
	return formatNumber(val, "#,##0.00");
}

/**
 * Format Number 1123.1 to 1.123,1 (depeding on locales, see header of script)
 */
function toNumber1NK(val)
{
	return formatNumber(val, "#,##0.0");
}

/**
 * Format Number 1123.1 to 1.123 (depeding on locales, see header of script)
 */
function toNumber0NK(val)
{
	return formatNumber(val, "#,##0");
}

// Original JavaScript code by Duncan Crombie: dcrombie@chirp.com.au
// Please acknowledge use of this code by including this header.

// OPS/IM always use "," as group, "." as comma, "$" as currency and "%" as percent in format string !!!
function formatNumber(number, format, print)
{  // use: formatNumber(number, "format")
	if (print) document.write("formatNumber(" + number + ", \"" + format + "\")<br>");

	if (number - 0 != number) return null;  // if number is NaN return null
	var useSeparator = format.indexOf(',') != -1;
	// use separators in number
	var usePercent = format.indexOf('%') != -1;
	// convert output to percentage
	var useCurrency = format.indexOf('$') != -1;
	// use currency format
	var isNegative = (number < 0);
	number = Math.abs(number);
	if (usePercent) number *= 100;
	format = strip(format, ",%$");
	// remove key characters
	number = "" + number;
	// convert number input to string

	// split input value into LHS and RHS using decpoint as divider
	//	var dec = number.indexOf(decpoint) != -1;
	var dec = number.indexOf('.') != -1;
	var nleftEnd = (dec) ? number.substring(0, number.indexOf('.')) : number;
	var nrightEnd = (dec) ? number.substring(number.indexOf('.') + 1) : "";

	// split format string into LHS and RHS using decpoint as divider
	//	dec = format.indexOf(decpoint) != -1;
	dec = format.indexOf('.') != -1;
	var sleftEnd = (dec) ? format.substring(0, format.indexOf('.')) : format;
	var srightEnd = (dec) ? format.substring(format.indexOf('.') + 1) : "";

	// adjust decimal places by cropping or adding zeros to LHS of number
	if (srightEnd.length < nrightEnd.length)
	{
		var nextChar = nrightEnd.charAt(srightEnd.length) - 0;
		nrightEnd = nrightEnd.substring(0, srightEnd.length);
		if (nextChar >= 5) nrightEnd = "" + ((nrightEnd - 0) + 1);  // round up

		// patch provided by Patti Marcoux 1999/08/06
		while (srightEnd.length > nrightEnd.length)
		{
			nrightEnd = "0" + nrightEnd;
		}

		if (srightEnd.length < nrightEnd.length)
		{
			nrightEnd = nrightEnd.substring(1);
			nleftEnd = (nleftEnd - 0) + 1;
		}
	}
	else
	{
		for (var i = nrightEnd.length; srightEnd.length > nrightEnd.length; i++)
		{
			if (srightEnd.charAt(i) == "0") nrightEnd += "0";  // append zero to RHS of number
			else break;
		}
	}

	// adjust leading zeros
	sleftEnd = strip(sleftEnd, "#");
	// remove hashes from LHS of format
	while (sleftEnd.length > nleftEnd.length)
	{
		nleftEnd = "0" + nleftEnd;
		// prepend zero to LHS of number
	}

	if (useSeparator) nleftEnd = separate(nleftEnd, separator);  // add separator
	var output = nleftEnd + ((nrightEnd != "") ? decpoint + nrightEnd : "");
	// combine parts
	if (isNegative)
	{
		// patch suggested by Tom Denn 25/4/2001
		//	  output = (useCurrency) ? "(" + output + ")" : "-" + output;
		output = "-" + output;
	}
	output = ((useCurrency) ? currency : "") + output + ((usePercent) ? percent : "");

	return output;
}

/**
 * removes all chars from input
 */
function strip(input, chars)
{  // strip all characters in 'chars' from input
	var output = "";
	// initialise output string
	for (var i = 0; i < input.length; i++)
		if (chars.indexOf(input.charAt(i)) == -1)
			output += input.charAt(i);
	return output;
}

/**
 * separate input by separator on 000s boundaries
 */
function separate(input, separator)
{  // format input using 'separator' to mark 000s
	input = "" + input;
	var output = "";
	// initialise output string
	for (var i = 0; i < input.length; i++)
	{
		if (i != 0 && (input.length - i) % 3 == 0) output += separator;
		output += input.charAt(i);
	}
	return output;
}

// GS20010920 ==>
/**
 * returns the absolute y coord of an element on the page
 */
function opsjGetAbsoluteY(el)
{
	var off = el.offsetTop;
	while (el.offsetParent != null)
	{
		el = el.offsetParent
		off += el.offsetTop;
	}
	return off;
}

/**
 * returns the absolute x coord of an element on the page
 */
function opsjGetAbsoluteX(el)
{
	var off = el.offsetLeft;
	while (el.offsetParent != null)
	{
		el = el.offsetParent
		off += el.offsetLeft;
	}
	return off;
}
// GS20010920 <==

// GS20020708 ==>
/**
 * resizes the current window to its contents
 * the windows size does never shrink
 * the position does not change
 */
function opsjResizeToContent()
{
	if (!ie)
		return;
	if (document.body.scrollHeight > window.clientHeight)
	{	// scrolling is needed
		var nMaxHeight = screen.Height - 20 * 2;
		// 20*2 to accomodate for window borders & captions
		nMaxHeight -= window.screenTop;
		var nNewHeight = document.body.scrollHeight > nMaxHeight ? nMaxHeight : document.body.scrollHeight;
		window.resizeBy(0, -window.clientHeight + nNewHeight);
	}
}

/**
 ==================================================================
 LTrim(string) : Returns a copy of a string without leading spaces.
 ==================================================================
 */
function LTrim(str)
	/*
	PURPOSE: Remove leading blanks from our string.
	IN: str - the string we want to LTrim
 */
{
	var whitespace = new String(" \t\n\r");

	var s = new String(str);

	if (whitespace.indexOf(s.charAt(0)) != -1)
	{
		// We have a string with leading blank(s)...

		var j = 0, i = s.length;

		// Iterate from the far left of string until we
		// don't have any more whitespace...
		while (j < i && whitespace.indexOf(s.charAt(j)) != -1)
			j++;

		// Get the substring from the first non-whitespace
		// character to the end of the string...
		s = s.substring(j, i);
	}
	return s;
}

/**
 ==================================================================
 RTrim(string) : Returns a copy of a string without trailing spaces.
 ==================================================================
 */
function RTrim(str)
	/*
	PURPOSE: Remove trailing blanks from our string.
	IN: str - the string we want to RTrim

 */
{
	// We don't want to trip JUST spaces, but also tabs,
	// line feeds, etc.  Add anything else you want to
	// "trim" here in Whitespace
	var whitespace = new String(" \t\n\r");

	var s = new String(str);

	if (whitespace.indexOf(s.charAt(s.length - 1)) != -1)
	{
		// We have a string with trailing blank(s)...

		var i = s.length - 1;
		// Get length of string

		// Iterate from the far right of string until we
		// don't have any more whitespace...
		while (i >= 0 && whitespace.indexOf(s.charAt(i)) != -1)
			i--;


		// Get the substring from the front of the string to
		// where the last non-whitespace character is...
		s = s.substring(0, i + 1);
	}

	return s;
}

/**
 =============================================================
 Trim(string) : Returns a copy of a string without leading or trailing spaces
 =============================================================
 */
function Trim(str)
	/*
	PURPOSE: Remove trailing and leading blanks from our string.
	IN: str - the string we want to Trim

	RETVAL: A Trimmed string!
 */
{
	return RTrim(LTrim(str));
}

/**
 Strips the "identifier" from the String
 e.g.:
 Input: "Menge: 1"
 Output: "1"
 */
function stripIdent(str)
{
	return str.replace(/^.*:\s*/, "");
}

/**
 gets the "identifier" from the String
 e.g.:
 Input: "Menge: 1"
 Output: "Menge"
 */
function getIdent(str)
{
	return str.replace(/:.*$/, "");
}

function opsjSubmitForm(form)
{
    if(form.onsubmit)
    {
        var result=form.onsubmit();
        if((typeof result=='undefined')||result)
        {
            form.submit();
            return true;
        }
    }
    else
    {
        form.submit();
        return true;
    }

    return false;
}
/**
 Ein Form-Target in beliebiger Groesse erstellen.
 see. LayoutHeaderSmallUndockable.jsp
 */
function submitFormInWindow(form, idlePage)
{
	var _target = form.target;
	var _colon = _target.indexOf(":");

	if (_colon != -1)
	{
		form.target = _target.substring(0, _colon);
		form.args = _target.substring(_colon + 1);
	}
	else if (typeof(form.args) == "undefined")
	{
		form.args = "";
	}

	if (form.args.indexOf("{") != -1)
	{
		var _args = form.args.split("{");
		form.args = _args[0];
		for (var i = 1; i < _args.length; i++)
		{
			_args[i] = _args[i].split("}");
			form.args += eval(_args[i][0]) + _args[i][1];
		}
	}

	form.args = form.args.replace(/ /g, "");

	// var _win = window.open(idlePage,form.target,form.args);
	if (!form.name)
	{
		// fake a name
		form.name = "__frmPost";
	}
	var _win = window.open(idlePage + "?" + form.name, form.target, form.args);

	if (typeof(focus) == "function")
	{
		_win.focus();
	}
	return _win;
}

/*
	Eine "modale" Auswahlmaske mit drei Auswahlm??glichkeiten.
	Aufruf: yesnocancel('Wollen sie a b oder c?', '_a_', '_b_', '_c_', 'meine_aktion')

	Dabei muss es die Funktion "meine_aktion" geben:
    function meine_aktion(result)
    {
    	alert("do: " + result);
    }

	nichts=-1
	yes=0
	no=1
	cancel=2

*/
var yesnocancel_win = null;
var yesnocancel_onaction = null;

function yesnocancel_check()
{
	if (!yesnocancel_win.closed)
	{
		setTimeout("yesnocancel_check()", 50);
	}
	else
	{
		eval(yesnocancel_onaction + "(" + window.yesnocancel_result + ")");
	}
}

function yesnocancel(text, yesText, noText, cancelText, onaction)
{
	window.yesnocancel_result = -1;
	window.yesnocancel_onaction = onaction;

	var win = window.open('about:blank', 'yesnocancel', "width=500,height=100,resizable=no,scrollbars=no,location=no,menubar=no,status=no,toolbar=no,depend=yes,screenX=100,screenY=100");
	yesnocancel_win = win;

	setTimeout("yesnocancel_check()", 50);

	win.document.writeln("<html><head><title>Frage</title></head><body style='font-family: sans-serif; background-color: #FBF5E3' onblur='window.close()'>");
	win.document.writeln(text);
	win.document.writeln("<br />");
	win.document.writeln("<br />");
	win.document.writeln("<table width='100%'><tr><td align='left'>");
	win.document.writeln("<input type='button' value='" + cancelText + "' onclick='javascript:window.opener.yesnocancel_result=2; window.close()' />");
	win.document.writeln("</td><td align='right'>");
	win.document.writeln("<input type='button' value='" + yesText + "' onclick='javascript:window.opener.yesnocancel_result=0; window.close()' />");
	win.document.writeln("<input type='button' value='" + noText + "' onclick='javascript:window.opener.yesnocancel_result=1; window.close()' />");
	win.document.writeln("</td></tr></table>");
	win.document.writeln("</body></html>");
	win.document.close();

	win.focus();
}

function navHover(element)
{
	element.className = "menuHeader_hover";
}

function navUnHover(element)
{
	element.className = "menuHeader";
}

function ou_setEmptyPage(emptyPage)
{
	ou_emptyPage = emptyPage;
}

function subNavWindow(name, url)
{
	window.open(url, name, 'resizable=yes,scrollbars=yes,location=no,menubar=no,status=no,toolbar=no');
}

function docViewWindow(name, url)
{
	window.open(url, name, 'resizable=yes,scrollbars=yes,location=no,menubar=yes,status=no,toolbar=no');
}

function toggleDisplay(id)
{
	od_setHide(id, !od_isHidden(id));
}

/**
 * decodes all &#nnn; in the given text to its corresponding character
 */
function opsjDecodeHexEntity(text)
{
	var entitySearch = /&#[0-9]+;/g;
	var entity;
	while (entity = entitySearch.exec(text))
	{
		var charCode = entity[0].substring(2, entity[0].length - 1);
		text = text.substring(0, entity.index)
			+ String.fromCharCode(charCode)
			+ text.substring(entity.index + entity[0].length);
	}

	return text;
}

function editText(event, source, key)
{
	if (!event)
	{
		event = window.event;
	}

	if (!source)
	{
		source = od_getParent(od_getEventTarget(event));
	}

	var text = source.previousSibling;
	if (text)
	{
		if (text.innerHTML)
		{
			text = od_getInnerText(text);
		}
		else
		{
			text = text.nodeValue;
		}

		text = od_escape(text);
	}

	var link;
	if (key)
	{
		link = key + "&display=" + text;
	}
	else
	{
		link = source.href + "&display=" + text;
	}

	var win = window.open(link, "editText", "width=800,height=400,resizable=yes,scrollbars=yes,location=no,menubar=no,status=no,toolbar=no");
	win.focus();

	od_doDefault(event, false);
	return false;
}

function toggleLayHeaderSelTx()
{
	var layHeaderSel = document.getElementById("layHeaderSel");
	var layHeaderSelTr = document.getElementById("layHeaderSelTr");

	if (od_isHidden(layHeaderSel))
	{
		var top = od_getAbsoluteTop(layHeaderSelTr);
		var left = od_getAbsoluteLeft(layHeaderSelTr);
		od_setStyleLeft(layHeaderSel, left - 80);
		od_setStyleTop(layHeaderSel, top + 15);
	}

	od_setHide(layHeaderSel, !od_isHidden(layHeaderSel));
}

function opsjSetSelectedStyle(element, activeStyle, inactiveStyle, active)
{
	var className = element.className;
	var toRemove, toSet;
	if (active)
	{
		toRemove = inactiveStyle;
		toSet = activeStyle;
	}
	else
	{
		toRemove = activeStyle;
		toSet = inactiveStyle;
	}

	var pos = className.indexOf(toRemove);
	if (pos > -1)
	{
		className = className.substring(0, pos) + className.substring(pos + toRemove.length);
	}

	if (className.indexOf(toSet + " ") > -1 || (className.indexOf(toSet) + toSet.length) == className.length)
	{
		// we are done
		element.className = className;

		return;
	}

	if (className.lastIndexOf(" ") + 1 != className.length)
	{
		className = className + " ";
	}
	className = className + toSet;

	element.className = className;
}

function opsjSetFullHeight(element)
{
	var posY = od_getAbsoluteTop(element);
	var clientHeight = od_getClientHeight();
	var height = clientHeight - posY - 30;

	element.height = height;
}

// Create an XMLHttpRequest object in any browser.
// Throws an exception if an instance cannot be created. 
function opsjNewXMLHttpRequest()
{
  try {return new XMLHttpRequest();} catch(e) {}
  try {return new ActiveXObject("Msxml2.XMLHTTP");} catch(e) {}
  try {return new ActiveXObject("Microsoft.XMLHTTP");} catch(e) {}

  // oddly, we get this in some cases for IE6. It appears that the browser claims
  // to have a native XMLHttpRequest (ie typeof XMLHttpRequest == "function") but 
  // calling it results in an exception. And the activex equivalents are not available.
  //
  // Possibly this error is actually coming from the Sarissa js library, which is used
  // by RichFaces (and by Tomahawk inputHtml, but we don't often use that component). It
  // is possible that the problem is due to the sarissa library overriding the standard
  // XMLHttpRequest method, and then failing in some environments. Certainly RichFaces
  // uses sarissa, and the actual exception that "new XMLHttpRequest" is throwing in the
  // problems cases is "Could not retrieve a valid progID or Class: Microsoft.XMLHTTP";
  // googling for that matches some sarissa code.
  opsjLog("Unable to create XMLHttpRequest instance");
  throw new Error("Unable to create XMLHttpRequest instance");
}

// Send a request to the server, and when the request is complete then
// invoke the provided callback passing an XMLHttpRequest object containing
// the response status and data.
//
// When the "async" param is false, this call blocks until the request is complete
// (and the callback function has run). When async is true, this function returns
// immediately.
//
// The callback function is invoked when the request is "complete", but it is
// up to the function to check for success or failure. Note that this is
// potentially browser-specific:
// * For firefox, a request to a non-running server returns rather quickly
//   (when tcp socket connection fails). Oddly, the status property of the
//   request object is set to 0 rather than 404 or similar. But this would be
//   sufficient for checking.
// * IE6 however still returns status==200 when the server is down.
// Therefore the callback function really needs to test whether there is data
// in xmlHttp.responseXML rather than testing the status property.
//
// This function throws an exception if the browser does not support XMLHttpRequest.
function opsjExecuteAjax(url, callback, async)
{
    opsjLog("creating ajax request to [" + url + "]");
	var xmlHttp = opsjNewXMLHttpRequest();
	xmlHttp.open('GET', url, async);
	if (async)
	{
		xmlHttp.onreadystatechange = function()
		{
			if (xmlHttp.readyState == 4)
			{
				callback(xmlHttp);
			}
		};
        xmlHttp.send(null);
	}
	else
	{
        xmlHttp.send(null);
		if (xmlHttp.readyState == 4)
		{
			callback(xmlHttp);
		}
	}
}

function opsjSetFormArguments(win, frm, urlString)
{
	var flds = opsjSplitUrl(urlString);
	for (var argIndex = 0; argIndex < flds.length; argIndex++)
	{
		var arg = opsjExtractArg(flds[argIndex]);
		var argName = arg[0];
		var argValue = arg[1];

		var inputElement = frm[argName];

		if (!inputElement)
		{
			inputElement = win.document.createElement("input");
			inputElement.setAttribute("type", "hidden");
			inputElement.setAttribute("name", argName);
			frm.appendChild(inputElement);
		}
		inputElement.setAttribute("value", opsjUrlDecode(argValue));
	}
}

/**
 decodes a url-encoded string
 Notice: This way might not be UTF-8 compatible yet, search the net about a replacement for this method
 once this requirement pops up.
 */
function opsjUrlDecode(str)
{
	if (str)
	{
		return unescape(str.replace(/\+/g, " "));
	}

	return null;
}

function opsjRegisterAlertKeypress()
{
	var alertDiv = document.getElementById(alertBoxId)
	if (alertDiv != null)
	{
		var oriOnkeydown = document.onkeydown;
		document.onkeydown = function(event)
		{
			if (!event)
				event = window.event;

			if (event.keyCode == 27) // esc
			{
				opsjAlertDismiss();
			}

			if (oriOnkeydown)
			{
				oriOnkeydown(event);
			}
		};
	}
}

function opsjAlertDismiss()
{
	var alertDiv = document.getElementById(alertBoxId)
	if (alertDiv != null)
	{
		od_setHide(alertDiv, true);
	}
}

function opsjAlertKeypress(event)
{
	var alertDiv = document.getElementById(alertBoxId)
	if (alertDiv != null)
	{
		if (!event)
		{
			event = window.event;
		}

		if (event.keyCode == 27) // esc
		{
			opsjAlertDismiss();
		}
	}
}

function opsjShowAlert(str)
{
	var alertDiv = document.getElementById(alertBoxId)
	if (alertDiv != null)
	{
		var textDiv = document.getElementById(alertBoxTextId);
		textDiv.childNodes[0].nodeValue = str;

		od_setHide(alertDiv, false);
	}
	else
	{
		alert(str);
	}
}

function opsjIsDigits(text)
{
	var validChars = "0123456789";

	for (var i = 0; i < text.length; i++)
	{
		var c = text.charAt(i);
		if (validChars.indexOf(c) == -1)
		{
			return false;
		}
	}

	return true;

}

function opsjSetFocus(element)
{
	if (element && element.focus)
	{
		setTimeout(function()
		{
			if (element.select)
			{
				element.select();
			}
			element.focus();
		},100);
	}
}


// special function for RichFacesCalenar to disable all WeekDay except Monday (used as YearWeek selector)
function firstWeekDayFunction(day)
{
    /*
    if (curRichDt==undefined)
    {
        curRichDt = day.date.getDate();
    }
    */

    if (day.isWeekend) return false;
    if (day.date.getDay() != 1) return false;
    else
        return true;
}

function disabledClassesProv(day)
{
    if (day.date.getDay() != 1)
        return 'rich-calendar-boundary-dates';
    else
        return 'everyThirdDay';

}
