//var _IsIE = /Microsoft Internet Explorer/.test(navigator.appName);
var _IsIE = (window.ActiveXObject != undefined);
var _bIsMobile = false; // Will be set dynamically
var _bIsIPhone = /iPhone/.test(navigator.userAgent);

var nMobileHeaderHeight = 36;

function HandleSessionExpired()
{
	// No url to 'session expired' page, just reloading ourself will redirect to the login page
	//alert('session expired');
	if (window.opener != null)
	{
		window.opener.location.href = window.opener.location.href;
		window.close();
	}
	else
	{
		top.location.href = top.location.href;
	}
}

function HandleSessionExpiredUrl(url)
{
	//alert('session expired');
	if (window.opener != null)
	{
		window.opener.location.href = url;
		window.close();
	}
	else
	{
		top.location.href = url;
	}
}

function loadJSFile(id, filePath)
{
	var script = document.getElementById(id);
	if (script == null)
	{
		script = document.createElement('SCRIPT');
		script.setAttribute('id', id);
		script.setAttribute('type', 'text/javascript');
		script.setAttribute('src', filePath);
		document.getElementsByTagName('HEAD')[0].appendChild(script);
	}
}

// VAU Vocal Activity Update
// BRF Badge Reload Full ?
// SPR pointer to object that implements bt_fullScreen_click for documents ???
var _bBRF = false;
var _VAU = '';
var _SPR = null;

function SetBRF(vf)
{
	_bBRF = vf;
}
function GetBRF()
{
	return _bBRF;
}

function SetVAU(vau)
{
	_VAU = vau;
}
function GetVAU()
{
	return _VAU;
}

function SetSPR(spr)
{
	_SPR = spr;
}
function GetSPR()
{
	return _SPR;
}

// -- Badge menu --

var oBadgeMenu;
var _isBadgesUpdatesUnderway = false;

function SetIsBadgesUpdatesUnderway(value)
{
	_isBadgesUpdatesUnderway = value;
}

function openPopUp()
{
	try
	{
		if (_isBadgesUpdatesUnderway)
		{
			//window.setTimeout(openPopUp(), 200);
			return;
		}

		if (oBadgeMenu != null)
		{
			oBadgeMenu.style.display = ''; //'block';
		}
	}
	catch (exception)
	{
		//alert('openPopUp ' + exception.message);
	}
}

function closePopUp()
{
	try
	{
		if (oBadgeMenu != null)
		{
			oBadgeMenu.style.display = 'none';
		}
	}
	catch (exception)
	{
		//alert('closePopUp ' + exception.message);
	}
}

var scrollTopBadge = 0;

function alignPopUp()
{
	try
	{
		if (oBadgeMenu != null)
		{
			oBadgeMenu.style.position = 'absolute';
			if (_bIsMobile)
			{
				oBadgeMenu.style.left = '0px';
				oBadgeMenu.style.top = nMobileHeaderHeight + 'px';

				oBadgeMenu.style.width = document.body.clientWidth + 'px';
				if (document.body.scrollHeight > 0)
					oBadgeMenu.style.height = (document.body.scrollHeight - nMobileHeaderHeight) + 'px';
				else
					oBadgeMenu.style.height = (document.body.clientHeight - nMobileHeaderHeight) + 'px';

				oBadgeMenu.style.display = ''; //'block';

				// Save badge position to scroll back to it
				//scrollTopBadge = offsetTop - scrollTop - 50; // -50 top bring it down a little
				// Save current scroll postion to scroll back to it (first is for IE, second is for FF, the other is always zero so we can just add them)
				scrollTopBadge = document.body.parentNode.scrollTop + document.body.scrollTop;
				// Scroll to menu
				scrollToOffset(nMobileHeaderHeight);
			}
			else
			{
				var sParentId = oBadgeMenu.getAttribute('parentId');
				var oParent = document.getElementById(sParentId);

				if (oParent != null)
				{
					// @THB 03/2009
					// In FF&Safari, only BODY, TABLE and TD count in "offset" hierarchy
					// and the offsetParent of absolute positioning is the BODY
					// In IE, DIV also counts in the "offset" hierarchy
					// and the offsetParent of absolute positioning seems to be nearest scroll client (for instance a DIV inside another scrolling DIV)
					// If the scrolling is done by a DIV inside a DIV (as in ScreenParticipant.ascx), FF&Safari miss the scrolling DIV in the "offset" hierarchy
					// So we must add every offset in "offset" hierarchy up to the absolute positioning parent
					// And then substract any scrolling in the regular "node" hierarchy

					var oBaseParent = null;
					if (_bIsMobile)
					{
						oBaseParent = oParent;
					}
					else
					{
						oBaseParent = oParent.offsetParent.offsetParent;
					}

					// Must display before using oBadgeMenu.offsetParent safely
					oBadgeMenu.style.display = ''; //'block';

					var offsetLeft = 0;
					var offsetTop = 0;
					var oContainer = oBaseParent;
					while (oContainer != oBadgeMenu.offsetParent && oContainer != null)
					{
						offsetLeft += oContainer.offsetLeft;
						offsetTop += oContainer.offsetTop;
						oContainer = oContainer.offsetParent;
					}

					var scrollLeft = 0;
					var scrollTop = 0;
					oContainer = oBaseParent;
					while (oContainer != oBadgeMenu.offsetParent && oContainer != null)
					{
						scrollLeft += oContainer.scrollLeft;
						scrollTop += oContainer.scrollTop;
						oContainer = oContainer.parentNode;
					}

					oBadgeMenu.style.width = oBaseParent.offsetWidth + 'px';
					oBadgeMenu.style.height = 'auto';
					oBadgeMenu.style.left = (offsetLeft - scrollLeft) + 'px';
					// -1 to overlap menu border with badge border
					oBadgeMenu.style.top = (offsetTop - scrollTop + oBaseParent.offsetHeight - 1) + 'px';
				}
			}
		}
	}
	catch (exception)
	{
		alert(exception);
	}
}

function closeAllPopUpAsync()
{
	window.setTimeout(closeAllPopUp, 0);
}

function closeAllPopUp()
{
	closePopUp();
	if (_bIsMobile)
	{
		scrollToOffset(scrollTopBadge);
	}
}

function openBadgeMenu(sBadgeMenuId)
{
	try
	{
		if (_isBadgesUpdatesUnderway)
		{
			//window.setTimeout(openBadgeMenu(sBadgeMenuId), 200);
			return;
		}

		if (oBadgeMenu != document.getElementById(sBadgeMenuId))
		{
			closePopUp();
		}
		oBadgeMenu = document.getElementById(sBadgeMenuId);

		if (oBadgeMenu.style.display == 'none')
		{
			alignPopUp();

			oBadgeMenu.ondrag = 'return false'; //inhibit event, only click allowed to cause an action
			oBadgeMenu.oncontextmenu = 'return false'; //inhibit event, only click allowed to cause an action
			if (!_bIsMobile)
			{
				oBadgeMenu.onmouseover = openPopUp;
				oBadgeMenu.onmouseout = closePopUp;
			}
		}
		else
		{
			closeAllPopUp();
		}
	}
	catch (exception)
	{
		alert(exception);
	}
}

var _imgClientId = '';
var _btnClientId = '';
var _actionCommand;

function InitializeSourceForDefaultNewButton(imgClientId, btnClientId, actionCommand, imageUrlForNewCommand)
{
	_imgClientId = imgClientId;
	_btnClientId = btnClientId;
	ChangeSourceForDefaultNewButton(actionCommand, imageUrlForNewCommand);
}

function ChangeSourceForDefaultNewButton(actionCommand, imageUrlForNewCommand)
{
	if (document.getElementById(_imgClientId) != null)
	{
		document.getElementById(_imgClientId).src = imageUrlForNewCommand;
	}
	if (document.getElementById(_btnClientId) != null)
	{
		_actionCommand = actionCommand;
		document.getElementById(_btnClientId).onclick = ActionNew;
	}
}


function ActionNew()
{
	hideMenu();
	eval(_actionCommand);
}

function SelectFunctionContainerInProgress(functionContainer, functionText)
{
	document.getElementById(functionContainer).className = 'functionContainerDisplayStateInProgress';
	document.getElementById(functionText).className = 'functionMenuDisplayStateInProgress_N';
}

function DeselectFunction(index)
{
	var functionContainer = _ucFunctionsHolderClientId + '_' + '_ctl0_' + 'functionsRepeater' + '_' + '_ctl' + index + '_' + '_ctl0_' + 'functionContainer';
	var functionText = _ucFunctionsHolderClientId + '_' + '_ctl0_' + 'functionsRepeater' + '_' + '_ctl' + index + '_' + '_ctl0_' + 'functionText';

	if (document.getElementById(functionContainer) != null)
		document.getElementById(functionContainer).className = 'functionContainer';

	if (document.getElementById(functionText) != null)
		document.getElementById(functionText).className = 'functionMenu_N';
}

// ugly(tm) only work for up to 10 menu elements (...)
function DeselectAllFunctions(ignoreIfModalWindowIsOpen)
{
	var myIframe = null;
	if (ignoreIfModalWindowIsOpen)
	{
		myIframe = document.getElementById('RSIFrame');
	}

	if (myIframe == null || myIframe.style.display == 'none')
	{
		for (index = 0; index <= 10; index++)
		{
			DeselectFunction(index);
		}
	}
}


var _focusControl = null;

function updateFocus()
{
	if (_focusControl != null)
	{
		try
		{
			_focusControl.focus();
		}
		catch (exception)
		{
			// Focus may throw if the control is burried inside some invisible containers, who cares...
		}
	}
}

function setFocus(ctrl, bInIFrameDialog)
{
	_focusControl = ctrl;
	// That Firefox bug comes and goes, so leave this trick even if it seems useless
	if (!bInIFrameDialog)
	{
		updateFocus();
	}
	else
	{
		// updateFocus() will be called by delayedLayout() in IFrame dialogs
		// Mostly a hack because Firefox looses his marbles if we do it now ?!
	}
}

function updateLayout(sFrameId, bIsPostBack)
{
	if (parent.updateLayoutFromParent)
	{
		var root = document.body;
		// Special case not needed for IE as long a the iframe size is not O initially
		//if (_IsIE)
		//{
		//	root = document.forms[0];
		//}

		// body.scrollWidth may be zero on some fullscreen browsers (BlackBerry, etc.)
		var nWidth = root.scrollWidth;
		if (root.offsetWidth > nWidth)
			nWidth = root.offsetWidth
		var nHeight = root.scrollHeight;
		if (root.offsetHeight > nHeight)
			nHeight = root.offsetHeight

		parent.updateLayoutFromParent(sFrameId, bIsPostBack, nWidth, nHeight);
	}
}

function delayedLayout(sFrameId, bIsPostBack)
{
	window.setTimeout(function() { updateLayout(sFrameId, bIsPostBack); }, 0);
	window.setTimeout(function() { updateFocus(); }, 0);
	// Again in 2 seconds because browser may react slowly (scrollbars appearing may require to center again, etc.)
	window.setTimeout(function() { updateLayout(sFrameId, bIsPostBack); }, 2000);
}


// If sFrameId is null or empty it's the generic iframe (actual ID 'RSIFrame')
// else it's a custom iFrame (IFrame on top of 'RSIFrame')
function get_iframeId(sFrameId)
{
	var sActualFrameId;

	if (sFrameId == null || sFrameId == '')
	{
		sActualFrameId = 'RSIFrame';
	}
	else
	{
		sActualFrameId = sFrameId;
	}

	return sActualFrameId;
}

function open_iframe(sFrameId, sUrl, nWidth, nHeight, bTestIFrameIsOpened)
{
	try
	{
		//alert('open_iframe(' + sFrameId + ', ' + sUrl + ', ' + nWidth + ', ' + nHeight + ', ' + bTestIFrameIsOpened + ')');
		var sActualFrameId = get_iframeId(sFrameId);
		var myIframe = document.getElementById(sActualFrameId);

		//if (myIframe != null)
		//	alert('bTestIFrameIsOpened == ' + bTestIFrameIsOpened + ' && myIframe.style.display == ' + myIframe.style.display);
		//else
		//	alert('bTestIFrameIsOpened == ' + bTestIFrameIsOpened + ' && myIframe == null');
		if (bTestIFrameIsOpened && myIframe != null && myIframe.style.display != 'none')
			return null;

		window.onresize = update_window;

		if (myIframe == null)
		{
			//alert('New IFRAME ' + sActualFrameId);
			myIframe = document.createElement('IFRAME');
			myIframe.setAttribute('id', sActualFrameId);
			myIframe.frameBorder = '0';
			myIframe.className = 'modalIFrame';
		}
		else
		{
			// Displaying it is not enough.
			// We must bring it to the front, so we detach it from where it was
			document.forms[0].removeChild(myIframe);
			// Have to display it now so that layout_iframe has some suggested size to work with
			myIframe.style.display = ''; //'block';
			// As good as new
			myIframe.style.border = '';
			myIframe.style.top = '';
			myIframe.style.left = '';
			myIframe.style.width = '';
			myIframe.style.height = '';
		}

		if (_bIsMobile)
		{
			// No sizing or centering, just fill the screen
			myIframe.style.width = '100%';
			myIframe.style.height = '100%';
			myIframe.style.left = '0px';
			myIframe.style.top = '0px';
			//myIframe.style.top = nMobileHeaderHeight + 'px'; // Let header show

			HideBottom();
		}
		else
		{
			myIframe['customWidth'] = nWidth;
			myIframe['customHeight'] = nHeight;

			// If size is 0 (or less ?), sizing and centering will be done in layout_iframe() after the content is loaded
			if (nWidth > 0)
			{
				myIframe.style.width = nWidth + 'px';
				var nLeft = (document.body.clientWidth - nWidth) / 2 + document.body.clientLeft;
				if (nLeft < 10)
					nLeft = 10;
				myIframe.style.left = nLeft + 'px';
			}
			else
			{
				// The default width of 300px or so, may be too wide for some boxes
				// We must put something smaller, but more than 0 to let the content's body suggest a required size (IE)
				myIframe.style.width = '20px';
			}

			if (nHeight > 0)
			{
				myIframe.style.height = nHeight + 'px';
				var nTop = (document.body.clientHeight - nHeight) / 2 + document.body.clientTop;
				if (nTop < 10)
					nTop = 10;
				myIframe.style.top = nTop + 'px';
			}
			else
			{
				// The default height of 150px or so, may be too tall for some boxes (simple question boxes)
				// We must put something smaller, but more than 0 to let the content's body suggest a required size (IE)
				myIframe.style.height = '20px';
			}
		}

		// Place to the front
		document.forms[0].appendChild(myIframe);

		myIframe.src = sUrl;

		// Don't wait, so we know something is loading
		ShowBackgroundMask(sFrameId);
	}
	catch (exception)
	{
		alert(exception);
	}
}

function updateLayoutFromParent(sFrameId, bIsPostBack, nWidth, nHeight)
{
	layout_iframe(sFrameId, nWidth, nHeight);
	if (bIsPostBack)
	{
		ResizeBackgroundMask();
	}
//	else
//	{
//		ShowBackgroundMask(sFrameId);
//	}
}

function layout_iframe(sFrameId, nWidth, nHeight)
{
	try
	{
		//alert('layout_iframe(' + sFrameId + ', ' + nWidth + ', ' + nHeight + ')');
		var sActualFrameId = get_iframeId(sFrameId);
		var myIframe = document.getElementById(sActualFrameId);

		if (myIframe != null)
		{
			if (_bIsMobile)
			{
				// If we really need to strech it beyond 100% of the background, we do
				if (myIframe.scrollHeight < nHeight)
				{
					myIframe.style.height = nHeight + 'px';
				}

				// Scroll back to top of the screen, because the page below the opening IFrame may be scrolled far down
				scrollToOffset(0);
			}
			else
			{
				// If size is 0, size iframe to it's content and center (can't be done with width/height 'auto')
				if (myIframe['customWidth'] <= 0)
				{
					myIframe.style.width = nWidth + 'px';
					var nLeft = (document.body.clientWidth - nWidth) / 2 + document.body.clientLeft;
					if (nLeft < 10)
						nLeft = 10;
					myIframe.style.left = nLeft + 'px';
				}

				if (myIframe['customHeight'] <= 0)
				{
					myIframe.style.height = nHeight + 'px';
					var nTop = (document.body.clientHeight - nHeight) / 2 + document.body.clientTop;
					if (nTop < 10)
						nTop = 10;
					myIframe.style.top = nTop + 'px';
				}

				// Put the border after laid out, only on desktop version
				// For some reason (bug ?), IE requires that we reset the border before putting it back, otherwise the iframe is blank !?
				// It doesn't help to put the border in CSS class 'modalIFrame' either.
				myIframe.style.border = '';
				myIframe.style.border = '1px solid #000000';
			}
		}
	}
	catch (exception)
	{
		alert(exception);
	}
}

function close_iframe(sFrameId)
{
	try
	{
		//alert('close_iframe(' + sFrameId + ')');
		var sActualFrameId = get_iframeId(sFrameId);
		var myIframe = document.getElementById(sActualFrameId);

		if (myIframe != null)
		{
			myIframe.style.display = 'none';
			// unloads document, but .src can't be compared to '' later, .src may still contain some characters (in Firefox, etc.)
			myIframe.src = '';
		}

		HideBackgroundMask(sFrameId);
		ResizeBackgroundMask();
		if (_bIsMobile)
		{
			// Scroll back to top of the screen, because the page below the closed IFrame may look blank far down
			scrollToOffset(0);
		}
	}
	catch (exception)
	{
		alert(exception);
	}
}

function refresh_iframe(sFrameId)
{
	try
	{
		var sActualFrameId = get_iframeId(sFrameId);
		var myIframe = document.getElementById(sActualFrameId);

		if (myIframe != null)
		{
			myIframe.src = myIframe.src;
		}
	}
	catch (exception)
	{
		alert(exception);
	}
}

//function reset_iframeSrc(sFrameId)
//{
//	try
//	{
//		var sActualFrameId = get_iframeId(sFrameId);
//		var myIframe = document.getElementById(sActualFrameId);

//		if (myIframe != null)
//		{
//			// unloads document, but .src can't be compared to '' later, .src may still contain some characters (in Firefox, etc.)
//			myIframe.src = '';
//		}
//	}
//	catch (exception)
//	{
//		alert(exception);
//	}
//}

function close_window()
{
	//alert('Are you sure you mean to close the *Window* and not some *IFrame* ?');
	window.close();
}

function update_window()
{
	ResizeBackgroundMask();
}

function HideBottom()
{
	var mainBottom = document.getElementById('mainBottom');
	if (mainBottom != null)
		mainBottom.style.display = 'none';
}

function ShowBottom()
{
	var mainBottom = document.getElementById('mainBottom');
	if (mainBottom != null)
		mainBottom.style.display = '';
}

function HideOtherIFrames(sFrameId)
{
	var sActualFrameId = get_iframeId(sFrameId);

	var iNode;
	var iLength = document.forms[0].childNodes.length;

	// reverse-iterate children until 'modalBottom'
	for (iNode = iLength - 1; iNode >= 0; iNode--)
	{
		var node = document.forms[0].childNodes[iNode];
		if (node.nodeName == 'DIV')
		{
			if (node.id == 'modalBottom')
			{
				break;
			}
		}
		else if (node.nodeName == 'IFRAME' && node.id != sActualFrameId)
		{
			node.style.display = 'none';
		}
	}
}

function ShowPreviousIFrame(sFrameId)
{
	var sActualFrameId = get_iframeId(sFrameId);

	var iNode;
	var iLength = document.forms[0].childNodes.length;

	// reverse-iterate children until 'modalBottom'
	for (iNode = iLength - 1; iNode >= 0; iNode--)
	{
		var node = document.forms[0].childNodes[iNode];
		if (node.nodeName == 'DIV')
		{
			if (node.id == 'modalBottom')
			{
				if (_bIsMobile)
				{
					ShowBottom();
				}
				break;
			}
		}
		else if (node.nodeName == 'IFRAME' && node.id != sActualFrameId && node.style.width != '0px' && node.style.height != '0px')
		{
			node.style.display = '';  //'block';
			// Break reverse-iterate now, don't show bottom
			break;
		}
	}
}


function ShowBackgroundMask(sFrameId)
{
	try
	{
		if (_bIsMobile)
		{
			//HideBottom();
		}
		else
		{
			var sActualFrameId = get_iframeId(sFrameId);

			// In desktop version, create one mask Div before every IFrame
			var sMaskId = sActualFrameId + 'MaskDiv';
			var myMaskDiv = document.getElementById(sMaskId);
			if (myMaskDiv == null)
			{
				myMaskDiv = document.createElement('DIV');
				myMaskDiv.setAttribute('id', sMaskId);
				myMaskDiv.className = 'maskDiv';

				myMaskDiv.style.top = '0px';
				myMaskDiv.style.left = '0px';
				if (_IsIE)
				{
					// Must resize manually with window.onresize in Internet Explorer
					myMaskDiv.style.position = 'absolute';
				}
				else
				{
					// Will resize automatically with those properties in other browsers
					myMaskDiv.style.position = 'fixed';
					myMaskDiv.style.width = '100%';
					myMaskDiv.style.height = '100%';
				}
			}
			else
			{
				myMaskDiv.style.display = ''; //'block';
				// Displaying it is not enough.
				// We must bring it just below the front IFrame, so we detach it from where it was
				document.forms[0].removeChild(myMaskDiv);
			}

			var myIframe = document.getElementById(sActualFrameId);
			if (myIframe != null)
			{
				// Place mask just below the front IFrame
				document.forms[0].insertBefore(myMaskDiv, myIframe);
			}
		}

		if (_bIsMobile || _bIsIPhone)
		{
			// Be lighter on mobile browser, workaround iPhone bug
			// In mobile version, only show one IFrame at a time, hide every other IFrame
			HideOtherIFrames(sFrameId);
		}

		ResizeBackgroundMask();
	}
	catch (exception)
	{
		alert(exception);
	}
}

function HideBackgroundMask(sFrameId)
{
	try
	{
		if (_bIsMobile || _bIsIPhone)
		{
			// In mobile version, show IFrame below if any (not closed IFrame with size {0, 0})
			// Only remove mask Div when there is no IFrame left
			ShowPreviousIFrame(sFrameId);
		}

		if (_bIsMobile)
		{
		}
		else
		{
			var sActualFrameId = get_iframeId(sFrameId);

			// In desktop version, hide mask Div below each IFrame
			var sMaskId = sActualFrameId + 'MaskDiv';
			var myMaskDiv = document.getElementById(sMaskId);
			if (myMaskDiv != null)
			{
				myMaskDiv.style.display = 'none';
			}
		}
	}
	catch (exception)
	{
		alert(exception);
	}
}

function ResizeBackgroundMask()
{
	var iNode;
	var iLength = document.forms[0].childNodes.length;

	// reverse-iterate children until 'modalBottom'
	for (iNode = iLength - 1; iNode >= 0; iNode--)
	{
		var node = document.forms[0].childNodes[iNode];
		if (node.nodeName == 'DIV')
		{
			if (node.id == 'modalBottom')
			{
				// We reached 'modalBottom', stop looking for maskDiv to resize
				break;
			}
			else if (node.className == 'maskDiv' && node.style.display != 'none')
			{
				if (_IsIE)
				{
					// Must resize manually with window.onresize in Internet Explorer
					// Will resize automatically in other browsers
					node.style.width = document.forms[0].scrollWidth + 'px';
					node.style.height = document.forms[0].scrollHeight + 'px';
				}
			}
		}
	}
}

function showLoadingDiv(idDiv, message)
{
	var myLoadDiv = document.getElementById(idDiv);
	if (myLoadDiv != null)
	{
		// Only change message if there isn't alreay one
		if (myLoadDiv.style.display == 'none')
		{
			myLoadDiv.innerHTML = message;
			myLoadDiv.style.display = '';
		}
	}
}

function hideLoadingDiv(idDiv)
{
	var myLoadDiv = document.getElementById(idDiv);
	if (myLoadDiv != null)
	{
		myLoadDiv.innerHTML = '';
		myLoadDiv.style.display = 'none';
	}
}

var _sLoadingMsg = '...';

function showLoading()
{
	showLoadingDiv('LoadDiv', _sLoadingMsg);
}

function hideLoading()
{
	hideLoadingDiv('LoadDiv');
}

function scrollToOffset(offset)
{
	window.scrollTo(0, offset);
}

function scrollToCtrl(ctrl)
{
	scrollToCtrlOffset(ctrl, 0);
}

function scrollToCtrlOffset(ctrl, ctrlOffset)
{
	// @THB 03/2009 see Library.js alignPopUp() if you get compatibility problems between IE, FF or Safari
	var scrollHeight = 0;
	var oContainer = ctrl;
	while (oContainer != ctrl.ownerDocument.body)
	{
		scrollHeight += oContainer.offsetTop;
		scrollHeight -= oContainer.scrollTop;
		oContainer = oContainer.offsetParent;
	}

	scrollToOffset(scrollHeight + ctrlOffset);
}

function genericHover(ctrl, bHighlight)
{
	if (bHighlight)
	{
		ctrl.className = ctrl.className.replace('_N', '_H');
	}
	else
	{
		ctrl.className = ctrl.className.replace('_H', '_N');
		ctrl.className = ctrl.className.replace('_C', '_N');
	}
}

function genericDown(ctrl, bDown)
{
	if (bDown)
	{
		ctrl.className = ctrl.className.replace('_N', '_C');
		ctrl.className = ctrl.className.replace('_H', '_C');
	}
	else
	{
		ctrl.className = ctrl.className.replace('_C', '_H');
	}
}

function genericToggle(titleId, ctrlId)
{
	var title = document.getElementById(titleId);
	var ctrl = document.getElementById(ctrlId);
	if (title != null)
	{
		if (0 <= title.className.indexOf('_O'))
		{
			title.className = title.className.replace('_O', '_X');
			if (ctrl != null)
			{
				ctrl.className = ctrl.className.replace('_O', '_X');
			}
		}
		else
		{
			title.className = title.className.replace('_X', '_O');
			if (ctrl != null)
			{
				ctrl.className = ctrl.className.replace('_X', '_O');
			}
		}
	}
}

function genericMobileToggle(titleId, ctrlId)
{
	if (_bIsMobile)
	{
		genericToggle(titleId, ctrlId);
	}
}

// List selection CSS changer
function setSelectedItem(itemId, parentnode, classextension)
{
	var item = document.getElementById(itemId);
	if (item)
	{
		var arraySpan;
		// Find previously selected span
		if (_oItemSelected == null)
		{
			arraySpan = document.getElementById(parentnode).getElementsByTagName('SPAN');
			for (i = 0; i < arraySpan.length; i++)
			{
				if (arraySpan[i].className.match(classextension))
				{
					_oItemSelected = arraySpan[i];
					break;
				}
			}
		}

		// Find previously selected tr
		if (_oItemSelected == null)
		{
			var arrayTr = document.getElementById(parentnode).getElementsByTagName('TR');
			for (i = 0; i < arrayTr.length; i++)
			{
				if (arrayTr[i].className.match(classextension))
				{
					_oItemSelected = arrayTr[i];
					break;
				}
			}
		}

		if (_oItemSelected != item)
		{
			if (_oItemSelected != null)
			{
				_oItemSelected.className = (_oItemSelected.className.replace('_H', '')).replace('_S', '');
				_oItemSelected.style.backgroundColor = '';

				// Unselect previous bullet item spans
				arraySpan = _oItemSelected.getElementsByTagName('SPAN');
				for (i = 0; i < arraySpan.length; i++)
				{
					if (arraySpan[i].className == 'listBulletItemSelected')
						arraySpan[i].className = 'listBulletItem';
				}
			}

			// Select new bullet item spans
			arraySpan = item.getElementsByTagName('SPAN');
			for (i = 0; i < arraySpan.length; i++)
			{
				if (arraySpan[i].className == 'listBulletItem')
					arraySpan[i].className = 'listBulletItemSelected';
			}

			item.className = item.className + '_S';
			item.style.backgroundColor = '#FEF6E2'; // Set selected item background color

			_oItemSelected = item;
		}
	}
}


// CustomPostButton CSS changers
function changeButtonStyle(button, style)
{
	var buttond = button + 'd';
	var buttong = button + 'g';
	var buttont = button + 't';
	var buttontable = button.replace('div', 'table');

	if (document.getElementById(button) != null)
		document.getElementById(button).className = 'btn' + style;
	if (document.getElementById(buttond) != null)
		document.getElementById(buttond).className = 'btnd' + style;
	if (document.getElementById(buttong) != null)
		document.getElementById(buttong).className = 'btng' + style;
	if (document.getElementById(buttont) != null)
		document.getElementById(buttont).className = 'btnt' + style;
	if (document.getElementById(buttontable) != null)
		document.getElementById(buttontable).className = 'tabbtn' + style;
}

function changeButtonCss(button, cssLeft, cssMiddle, cssRight, cssTable)
{
	var buttond = button + 'd';
	var buttong = button + 'g';
	var buttontable = button.replace('div', 'table');

	if (document.getElementById(button) != null)
		document.getElementById(button).className = cssMiddle;
	if (document.getElementById(buttond) != null)
		document.getElementById(buttond).className = cssRight;
	if (document.getElementById(buttong) != null)
		document.getElementById(buttong).className = cssLeft;
	if (document.getElementById(buttontable) != null)
		document.getElementById(buttontable).className = cssTable;
}

function toggleExtension(sInputPhoneId, sSpanExtId, sInputExtId)
{
	var txt_PhoneValue = document.getElementById(sInputPhoneId);
	var span_Ext = document.getElementById(sSpanExtId);
	var txt_PhoneExt = document.getElementById(sInputExtId);
	if (txt_PhoneValue != null && span_Ext != null && txt_PhoneExt != null)
	{
		// Only show extension on USA/Canada phone numbers (starting with 001 or +1)
		// Or as long as the extension contains something
		if (txt_PhoneExt.value != '' || /^001/.test(txt_PhoneValue.value) || /^\+1/.test(txt_PhoneValue.value))
		{
			// @THB 03/2010 TODO enable extension when we have decided what the extension separator should be ('x' ?)
			//span_Ext.style.display = txt_PhoneValue.style.display;
		}
		else
		{
			span_Ext.style.display = 'none';
		}
	}
}

var _sLastFocusId = '';

function saveLastFocus(sCtrlId)
{
	_sLastFocusId = sCtrlId;
}

function switchViewportToNormal()
{
	var viewport = document.getElementsByName("viewport")[0];
	if (/android/.test(navigator.userAgent))
	{
		if (viewport != null)
		{
			viewport.setAttribute("content", "width=device-width, maximum-scale=1.0, minimum-scale=1.0");
		}
	}
	else
	{
		if (viewport != null)
		{
			viewport.setAttribute("content", "width=device-width, maximum-scale=1.0, minimum-scale=1.0, initial-scale=1.0, user-scalable=no");
		}
	}
}

function switchViewportToDocument()
{
	// The portrait width is 1/3 the HTML width and the landscape width is 1/2 the HTML width
	// So we use 0.34 and 0.5 as initial-scale
	// 1/3 is estimated to 0.34, rounded above to be sure the width is no more than 960
	// Tested : 0.33 was blowing width to 970 (=320/0.33) instead of 960
	var viewport = document.getElementsByName("viewport")[0];
	if (/Android/.test(navigator.userAgent))
	{
		if (viewport != null)
		{
			if (window.orientation == 0)
				viewport.setAttribute("content", "width=960, maximum-scale=1.6, minimum-scale=0.34");
			else
				viewport.setAttribute("content", "width=960, maximum-scale=1.6, minimum-scale=0.25");
		}
	}
	else
	{
		if (viewport != null)
		{
			if (window.orientation == 0)
				viewport.setAttribute("content", "width=960, maximum-scale=1.6, minimum-scale=0.25, initial-scale=0.64, user-scalable=yes");
			else
				viewport.setAttribute("content", "width=960, maximum-scale=1.6, minimum-scale=0.25, initial-scale=0.7, user-scalable=yes");
		}
	}
}

// Invoked by RM2Help
function showHelpView(width, height, title, text)
{
	document.getElementById('div_Help').style.display = ''; //'block';
	if (_bIsMobile)
	{
		document.getElementById('div_Help').style.width = "100%";
	}
	else
	{
		document.getElementById('div_HelpText').style.height = height;
		document.getElementById('div_HelpText').style.width = width;
	}
	document.getElementById('span_HelpTitle').innerHTML = title;
	document.getElementById('span_HelpText').innerHTML = text;
}

// Invoked by some help texts
function showToolTipParagraph(toolTipId, paragraphIdToShow, nbParagraphs)
{
	for (var paragraphId = 1; paragraphId <= nbParagraphs; paragraphId++)
	{
		try
		{
			document.getElementById(toolTipId + '.' + paragraphId).style.display = (paragraphId == paragraphIdToShow) ? '' : 'none';
		}
		catch (e)
		{
		}
	}
}
