var g_doc = null;

function isString(x) { return (typeof x == 'string'); }

// Swaps the values of elements at i and j in an Array.
//
function swap(array, i, j)
{
	// ensure array is a valid Array
	//
	if (!array || (array.length == "undefined") || (array.length <= 1))
		return;

	// ensure that i & j indexes are in range
	//
	var len = array.length;
	if ((i < 0) || (j < 0))
		return;
	if ((i > len) || (j > len))
		return;

	// swap the values
	//
	var temp = array[i];
	array[i] = array[j];
	array[j] = temp;
}

// Parses the ampersand-separated query string name=value pairs of the current
// page's URL. It stores the name/value pairs in properties of an object and 
// returns that object.
//
// Example: eval("lnk" + queryString().state + ".coords = '0'");
//
// Note: 'queryString().state' returns true if 'state' is in the query string
// AND its value is not blank.  Do 'queryString().state != null' to test for
// existence only.
//
function queryString(loc)								// loc can be null or for instance "top.location"
{
	loc = (loc ? loc : location);
	var sQS = loc.search.substring(1);					// get the query string
	var args = new Object();
	var rgsPropValue = sQS.split("&");					// split at ampersand
	for (var i = 0; i < rgsPropValue.length; i++)
	{
		var j = rgsPropValue[i].indexOf('=');			// look for "name=value"
		if (j == -1)									// if not found
			continue;									// skip
		var sName  = rgsPropValue[i].substring(0, j);	// extract the name
		var sValue = rgsPropValue[i].substring(j+1);	// extract the value
		args[sName] = unescape(sValue);					// store name/value
		//
		// Note: In JavaScript 1.5, use decodeURIComponent() not unescape().
		//
	}	
	return args;
}

// Appends the specified name/value pair to the provided query string (if not already present).
//
function appendQueryString(qs, name, value)
{
	if (qs.indexOf("?") == -1)
		return (qs += ("?" + name + "=" + value));
	if (qs.toLowerCase().indexOf(name.toLowerCase()) == -1)
		return (qs += ("&" + name + "=" + value));
	return qs;
}

//Function to replace all occurrences of '&lt;', '&gt; and '&amp' to <, >, & respectively.
//
function SpCharDecode(strTemp)
{
	strTemp = strTemp.replace(/&amp;/g,'&');	// call first for FF fix
	strTemp = strTemp.replace(/&amp;/g,'&');	// call again for FF fix
	strTemp = strTemp.replace(/&lt;/g,'<');
	strTemp = strTemp.replace(/&gt;/g,'>');
	return strTemp; 
}

function call(fn)
{
	try
	{
		try
		{
			eval(_getFunctionName(fn));
		}
		catch (e)
		{
			return;		// the function doesn't exist
		}
		
		eval(fn);
	}
	catch (e)
	{
		alert(getExceptionInfoWithoutNumber(e, 'Calling ' + fn + ' failed: '));
	}

	function _getFunctionName(fn)
	{
		if (!fn)
			return fn;
		var i = fn.indexOf('(');
		if (i == -1)
			return fn;
		return fn.substring(0, i);
	}
}

function callWithDoc(fn, doc)
{
	try
	{
		g_doc = doc;
		call(fn);
	}
	finally
	{
		g_doc = null;
	}
}

var ctrlSelect = null;	// set by setFocus()
function selectCtrl(ctrl)
{
	if (ctrl)
		ctrlSelect = ctrl;
	if (ctrlSelect)
		if ((ctrlSelect.type == "text") || (ctrlSelect.type == "textarea") || (ctrlSelect.type == "file"))
			ctrlSelect.select();
	ctrlSelect = null;
}

function setFocusByID(sID) { setFocus(getById(sID)); }

function setFocusByName(sName)
{
	var ctrls = document.getElementsByName(sName);
	if (ctrls && ctrls.length > 0)
		setFocus(ctrls[0]);
}

function setFocus(ctrl)
{
	if (ctrl && !ctrl.disabled)
	{
		ctrl.focus();
		ctrlSelect = ctrl;
		
		// Allow the browser to catch up with window refreshing
		// tasks before selecting the contents.
		//
		window.setTimeout("selectCtrl();", 50);
	}
}

// Used to get elements on parent document from inside IFrame
function getFromParentById(sID)
{
    if (!sID)
		return null;
	var d = parent.document;
	
	var element = d.getElementById(sID);
	
	// If the element is not found, make sure the id was not prefixed by a control or master page
	if(!element)
	{
	    element = getElementByBaseId(d, sID);	    
	}
	    
	return element;
}

function getById(sID)
{
	if (!sID)
		return null;
	var d = (g_doc ? g_doc : document);
	
	var element = d.getElementById(sID);
	
	// If the element is not found, make sure the id was not prefixed by a control or master page
	if(!element)
	{
	    element = getElementByBaseId(d, sID);	    
	}
	    
	return element;
}

var g_ElementCache = new Array();

// Used to get elements that are nested inside ASP controls or
// master pages.  These elements have control prefixes put in front
// of their id's by ASP.NET when the page is rendered.
// Takes a string that represents part of the element ID.  
// If this parameter matches any part of any ID of one of the
// elements on the page, then the function will return that element.
function getElementByBaseId(doc, baseId)
{
    var element = null;
    // Try the cache first
    try
    {
        element = g_ElementCache[baseId];
    }
    catch (e)
    {
    }
    
    if (element == null)
    {
        try
        {                 
            var pattern = "<[^>]+?\\s(?:id|ID|Id|iD)=([\"']?)([\\w\\$\\:]*?[_\\:\\$]{1}" + baseId + "\\b)\\1[^<>]*?>";
            var re = new RegExp(pattern);    
            re.multiline = true;
            // We only need the first one found
            var firstMatch = re.exec(doc.body.innerHTML);
            if (firstMatch)
            {
                // Use the second captured group in the match as the ID
                element = doc.getElementById(firstMatch[2]);
                if (element)
                {
                    g_ElementCache[baseId] = element;
                }
            }
        }
        catch (e)
        {
        }        
    }    
    return element;
}

// NOTE: Returns { left:0, top:0, right:0, bottom:0, width:0, height:0 } if sID is bad or not found (asserts in debug).
//
function getElementPosition(ctrl)
{
	var offsetLeft = 0, offsetTop = 0;
	var cpxWidth = 0, cpxHeight = 0;

	assert(ctrl);

	if (ctrl)
	{
		cpxWidth  = ctrl.offsetWidth;
		cpxHeight = ctrl.offsetHeight;
	}

	while (ctrl)
	{
		offsetLeft+= ctrl.offsetLeft;
		offsetTop += ctrl.offsetTop;
		ctrl = ctrl.offsetParent;
	}

	// do leftMargin on "Mac"

	return { left:offsetLeft, top:offsetTop, 
			 right:(offsetLeft + cpxWidth), bottom:(offsetTop + cpxHeight),
			 width:cpxWidth, height:cpxHeight };
}

function getElementPositionByID(sID)
{
	return getElementPosition(getById(sID));
}

function opacity(sID, iOpacity, disable)
{
	var ctrl = getById(sID);
	if (ctrl)
	{
		if (!iOpacity)
			iOpacity = 30;
		ctrl.style.filter = ("alpha(opacity=" + iOpacity + ")");	// for IE
		ctrl.style.opacity = (iOpacity/100.0);						// for Netscape
		
		if (disable)
			ctrl.disabled = true;
	}
}

function isIE() { return (navigator.appName == "Microsoft Internet Explorer"); }
function isNav() { return (navigator.appName == "Netscape"); }
function isNav4() { return ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4)); }

var base64s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function encodeBase64(decStr)	// performs base 64 encoding
{
	var bits, dual, i = 0, encOut = '';
	while(decStr.length >= i + 3)
	{
		bits = (decStr.charCodeAt(i++) & 0xff) << 16 | (decStr.charCodeAt(i++) & 0xff) << 8  | decStr.charCodeAt(i++) & 0xff;
		encOut += base64s.charAt((bits & 0x00fc0000) >> 18) + base64s.charAt((bits & 0x0003f000) >> 12) +
		base64s.charAt((bits & 0x00000fc0) >> 6) + base64s.charAt((bits & 0x0000003f));
	}
	if(decStr.length-i > 0 && decStr.length-i < 3)
	{
		dual = Boolean(decStr.length -i -1);
		bits = ((decStr.charCodeAt(i++) & 0xff) <<16) | (dual ? (decStr.charCodeAt(i) & 0xff) <<8 : 0);
		encOut += base64s.charAt((bits & 0x00fc0000) >>18) + base64s.charAt((bits & 0x0003f000) >>12) +
		(dual ? base64s.charAt((bits & 0x00000fc0) >> 6) : '=') + '=';
	}
	return encOut
}

function decodeBase64(encStr) 
{
  if (encStr.length < 1) 
	return "";

  if (typeof(atob) == "function")
  {
	return atob(encStr);
  }
  else
  {
	var decOut = "";
	var length = encStr.length;
	  
	// Adjust for trailing = character
	if (encStr.substr(length - 1, 1) == "=") length--;
	if (encStr.substr(length - 1, 1) == "=") length--;
	  
	var charsLeft = length % 4;
	var n, i, parts;

	for (parts = length >> 2, i = 0; parts; parts--, i += 4) 
	{
		n = base64s.indexOf(encStr.substr(i, 1)) << 18 | base64s.indexOf(encStr.substr(i+1, 1)) << 12 |
			base64s.indexOf(encStr.substr(i+2, 1)) << 6 | base64s.indexOf(encStr.substr(i+3, 1));
		decOut += String.fromCharCode((n >> 16) & 255, (n >> 8) & 255, n & 255);
	}
	  
	if (charsLeft == 2) 
	{
		n = base64s.indexOf(encStr.substr(i, 1)) << 6 | base64s.indexOf(encStr.substr(i+1, 1));
		decOut += String.fromCharCode((n >> 4) & 255);
	} 
	else if (charsLeft == 3) 
	{
		n = base64s.indexOf(encStr.substr(i, 1)) << 12 | base64s.indexOf(encStr.substr(i+1, 1)) << 6 | base64s.indexOf(encStr.substr(i+2, 1));
		decOut += String.fromCharCode((n >> 10) & 255, (n >> 2) & 255);
	}
	  
	return decOut;
  }
}

function trim(str, ch)
{
	if (!str)
		return str;
	else if (!ch)
		return str.replace(/^\s*|\s*$/g, '');						// trim spaces
	else
	{
		var pattern = new RegExp("^" + ch + "*|" + ch + "*$", "g");	// trim the given character
		return str.replace(pattern, '');
	}
}

// Inserts commas for displaying large integers (for floats call this function 
// separately with the integer and fractional parts).
//
function formatCommas(n)
{
	if (!n)
		return 0;
	n = n.toString();
	var re = /(-?\d+)(\d{3})/;
	while (re.test(n))
		n = n.replace(re, "$1,$2");
	return n;
}

function ellipsize(s, chars)
{
	return ((s && (s.length <= chars)) ? s : (s.substring(0, chars) + "..."));
}

function clearSelectList(list)
{
	for (var i = list.options.length-1; i >= 0; i--)
	{
		if (isIE())
			list.options.remove(i);
		else
			list.options[i] = null;
	}
}

function expandCollapse(ctrl, minimized)
{
	if (ctrl.style.display == "")
	{
		ctrl.style.display = "none";
		minimized.style.display = "";
	}
	else
	{
		ctrl.style.display = "";
		minimized.style.display = "none";
	}
}

function ignoreIEUnspecifiedError()
{
	window.onerror = _ignoreIEUnspecifiedError;
}

function _ignoreIEUnspecifiedError(sError)
{
	if (isIE())
		window.event.returnValue = (sError.toLowerCase().indexOf('unspecified error') >= 0);
}

var g_previewTitle = null;
var g_previewWindow = null;
var g_previewTimerID = null;
function displayPreview(url, title, openOnly)
{
	g_previewWindow = window.open(url, "previewWindow", "height=768,width=1024,scrollbars=no,resizable=yes,toolbars=no,status=yes,menubar=no,location=no");

	if (openOnly)
	{
		g_previewWindow.focus();
		return g_previewWindow;
	}
	
	// cache the title (if any) to be set by onPreviewLoad() later
	//
	if (title)
		g_previewTitle = ("Preview of " + title);

	// call onPreviewLoad() repeatedly since we don't know when the preview window is fully loaded
	//
	g_previewTimerID = window.setInterval("onPreviewLoad();", 100);

	g_previewWindow.focus();
}

function onPreviewLoad()
{
	try
	{
		// set the preview window to call onPreviewUnload() prior to unloading
		//
		g_previewWindow.document.body.onunload = function () { if (onPreviewUnload) onPreviewUnload(); }

		// set the browser's title
		//
		if (g_previewTitle)
			g_previewWindow.document.title = g_previewTitle;

		disableAnchors(g_previewWindow.document);
		disableSubmit(g_previewWindow.document);
	}
	catch(e)
	{
		return;
	}
}

function disableAnchors(element)
{
	if (element)
	{
		var anchors = element.getElementsByTagName("a");
		for (var i = 0; i < anchors.length; i++)
		{
			anchors[i].target = "_self";
			anchors[i].href = "javascript:alert('Links are disabled in preview!');";
		}
	}
}

function disableSubmit(element)
{
	if (element)
	{
		var forms = element.getElementsByTagName("form");
		for (var j = 0; j < forms.length; j++)
			for (var k = 0; k < forms[j].length; k++)
				if (forms[j].elements[k].tagName.toLowerCase() == 'input')
					if (forms[j].elements[k].type.toLowerCase() == 'submit')
						forms[j].elements[k].disabled = true;
	}
}

function onPreviewUnload()
{
	clearInterval(g_previewTimerID);
	g_previewTimerID = g_previewWindow = g_previewTitle = null;
}

//	Checks to see if a string is numeric 
//	- returns true or false based on this evaluation
function IsNumeric(sText)
{
	var ValidChars = "0123456789.";
	var IsNumber=true;
	var Char;

	for (i = 0; i < sText.length && IsNumber == true; i++) 
	{ 
		Char = sText.charAt(i); 
		if (ValidChars.indexOf(Char) == -1) 
		{
			IsNumber = false;
		}
	}
      
   return IsNumber;   
}

function enableExtendedImageButton(id, enable)
{
	try
	{
		if (EIButtonManager != null && typeof(EIButtonManager) != 'undefined')
		{
			if (enable) {
				EIButtonManager.EnableButton(id);
				}
			else {
				EIButtonManager.DisableButton(id);
				}
			return;
		}
	}
	catch (e) {}
	
	// If button can't be disabled or enabled then hide or show instead
	showExtendedImageButton(id, enable);		
}

function showExtendedImageButton(id, show)
{
	try 
	{
		if (EIButtonManager != null && typeof(EIButtonManager) != 'undefined')
		{
			if (show) {
				EIButtonManager.ShowButton(id);
				}
			else {
				EIButtonManager.HideButton(id);
				}					
			return;
		}
	}
	catch (e) {}
	
	// If there is an error in trying to hide using the ExtendedImageButton manager, hide the old way
	var visibility = (show ? "visible" : "hidden");
		
	var anchor = getById(id + 'a');
	if (anchor)
		anchor.style.visibility = visibility;

	var img = getById(id);
	if (img)
		img.style.visibility = visibility;		
}

function cursorPosition()
{
	var obj = document.activeElement;
	var cur = document.selection.createRange();
	var pos = 0;
	if (obj && cur)
	{
		var tr = obj.createTextRange();
		if (tr)
		{
			while (cur.compareEndPoints("StartToStart", tr) > 0)
			{
				tr.moveStart("character", 1);
				pos++;
			}
			return pos;
		}
	}
	return -1;
}

function refreshWSTPage(winName, forwardUrl)
{
	if (!winName)
		winName = window.name;
	if (winName)
	{
		window.name = null;
		var win = window.open("", winName, "");
		win.location.reload();

		if (forwardUrl)
			window.location.href = forwardUrl;
		else
			window.close();
	}
}

function isValidEmail(email)
{
	var validPattern = '^(([a-zA-Z0-9]+[a-zA-Z0-9_\\-]*(\\.[a-zA-Z0-9_\\-]+)*))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,}|[0-9]{1,3})$';
	return email.match(new RegExp(validPattern, 'i'));
}

// Checks to see if the modalPopInHeight for the popin will fit with the clients
// desktop resolution.  If it does not, it will return a height that will fit.
function getClientPopInHeight(modalPopInHeight)
{
    var lowResHeight = 550;
    var midResHeight = 660;
    
    var clientHeight = window.screen.height;
    if(clientHeight <= 800 && modalPopInHeight > lowResHeight)
    {
        // Resolutions 1024x768, 1280x720, 1280x800
        return lowResHeight;
    }
    else if(clientHeight <= 864 && modalPopInHeight > midResHeight)
    {
        // Resolution 1152x864
        return midResHeight;
    }
    else
    {
        // Return orignal modal pop in height since it will fit in all resolutions
        return modalPopInHeight;
    }
}

function removeChildren(element)
{
	if (!element)
		return;

	var children = element.childNodes.length;
	while (children > 0)
	{
		try
		{
			element.removeChild(element.childNodes[0]);
		}
		catch (e)
		{
			// try a different method
			//
			element.childNodes[0].parentNode.removeChild(element.childNodes[0]);
		}

		// prevent infinite loop in case we can't remove something
		//
		if (element.childNodes.length == children)
			break;
		children = element.childNodes.length;
	}

	element.innerHTML = "";		// just to be sure
}