//<%
//Generic utilities for any client side javascript files
//To have a method in here it must not depend on any globals
//or any other javascript files

// NOTE: THIS FILE IS COMMON TO BOTH "CLIENT SERVICES" AND "SERVICE DESK"
//       AND SHOULD LIVE IN THE "COMMON" DIRECTORY I.E "./PL/Common/Scripts/" IN CVS.
//		 *NOT* IN CVS HERE "./PL/ClientServices/Scripts/" OR "./PL/ServiceDesk/Scripts/"
// Retrieve the value of the cookie with the specified name.

function getCookie(sName, curDoc)
{
	if (!curDoc)
		curDoc = document;

	// cookies are separated by semicolons
	var aCookie = curDoc.cookie.split("; ");
	for (var i=0; i < aCookie.length; i++)
	{
		// a name/value pair (a crumb) is separated by an equal sign
		var aCrumb = aCookie[i].split("=");
		if (sName == aCrumb[0]) 
		return decodeURIComponent(aCrumb[1]);
	}

	// a cookie with the requested name does not exist
	return null;
}

// We don't want to use the common_label_msg system if we are in Self Service,
// so figure out if we are there.
var bIsSSHDorSSD_Utility = false;
if (typeof(window) != 'undefined')
{
	var IsSSHDorSSD = getCookie("IsSSHDorSSD", document);
	if (IsSSHDorSSD == 'CS' || IsSSHDorSSD == 'SSHD' || IsSSHDorSSD == 'TRUE')
	{
		bIsSSHDorSSD_Utility = true;
	}
}

var _CommonLabelMessages = null;
var _CommonSystemMessages = null;
var clmNoReplace = false;

if (typeof(window) != 'undefined')
{
	var parTemp = window;
	// Just in case something goes wrong, I don't want to spin forever
	var lCount = 0;
	
	// Find common_label_msg
	while (parTemp != null && lCount++ < 50)
	{
		// See if the array is defined
		if (typeof(parTemp.clmArr) != 'undefined')
		{
			// This is the one we'll use
			_CommonLabelMessages = parTemp;
			break;
		}

		// We're at the top already, quit searching
		if (parTemp == window.top)
			break;

		// Get this window's parent
		if (typeof(parTemp.parent) != 'undefined')
			parTemp = parTemp.parent;
		else
			break;
	}
	
	if (_CommonLabelMessages == null)
	{
		// No common_label_msg found, add to this window
		_CommonLabelMessages = window;
		if (bIsSSHDorSSD_Utility == false)
		{
			document.write('<script type="text/javascript" src="Scripts/common_label_msg.js"></script>');
			//document.write('<script type="text/javascript">alert("common_label_msg added " + window.location)</script>');
			//window.open("http://sgibson2k3/sde/commonlabelmsg.htm", "", "width=400,height=100");
			//clmNoReplace = true;
		}
	}

	parTemp = window;
	// Just in case something goes wrong, I don't want to spin forever
	lCount = 0;

	// Find CommonSystemMsg
	while (parTemp != null && lCount++ < 50)
	{
		// See if the array is defined
		if (bIsSSHDorSSD_Utility == false)
		{
			if (typeof(parTemp.csmArr) != 'undefined')
			{
				// This is the one we'll use
				_CommonSystemMessages = parTemp;
				break;
			}
		}
		else
		{
			// The CommonSystemMsg is implemented different in MCS/SSHD, look for _GetMerlinMsg
			if (typeof(parTemp._GetMerlinMsg) != 'undefined')
			{
				// This is the one we'll use
				_CommonSystemMessages = parTemp;
				break;
			}
		}

		// We're at the top already, quit searching
		if (parTemp == window.top)
			break;

		// Get this window's parent
		if (typeof(parTemp.parent) != 'undefined')
			parTemp = parTemp.parent;
		else
			break;
	}

	if (_CommonSystemMessages == null)
	{
		// No common_label_msg found, add to this window
		_CommonSystemMessages = window;
		if (bIsSSHDorSSD_Utility == false)
		{
			document.write('<script type="text/javascript" src="Scripts/CommonSystemMsg.js"></script>');
			//document.write('<script type="text/javascript">alert("CommonSystemMsg added " + window.location)</script>');
			//window.open("http://sgibson2k3/sde/commonsystemmsg.htm", "", "width=400,height=100");
		}
	}
}

var GetstringPlainRegex = null;
if (_CommonLabelMessages != null)
{
	GetstringPlainRegex = _CommonLabelMessages._GetstringPlainRegex;
}

function GetMSDEBucketMessage(TokenNumber)
{
	if (_CommonLabelMessages != null)
	{
		return _CommonLabelMessages._GetMSDEBucketMessage(TokenNumber);
	}
}

function GetHTMLMsg(sErrNum)
{
	if (_CommonLabelMessages != null)
	{
		return _CommonLabelMessages._GetHTMLMsg(sErrNum);
	}
}

function clmGetText(parentObj)
{
	if (_CommonLabelMessages != null)
	{
		return _CommonLabelMessages._clmGetText(parentObj);
	}
}

function Getstring(testhtml, localArray)
{
	if (_CommonLabelMessages != null)
	{
		return _CommonLabelMessages._Getstring(testhtml, localArray);
	}
}

function clmGetMessageForString(id, args, plain)
{
	if (_CommonLabelMessages != null)
	{
		return _CommonLabelMessages._clmGetMessageForString(id, args, plain);
	}
}

function clmReplacePropertyPlain(obj, prop)
{
	if (_CommonLabelMessages != null)
	{
		return _CommonLabelMessages._clmReplacePropertyPlain(obj, prop);
	}
}

function csmGetText(args)
{
	if (_CommonSystemMessages != null)
	{
		return _CommonSystemMessages._csmGetText(args);
	}
}

function clmGetstringPlain(testhtml, localArray)
{
	if (_CommonSystemMessages != null)
	{
		return _CommonSystemMessages._clmGetstringPlain(testhtml, localArray);
	}
}

function MerlinSystemMsg()
{
	// This is the regular help desk
	if ((_CommonSystemMessages != null) &&  (!bIsSSHDorSSD_Utility) && ((_CommonSystemMessages.IsSSHDorSSD == undefined) || (_CommonSystemMessages.IsSSHDorSSD == null)))
	{
		var strErrMsg="";

		if (arguments.length < 2)
			strErrMsg = arguments[0];
		else
		{
			var tmpArray=[];
			var i;
			for (i=0; i < arguments.length-1; i++)
			{
				tmpArray[i]=arguments[i];
			}
			strErrMsg = _CommonSystemMessages._csmGetText(tmpArray);
			tmpArray = null;
		}
		//sridhar-27787: added if
		if (arguments.length < 2)
			ret = MerlinErrorMsgBox(strErrMsg, 0);
		else
			ret = MerlinErrorMsgBox(strErrMsg, arguments[arguments.length-1]);
		//sridhar-27787:ends here
		return ret;
	}
	else
	{
		// MCS / SSHD only
		if (bIsSSHDorSSD_Utility)
		{
			var strErrMsg="";
			var sBrowser = "" 	
			if (arguments.length < 2)
				strErrMsg = arguments[0];
			else
			{
				var tmpArray=[];
				var i;
				for (i=0; i < arguments.length-1; i++)
				{
					tmpArray[i]=arguments[i];
				}
				strErrMsg = _csmGetText(tmpArray);
				tmpArray = null;
			}
			if (parseInt(navigator.appVersion) >= 4)
			{ 
				if (navigator.appName == "Netscape")
				{
					if ( document.getElementById && !document.all )
						sBrowser =  "NC6"
					else
						sBrowser = "NC" 
				}
				else if (navigator.appName == "Microsoft Internet Explorer")
					sBrowser = "IE" 
				else
					sBrowser = ""
			}
			else 
				sBrowser = ""
			if(sBrowser == "IE" )
			{		
				//sridhar-27787: added if
				if (arguments.length < 2)
					ret = MerlinErrorMsgBox(strErrMsg, 0);
				else
					ret = MerlinErrorMsgBox(strErrMsg, arguments[arguments.length-1]);
				//bug # 35493, 35494
				if ((ret == 1) || (ret == 6))
				    ret = true;
				else
				ret = false;
				//bug # 35493, 35494
				//sridhar-27787:ends here
			}
			else
			{
				if ((arguments.length < 2) || (arguments[arguments.length - 1] == 0) || (arguments[arguments.length - 1] == 16) || (arguments[arguments.length - 1] == 32) || (arguments[arguments.length - 1] == 48) || (arguments[arguments.length - 1] == 64))
					ret = alert(strErrMsg);
				else
					ret = confirm(strErrMsg);
			}
			return ret;
		}
	}
}

function GetMerlinMsg(TokenNumber)
{
	if (_CommonSystemMessages != null)
	{
		return _CommonSystemMessages._GetMerlinMsg(TokenNumber);
	}
}

/**
 * Confirm SMTP address format
 */
//Saroj (Bug# 48290): Changed the regular expression being used for SMTP email address validation
var _UtilSmtpAddressRe = /^([\w\'-\.\&\#]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,6}|[0-9]{1,3})(\]?)$/

function UtilvalidateSmtpAddress(sSMTPAddr) 
{
   //validate the email address
   return _UtilSmtpAddressRe.test(sSMTPAddr);
} //end email validation


function UtilStripSMTPPrefix(address)
{
	if (address != null && address != "")
	{
		address = UtilTrimStr(address);
		
		if ("SMTP:{" == address.substr(0,6))
		{
			//var newAddr = address;			
			var iStart = 6;
			var iEnd = iStart;
			
			iEnd = address.indexOf("}", iStart) - iStart;

			return address.substr(iStart,iEnd)
		}
		else
		{
			// check if the address is a plain address with out any formating.
			if( UtilvalidateSmtpAddress(address) == true)
				return address;
		}
	}
	
	return "";
}

/**
 * Trim whitespace off of both ends of a string.
 */
var UtilTrimRe=/^\s+|\s+$/g;
function UtilTrimStr(inStr)
{
   return inStr.replace(UtilTrimRe,'');
}


/**
 * Replace all occurance of a single character with a new string.
 */
function UtilReplaceAllOfChar(strSearchMe, strOldChar, strNew)
{
   var re = new RegExp("\\" + strOldChar, 'g');
   return strSearchMe.replace(re, strNew);
}

/**
 * This method is used to construct a "standard" javascript exception
 * with a name (aka exception type) you can check against when
 * catching exceptions as well as a more user oriented message.
 */
function UtilGetErrorObj(name, msg)
{
   var err = new Error();
   err.message = msg;
   //not standard, but compatible with IE
   err.description = msg;
   err.name = name;
   return err;
}

var UtilJsQuoteStrRe = RegExp("'", "g");
/**
 * Quote a string for safe use in script blocks or JS
 * embedded in HTML attributes
 */
function UtilJsQuoteStr(inData)
{
   return ["decodeURI('",
           encodeURI(inData).replace(UtilJsQuoteStrRe,"\\'"),
           "')"].join('');
}

/**
 * Quote Data (numbers or strings) for safe use in script blocks or JS
 * embedded in HTML attributes
 */
function UtilJsQuoteData(inData)
{
   var dataType = typeof(inData);
   
   if (null == inData)
      return "null";
   switch (dataType)
   {
      case "number":
         return "" + inData;
         break;
      case "string":
         return UtilJsQuoteStr(inData);
         break;
      case "object":
         //generic dumping functionality.
         if ('function' == typeof(inData.dump))
            return inData.dump();
             
         if  (typeof(inData.length) == 'number')
           //  Smells like an array (can't use constructor because it doesn't
           //  match if the object was created/evaled in one frame and 
           //  then is attempted to be serialized in another)
               return UtilJsQuoteSimpleArray(inData);
      
         break;
      case "boolean":
         return inData.toString();
         break;
         //let default fall through
   }
   
   throw UtilGetErrorObj("UnknownType",
                         "Dont know how to quote type: " + typeof(inData));
}


/**
 * Quote Hash Table (numbers or strings) for safe use in script blocks or JS
 * embedded in HTML attributes
 */
function UtilJsQuoteSimpleHash(inData, addFinalSemi)
{
   if (null == addFinalSemi)
      //default to true
      addFinalSemi = true;

   var outArray=['(function () { var outData={};'];
   for (key in inData)
   {
      outArray[outArray.length] = 'outData[';
      outArray[outArray.length] = UtilJsQuoteData(key);
      outArray[outArray.length] = ']=';
      outArray[outArray.length] = UtilJsQuoteData(inData[key]);
      outArray[outArray.length] = ';\n';
   }

   outArray[outArray.length]='return outData; })()';
   
   if (addFinalSemi)
      outArray[outArray.length] = ';';
   
   return outArray.join('');
}


/**
 * Quote Array (numbers or strings) for safe use in script blocks or JS
 * embedded in HTML attributes
 */
function UtilJsQuoteSimpleArray(inArray)
{
   var i;
   var outArray = ['['];
   for (i=0; i < inArray.length ; i++)
   {
      if (i != 0)
         outArray[outArray.length] = ',';
      
      var curItem = inArray[i];

      outArray[outArray.length] = UtilJsQuoteData(curItem);
   }
   outArray[outArray.length] = ']';
   return outArray.join('');
}


var UtilHTMLEncodeAmpRe = new RegExp("&","g");
var UtilHTMLEncodeQuoteRe = new RegExp('"',"g");
var UtilHTMLEncodeLeRe = new RegExp('<',"g");
var UtilHTMLEncodeGtRe = new RegExp('>',"g");
/**
 * Quote data for HTML embedded (between tags).
 */
function UtilHTMLEncode(inStr)
{
	
   if ((inStr == null) || (inStr == "&nbsp") || (inStr == "&nbsp;"))
   {
      inStr = new String("");
   }
   
   if (typeof(inStr) == "number")
   {
      inStr = new String(inStr);
   }

   if (typeof(inStr) == "date")
   {
      inStr = new String(inStr);
   }

   if (typeof(inStr) == "boolean")
   {
      return inStr;
   }

   return inStr.replace(UtilHTMLEncodeAmpRe, "&amp;")
      .replace(UtilHTMLEncodeQuoteRe, "&quot;")
      .replace(UtilHTMLEncodeLeRe, "&lt;")
      .replace(UtilHTMLEncodeGtRe, "&gt;");
}

//54073:<--
var UtilHTMLDecodeAmpRe = new RegExp("&amp;","g");
var UtilHTMLDecodeQuoteRe = new RegExp('&quot;',"g");
var UtilHTMLDecodeLeRe = new RegExp('&lt;',"g");
var UtilHTMLDecodeGtRe = new RegExp('&gt;',"g");
var UtilHTMLDecodeAposRe = new RegExp("&apos;","g");

function UtilHTMLDecode(inStr)
{
	
   if (inStr == null)
   {
      inStr = new String("");
   }
   
   if (typeof(inStr) == "number" || typeof(inStr) == "date")
   {
      inStr = new String(inStr);
   }

   return inStr.replace(UtilHTMLDecodeAmpRe, "&")
      .replace(UtilHTMLDecodeQuoteRe, '"')
      .replace(UtilHTMLDecodeLeRe, "<")
      .replace(UtilHTMLDecodeGtRe, ">")
      .replace(UtilHTMLDecodeAposRe, "'");
}
//-->

/****
 * Array Utilities - 
 * Remember that arrays have the following built in methods:
 *   concat - concatinate two arrays to create a third new array
 *   join - create a string by combining all elements with the
 *          provided seperator string between the elements.
 *   pop, push, shift, unshift, reverse - what you would think
 *   slice - extract a sub-range of the array
 *   sort - sort the array 
 *   splice - insert/remove items into/from array
 * 
 * Always use the built in methods if appropriate, they are much faster
 * then can be coded by hand.
 *
 * Best way to copy an existing array that is zero based and not sparse
 * is probably:
 *    UtilArrayConcat(existing, arrToAppendItemsFrom);
 ****/

/**
 * Create an array of numbers in the range specified.
 */
function UtilCreateArrayRange(min, max)
{

   if (1 == arguments.length)
   {
      //legal, can specify one argument and do 0 up to but not including arg
      max = min;
      min =0;
   }
   
   var outArray;
   if (max > min)
      outArray = new Array(max - min);
   else
      outArray = [];

   var offset =0;
   for (var i = min ; i < max ; i++, offset++)
   {
      
      outArray[offset] = i;
   }
   return outArray;
}


/**
 * Check to see if arrays of simple data types are equal.
 * Assumes 0..n arrays
 *
 * Optional strict argument means that if the objects
 * are not object, they must have the same data type 
 * aka "1" and 1 are not equal.
 * 
 * strictNess has a couple of levels:
 * null or false - default, not strict
 * 1 or true - objects must be equal
 * 2 - objects must have same type, but not be equal 
 */
function UtilSimpleArrayEqual(arr1, arr2, strict)
{

   if (strict)
   {
      if (strict == true)
         strict = 1;
   }
   
   //check both null or both set to same array
   if (arr1 == arr2)
      return true;

   if ((null == arr1)  || (null == arr2))
      //one null, one not
      return false;


   //if we get here both not null
   if (arr1.length != arr2.length)
      return false;

   //same length so check items
   var i;
   for (i=0; i < arr1.length ; i++)
   {
      var curItem1 = arr1[i];
      var curItem2 = arr2[i];

      if (strict)
      {
         if (typeof(curItem1) != typeof(curItem2))
            return false;
      }

      if ((typeof(curItem1) == "object") &&
          (strict || (typeof(curItem2) == "object")))
      {
         //both are objects
         
         if (curItem1.constructor != curItem2.constructor)
            //different constructors/types
            return false;
         
         if (curItem1.constructor == Array)
         {
            //we can check to see if the subarray is equal (at least)
            if (!UtilSimpleArrayEqual(curItem1, curItem2))
               return false;
            continue;
         }
         
         //don't check equality if strict is == 2
         if (strict == 2)
            continue;
      }
         
      if (curItem1 != curItem2)
         return false;
   }
   
   return true;
}


/**
 *
 * Even though UtilArrayConcat may assign in place, you must assign
 * the output back onto the first argument:
 *
 * Right:
 *
 *   appendArray = UtilArrayConcat(appendArray, addToItArray);
 * 
 * WRONG:
 *   UtilArrayConcat(appendArray, addToItArray); //THIS IS A BUG
 */
function UtilArrayConcat(arrToAppendTo, arrToBeAdded)
{

   var arrConstructor = [].constructor;
   
   if ((arrConstructor == arrToBeAdded.constructor) &&
       (arrConstructor == arrToAppendTo.constructor) &&
       (arrToBeAdded.length > 5))
   {
      //don't want to create garbage unless length is greater than 5
      arrToAppendTo = arrToAppendTo.concat(arrToBeAdded);
   }
   else
   {
      //slow way if it is not a true array
      //This works around an IE arguments bug.
      //Also for (in) doesn't work with IE or mozilla arguments
       var i;
       for (i = 0 ; i < arrToBeAdded.length ; i++)
       {
          arrToAppendTo[arrToAppendTo.length] = arrToBeAdded[i];
       }
   }
   
   return arrToAppendTo;
}

/**
 * Returns a new array which is the result of calling the provided
 * method on each member of the array.
 * For example:
 *    UtilArrayMapFunction(['1','2','3'],parseInt);
 * Returns
 *    [1,2,3]
 */
function UtilArrayMapFunction(inArray, inFunc)
{
   var outArray = new Array();
   for (var key in inArray)
   {
      outArray[key] = inFunc(inArray[key]);
   }
   return outArray;
}

/**
 * Return true if the top level of the array is null free
 */
function UtilArrayEnsureNoTopLevelNulls(inArray)
{
   var key;
   for (key in inArray)
   {
      if (null == inArray[key])
         return false;
   }
   return true;
}

/**
 * Returns a fresh array contianing the non-null elements of the
 * array if testFunc is not provided. If testFunc is provided
 * returns only the items for which testFunc(item) returns true.
 * Examples:
 *    UtilArrayFilterTopLevelNulls([null,1,null,2,null]);
 *  Returns: [1,2]
 *
 *    UtilArrayFilterTopLevelNulls([null,1,null,2,null],
 *                                 function (arg)
 *                                 { return arg==1});
 *  Returns: [1]
 */
function UtilArrayFilterTopLevelNulls(inArray, testFunc)
{
   var outArray = [];
   var i;
   for (i=0; i < inArray.length ; i++)
   {

      var curItem = inArray[i];
      if ((testFunc && !testFunc(curItem))
          || (curItem == null))
         continue;

      outArray[outArray.length] = curItem;
   }
   return outArray;
}


/**
 * Returns a object dictionary where each item in the array
 * has been make into a dictionary key with the value of true.
 * 
 * In: [1,2,3]
 * Out: {1:true,
 *       2:true,
 *       3:true}
 */
function UtilArrayValuesToDictKeys(inArray)
{
   var outDict = {};
   for (var key in inArray)
   {
      outDict[inArray[key]] = true;
   }
   return outDict;
}


/**
 * Returns a object dictionary where each item in the array
 * has been make into a dictionary key with the value being
 * the associated object from the original array.
 * 
 * In: [{key: 5}, {key: 6}], function (obj){return obj.key;}
 * Out: {5: {key: 5},
 *       6: {key: 6}}
 */
function UtilObjArrayToDict(inArray, keyFunc)
{
   var outDict = {};
   var curObj;
   for (var key in inArray)
   {
      curObj = inArray[key];
      outDict[keyFunc(curObj)] = curObj;
   }
   
   return outDict;
}

/**
 * Returns a object dictionary where each item in the array has been
 * make into a dictionary key (based on what the passed in function
 * returns) with the value of the offset at which the item occured.
 * 
 * In: [{key: 5}, {key: 6}], function (obj){return obj.key;}
 * Out: {5: 0,
 *       6: 1}
 */
function UtilObjArrayToOffsetDict(inArray, keyFunc)
{
   var outDict = {};
   var curObj;
   var i;
   for (i = 0 ; i < inArray.length ; i++)
   {
      curObj = inArray[i];
      outDict[keyFunc(curObj)] = i;
   }
   
   return outDict;
}


/* In: ["NID=QSEQ22", "TMODE=E", ...]
 * Out: {NID: "NID=QSEQ22"2,
 *       TMODE: "TMODE=E", ...}
 */
function UtilInArrayToDict(inArray, keySeperator)
{
   var outDict = {};
   var curObj;
   var i;
   for (i = 0 ; i < inArray.length ; i++)
   {
	  if(inArray[i] == "") continue;
	  
      curObj = inArray[i].split(keySeperator);
      
      if(curObj.length < 2)
		outDict[curObj[0]] = "";
	  else
	  {
		var key = curObj.shift(); //splice(0,1);
	  
		outDict[key] = curObj.join(keySeperator);
	  }
   }
   
   return outDict;
}

/* In: ["NID=QSEQ22", "TMODE=E", ...]
 * Out: {NID: "NID=QSEQ22"2,
 *       TMODE: "TMODE=E", ...}
 */
function UtilDictToArray(inDict, keySeperator, nodeSeperator)
{
   var outArray = "";
   var curObj;
   for (var key in inDict)
   {
      outArray = outArray + key + keySeperator + inDict[key] + nodeSeperator;
   }
   
   return outArray.substr(0, outArray.length-1);
}

/**
 * Completly replaces the contents of the destArray
 * with the contents of the inArray.
 * 
 * Does a shallow copy only.
 */
function UtilArrayReplaceContents(destArray, inArray)
{
   //match lengths for performance and to trim excess
   destArray.length = inArray.length;
   
   var i;
   for (i=0; i < inArray.length ; i++)
   {
      destArray[i] = inArray[i];
   }
}


var UtilReIsNumber = new RegExp("^[ \t\n\r]*-?[0-9]+[ \t\n\r]*$");
/**
 * Validates and parses the provided input. Input must be positive or
 * negative whole number.
 * 
 * Whitespace around number is OK.
 *
 * Throws a NotANumber exception if there is anything that isn't a
 * whole number surrounded by optional whitespace.
 */
function UtilSafeParseInt(strInput)
{
   
   if (('number' == typeof(strInput)) &&
       //a number may not be an int, so we have to check
       (strInput == parseInt(strInput)))
      return strInput;

   
   if ('string' != typeof(strInput))
   {
      //coerce it back into a string, this is in case it is some
      //funcy object that has a good string representation
      strInput = "" + strInput;
   }
   
   var matchObj = UtilReIsNumber.exec(strInput);
  
   if (null == matchObj)
   {
      var exObj = UtilGetErrorObj("NotANumber",
                                  "Input was not a number: " + strInput);
      throw exObj;
   }
  
   var iOut = parseInt(strInput);
    
   return iOut;
}

/**
 * Validates and parses the provided input. Input must be positive or
 * negative whole number.
 * 
 * Whitespace around number is OK.
 *
 * Throws a NotANumber exception if there is anything that isn't a
 * whole number surrounded by optional whitespace.
 */
function UtilSafeParseFloat(strInput)
{
   //warning -- no locale aware
   if ('number' == typeof(strInput))
      return strInput;

   
   if ('string' != typeof(strInput))
   {
      //coerce it back into a string, this is in case it is some
      //funcy object that has a good string representation
      strInput = "" + strInput;
   }

   
   var numObj = new Number(strInput);
  
   if (isNaN(numObj))
   {
      var exObj = UtilGetErrorObj("NotANumber",
                                  "Input was not a number: " + strInput);
      throw exObj;
   }

   
   var fOut = numObj;
   if (fOut.value)
      fOut = fOut.value;
   else
      fOut = parseFloat(fOut);
    
   return fOut;
}


/**
 * Tries to guess what the decimal seperator will be
 */
function UtilGuessDecimalSeperator()
{
   //0.5 has an exact binary representation, so it should
   //always result in 0,5 or 0.5 or whatever
   var decString = (0.5).toLocaleString();
   decRe = UtilGuessDecimalSeperator.decRe;
   if (!decRe)
   {
      decRe = /^0*([^0-9])+50*$/;
      UtilGuessDecimalSeperator.decRe = decRe;
   }
   var match = decRe.exec(decString);
   return match[1];
}


/**
 * Validates and parses the provided input. Input must be positive or
 * negative whole number.
 * 
 * Whitespace around number is OK.
 *
 * Throws a NotANumber exception if there is anything that isn't a
 * whole number surrounded by optional whitespace.
 */
function UtilSafeParseFloatLocale(strInput)
{
   if ('number' == typeof(strInput))
      return strInput;
   
   if ('string' != typeof(strInput))
   {
      //coerce it back into a string, this is in case it is some
      //funcy object that has a good string representation
      strInput = "" + strInput;
   }

   var floatRe = UtilSafeParseFloatLocale.floatRe;

   if (!floatRe)
   {
      floatRe = new RegExp("^([0-9]*)(\\" + UtilGuessDecimalSeperator() + "([0-9]*))?$");
      UtilSafeParseFloatLocale.floatRe = floatRe;
   }
      
   var matchObj = floatRe.exec(strInput);
   var fOut;
   if (null == matchObj)
   {
      //simple locale aware failed, try it locale independent
      fOut  = new Number(strInput);
      if (isNaN(fOut))
      {
         var exObj = UtilGetErrorObj("NotANumber",
                                     "Input was not a number: " + strInput);
         throw exObj;
      }

      if (fOut.value)
         fOut = fOut.value;
      else
         fOut = parseFloat(fOut);
   }
   else
   {
      //built it from the parts
      fOut  = parseFloat(matchObj[1] + "." + matchObj[3]);
   }
   return fOut;
}


var  UtilIeRe=/^[^;]+; MSIE[^;]+;.+$/;
/**
 * Returns true is brower appears to be an IE version.
 */
function UtilIsIe()
{
   if (UtilIeRe.exec(navigator.userAgent))
      //normalize probably not safe
      return true;
   else
      return false;
}

/**
 * Note: Body must be sized for height and width of 100% to work on IE.
 */
function UtilGetWindowContentsSize(inWin)
{
   if (null != inWin.innerHeight)
      //mozilla
      return [inWin.innerWidth, inWin.innerHeight];
   else
   {
      //ie
      return [inWin.frameElement.offsetWidth,
              inWin.frameElement.offsetHeight];
   }
}


/**
 * Note: Get the element which generated the event in Mozilla and IE.
 */
function UtilGetEventElement(event)
{
   if (event.target)
      return event.target;
   else
      return event.srcElement;
}

/**
 * Take in incomming dictionary object and call setAttribute(key, value)
 * on every member.
 */
function UtilApplyDictToObjectAttrs(inObj, inDict)
{
   var key;
   for (key in inDict)
   {
      inObj.setAttribute(key,inDict[key]);
   }
}

/**
 * Take in incomming dictionary object and call inObj[key] = value
 * on every member.
 */
function UtilApplyDictToObject(inObj, inDict)
{
   var key;
   for (key in inDict)
   {
      inObj[key]= inDict[key];
   }
}

/**
 */
function UtilDictGetValues(inDict)
{
   var outList = [];
   var key;
   for (key in inDict)
   {
      outList[outList.length] =  inDict[key];
   }
   
   return outList;
}


/**
 * UtilSetCenterPop: Centers the opening window to monitor screen by
 * manipulating the incoming features string.  The incoming features
 * string must contain an appropriate width and height setting.
 */
function UtilSetCenterPop(strFeatures, sWidth, sHeight)
{
   //allow it to be passed in for testing
   if (null == sWidth)
      sWidth = screen.width;

   if (null == sHeight)
      sHeight = screen.height;

   //acquire formerly global settings
   var dictDlg = UtilInitDlg(strFeatures);
   
   var w = UtilGetFeatureInt(dictDlg.FDel, strFeatures, dictDlg.dw);
   var h = UtilGetFeatureInt(dictDlg.FDel, strFeatures, dictDlg.dh);
   
   if (w < 0 || h < 0)
      return strFeatures;
	
   var l = Math.round((sWidth - w) / 2);
   var t = Math.round(((sHeight-60) - h) / 2);
   
   if (l<0)
      l = 2;
   
   if (t<0)
      t = 2;

   strFeatures = UtilSetFeature(dictDlg.FDel, strFeatures, dictDlg.dl, l);
   strFeatures = UtilSetFeature(dictDlg.FDel, strFeatures, dictDlg.dt, t);
   return strFeatures;
}

function UtilInitDlg(strFeatures)
{
   var i = strFeatures.indexOf(";");
   var res;
   if (i<0)
   {
      res= {FDel:",",
            dw:"width",
            dh:"height",
            dl: "left",
            dt: "top",
            ds: "scrollbars", 
            dr: "resizable"};
   }
   else
   {
      res= {
         FDel:";",
         dw: "dialogwidth",
         dh: "dialogheight",
         dl: "dialogleft",
         dt: "dialogtop",
         ds: "scrollbars",
         dr: "resizable"
      };
   }
   return res;
}

/** Extracts the value for the feature with the given feature name.
 */
function UtilGetFeature(FDel, strFeatures, featureName)
{

   var re = UtilCreateFeatureRe(FDel, featureName);
   var arrMatch=re.exec(strFeatures);
   if (null == arrMatch)
      return null;
   var res = arrMatch[2];//should be the value
   res = UtilTrimStr(res);
   return res;
}

/** Gets the feature of the given feature name and attempts to
 * parse and return is as a int.
 */
function UtilGetFeatureInt(FDel, strFeatures, featureName)
{

   var res  = UtilGetFeature(FDel, strFeatures, featureName);
   if (null == res)
      return -1;
   
   var p = res.indexOf("px");
   
   if (-1 != p)
   {
      res = res.substring(0, p);
      //willing to re-trim since we have adjusted the string
      res = UtilTrimStr(res);
   };
   
   if (isNaN(res))
      return -1;

   return parseInt(res);
}


/** Adds or replaces the given feature name  with the new value and
 * returns the modified feature string.
 */
function UtilSetFeature(FDel, strFeatures, featureName, featureValue)
{
   strFeatures = UtilRemoveFeature(FDel, strFeatures, featureName);
   
   return strFeatures+FDel+featureName+"="+featureValue;
}

/**
 * Creates an Re gives us a reliable way to locate and parse the value
 * associated with the given feature name.
 */
function UtilCreateFeatureRe(FDel, featureName)
{
   var re = new RegExp('(^|\\' + FDel + ')\\s*'+featureName+'\\s*[:=]([^\\' + FDel + ']*)($|\\' + FDel + ')',
                       'gi');//global (multiple) and ignore case
   return re;
}

/**
 * Removes the feature from the feature string and returns
 * the modified feature string.
 */
function UtilRemoveFeature(FDel, featuresStr, featureName)
{
   //re which can find matching features settings
   var re = UtilCreateFeatureRe(FDel, featureName);
   var outStr=featuresStr.replace(re, FDel);
   
   if ('' == outStr)
      return outStr;
   
   var start = 0;
   var end = outStr.length;
   
   if (outStr.charAt(0) == FDel)
      start++;
   if ((start != end) && outStr.charAt(end -1) == FDel)
      end--;
   return outStr.substring(start, end);
}


/**
 * Replaces the section of the string between removeStart and
 * removeEnd with the given replacement and returns the new/modified
 * string.
 */
function UtilReplaceString(strIn, removeStart, removeEnd, removeReplacement)
{
   var strOut = strIn.substring(0, removeStart)
      + removeReplacement
      + strIn.substring(removeEnd);
   return strOut;
}

/*
 * End of UtilSetCenterPop related code 
 */


var _UtilEnsureUrlIsVirtRelativeRe = null;
function UtilEnsureUrlIsVirtRelative(inUrl)
{
   //create the RE on demand
   if (null == _UtilEnsureUrlIsVirtRelativeRe)
   {

      //matches http or https followed by // followed by a hostname followed by a slash
      //extra pluses are to make sure that extra adjacent slashes don't throw
      //everything off
      _UtilEnsureUrlIsVirtRelativeRe = new RegExp('https?:[/\\\\][/\\\\][^/\\\\]+[/\\\\]+'
                            //followed by  a virtual directory name, followed by a slash
                                                 + '[^/\\\\]+[/\\\\]+'
                                                  //then whatever is relative, 
                                                  // it cannot be empty
                                                  + '(.+)$', 'i');
   }

   var arrMatches = _UtilEnsureUrlIsVirtRelativeRe.exec(inUrl);
   
   if (null == arrMatches)
      return inUrl;
   else
      return arrMatches[1];
}

var _UtilIsRootHttpishUrlRe = new RegExp('^https?:[/\\\\][/\\\\]','i');

/**
 * Returns true if URL looks like an http or https url with protocol
 * and full path.
 */
function UtilIsRootHttpishUrl(inUrl)
{
   if (null != _UtilIsRootHttpishUrlRe.exec(inUrl))
      return true;
   else
      return false;
}
   



var _UtilExtractFileNameFromUrlRe = new RegExp('((^|[/\\\\])([^/\\\\?&]+)[/\\\\]*)([?&].*)?$');

/**
 * Returns an array containing two items, the url not including the query string, and the query
 * string itself. The query string will always begin with a question mark.
 */
 
 
function UtilSplitUrlAtQueryString(inUrl)
{
   var arrMatch =  _UtilExtractFileNameFromUrlRe.exec(inUrl);
   var sParam = '';
   if (arrMatch[4])
   {
     sParam = '?'+arrMatch[4].substring(1);
   }
   return [inUrl.substring(0, 
                           inUrl.length - sParam.length),
           sParam];
}
/**
 * Returns the last filename portion of the URL ignoring params.
 * It returns the non-decoded version (%xx will be still be present).
 * Trailing slashes are also ignored.
 *
 * Examples:
 *  UtilExtractFileNameFromUrl("http://foo.myHost/images/image.gif")
 *  ->'image.gif'
 *  UtilExtractFileNameFromUrl("image.gif")
 *  ->'image.gif'
 *  UtilExtractFileNameFromUrl("..\\image.gif?foo=10")
 *  ->'image.gif'
 *  UtilExtractFileNameFromUrl("../\\\\//image%20foo.Gif\\/&foo")
 *  -> 'image foo.Gif'
 */
function UtilExtractFileNameFromUrl(inUrl, returnStartOffset)
{
   var arrMatch =  _UtilExtractFileNameFromUrlRe.exec(inUrl);
   
   if (null == arrMatch)
      return null;
   //return the actual file name portion only

   var rawFileName = arrMatch[3];

   if (!returnStartOffset)
      return rawFileName;
   else
   {
      var params = arrMatch[4];
      if (null == params)
         //missing (non matches) return empty string on IE and null on mozilla
         //so we make it IE like here
         params = '';
      
      //return a two item pair, the first being where the actual file name
      //started, the second being the offset where the filename starts
      return [arrMatch.index + arrMatch[2].length , rawFileName, params];
   }
}



/**
 * Returns a two element array containing the base part of the path
 * and the filename.
 */
function UtilExtractDirAndFileFromUrl(inUrl)
{
   var pair = UtilExtractFileNameFromUrl(inUrl, true);
   if (null == pair)
      return null;
   return [inUrl.substring(0,pair[0]),
           pair[1]];
}


/**
 * Returns true if code seems to be running on the server, else false
 * incidating running in a browser.
 */
function UtilIsServerSide()
{
   try 
   {
      if (window.document.getElementById)
         return false;
   }
   catch (e)
   {
      return true;
   }
}


/**
 * sort extracted value via extraction function.
 *
 * WARNING: This does the sort in place
 *
 * Note: the 'ignoreCase' is optional (added for #30238) This will allow us to do pure alphabetical sorting.
 */
function UtilSortObjectsByGetter(inArray, extractFunc, ignoreCase)
{
   var tmpArray = new Array(inArray.length);
   if (ignoreCase == null)
      ignoreCase = false;

   //this is based on the decorate, sort, undecorate approach

   //decorate by creating array of array pairs:
   //   1st pair item - extracted sort value string
   //   2nd pair item - actual object


   //Must terminate via null char since JS sort by "printed" represetation.
   //which will have a comma which can throw things off

   var nullChar = String.fromCharCode(0);

   var i;
   var curObj;
   for (i=0 ; i < inArray.length ; i++)
   {
      curObj = inArray[i];
      if (ignoreCase)
         tmpArray[i] = [String(extractFunc(curObj).toLowerCase()) + nullChar,
                        curObj];   // change the key string to lower.
      else
         tmpArray[i] = [String(extractFunc(curObj)) + nullChar, 
                        curObj];   // go with the default behaviour.
   }

   //Native sort safe with null char trick
   tmpArray = tmpArray.sort();
   
   //now write the values into the incomming array
   for (i=0 ; i < inArray.length ; i++)
   {
      inArray[i] = tmpArray[i][1];
      tmpArray[i] = null; //help gc
   }
   
   tmpArray = null;
   
   return inArray; //like the built in array sort function
}

/**
 * sort extracted value via extraction function.
 *
 * WARNING: This does the sort in place
 *
 * Note: This function sorts only on Numeric Key.
 */
function UtilSortObjectsByGetter_Numeric(inArray, extractFunc)
{
   var tmpArray = new Array(inArray.length);

   //this is based on the decorate, sort, undecorate approach

   //decorate by creating array of array pairs:
   //   1st pair item - extracted sort value string
   //   2nd pair item - actual object


   //Must terminate via null char since JS sort by "printed" represetation.
   //which will have a comma which can throw things off

   var nullChar = String.fromCharCode(0);

   var i;
   var curObj;
   for (i=0 ; i < inArray.length ; i++)
   {
      curObj = inArray[i];
      tmpArray[i] = [extractFunc(curObj), curObj];   // go with the default behaviour.
   }

   //Native sort safe with null char trick
   tmpArray = tmpArray.sort(function SortNumeric(num1, num2){return num1[0] - num2[0];});
   
   //now write the values into the incomming array
   for (i=0 ; i < inArray.length ; i++)
   {
      inArray[i] = tmpArray[i][1];
      tmpArray[i] = null; //help gc
   }
   
   tmpArray = null;
   
   return inArray; //like the built in array sort function
}

/**
 * Dynamically set the given handler to the given function.
 */
function UtilSetEventMethod(htmlObj, methodName, inFunc)
{
   try 
   {
      //mozilla only works by setting directly
      htmlObj[methodName]=inFunc;
   }
   catch (e)
   {
      //ignore exception, IE only works via setAttribute
      htmlObj.setAttribute(methodName,inFunc);
   }
}

/**
Dynamically set onmouseover handler to the give function
*/
function UtilSetOnMouseOverMethod(htmlObj, inFunc)
{
	UtilSetEventMethod(htmlObj, 'onmouseover', inFunc);
}

/**
Dynamically set onmouseout handler to the give function
*/
function UtilSetOnMouseOutMethod(htmlObj, inFunc)
{
	UtilSetEventMethod(htmlObj, 'onmouseout', inFunc);
}

/**
 * Dynamically set the onlick handler to the given function.
 */
function UtilSetOnclickMethod(htmlObj, inFunc)
{
   UtilSetEventMethod(htmlObj, 'onclick', inFunc);
}



/**

 * Dynamically set the onDbllick handler to the given function.

 */

function UtilSetOnDblclickMethod(htmlObj, inFunc)

{

   UtilSetEventMethod(htmlObj, 'ondblclick', inFunc);

}



/**

 * Dynamically set the onFocus handler to the given function.

 */

function UtilSetOnFocusMethod(htmlObj, inFunc)

{

   UtilSetEventMethod(htmlObj, 'onfocus', inFunc);

}





/** Returns true if the passed in object is an instance of the given
 * class. Instances of subclasses will also return false.
 */
function UtilIsClassInstance(inObj, classObj)
{
   if ((null == inObj) 
       || ("object" != typeof(inObj))
       || (inObj.constructor != classObj))
      return false;
   else
      return true;

}

/* This function is called from almost all <number>.js files and few others
*/
function UtilIsOpenerClosed()
{
   try
   {
      if (top.opener.closed == false)	
          return false;
   }
   catch (e)
   {
      // do nothing the flag is set to true by default.
   }
   return true;
}

/**
 * Function which opens the color palette in customization Module.
 * 
 * Should not be here since it is ServiceDesk specific.
 */
function UtilOpenColorEditor(SelectID)
{
	try{
		res = myShowModalDialog("CustomColorEditor.asp",document.getElementById(SelectID).value, UtilSetCenterPop("dialogTop:100; dialogLeft:100;dialogWidth:545px;dialogHeight:350px;status:0;toolbar:0;help:0")); 
		
		if (res==null)
			return;
                    

           	document.getElementById(SelectID).value = res;
		if (document.getElementById(SelectID).value != res)
		{
			var m = document.getElementById(SelectID).length;
			document.getElementById(SelectID).options[m] = new Option(res, res, true, true)
		
		}	
		DisplayColor(SelectID);			
		
	}
	
	catch(e){
	}
}

//adds, removes or deletes a key from the querystring. 
//returns the appropriate value based on the action. 
function UtilKeyInQueryString(inUrl, name, action, value, defaultReturnVal)
{
	var sReturn = (defaultReturnVal)?defaultReturnVal:"";
	
	var arrSplit = UtilSplitUrlAtQueryString(inUrl);
	var url = arrSplit[0];
	var queryStr = arrSplit[1];
	
	
	var arrQueryString = [];
	var a;
	var foundKeyInUrl = false
		
	if (!action)
		action = "get";
		
	if (queryStr.length)
	    {
  	       //remove question mark if there is a query string
	       queryStr = queryStr.substring(1);
		   arrQueryString = queryStr.split("&");
	    }

	for (a=0; a<arrQueryString.length; a++)
	{
		arrQS1 = arrQueryString[a].split("=");
		if (name == arrQS1[0])
		{
			if (action=="get")
				sReturn = decodeURIComponent(arrQS1[1]);
			else if (action=="delete")
			{				
				arrQueryString.splice(a,1);
				
				if (0 == arrQueryString.length)
				  //no params left, no question mark
				  sReturn = url;
				else
				   sReturn = url + "?" + arrQueryString.join("&");
			}
			else if (action=="set")	
			{
				arrQS1[1] = encodeURIComponent(value);				
				arrQueryString[a] = arrQS1.join("=")
				sReturn = url + "?" + arrQueryString.join("&");
			}
			foundKeyInUrl = true
			break;				
		}		
	}	
		
	if (action=="delete" && !queryStr.length)
		sReturn = inUrl;
		
	if (action=="set" && !foundKeyInUrl)
	{
		arrQueryString[arrQueryString.length] = encodeURIComponent(name) + "=" + encodeURIComponent(value);
		sReturn = url + "?" + arrQueryString.join("&");
	}
	
	return sReturn
}

//displays the assignto popup (dual or group) and returns the selected data. 
function UtilGetAssignTo(sMode, iSubjSeq, subject, moduleID, myShowModalDialog)
{
	if (!myShowModalDialog)
		myShowModalDialog=window.showModalDialog;
	
	var sAdditionalArgs=""
	var sPopupHeight="530"
	
	if (!sMode)
		sMode = "STAFF";
	
	if (sMode=="SUGGSTAFF")sAdditionalArgs="&SubjSeq="+subject
	if (sMode=="GROUP")sPopupHeight="395"
		
	strRetVal = myShowModalDialog ("AssignTo.asp?MODE="+sMode+sAdditionalArgs+"&CallingModuleName="+moduleID,window.document,"center=yes;help:no;dialogheight="+sPopupHeight+"px;dialogwidth=750px;status=yes");		
	if (strRetVal.length)
	{
		DataArr = strRetVal.split(String.fromCharCode(2))
		return DataArr
	}	
		
	return ""
}	

// saves a cookie value and expiration date
function setCookie (name, value, expires, curDoc) 
{
	if (!curDoc)
		curDoc = document;
		
	if (!expires) expires = new Date()
	curDoc.cookie = name + "=" + encodeURIComponent(value) +     
	"; expires=" + expires.toGMTString() +  "; path=/"; 
}                                                       
	
// deletes an existing cookie
function delCookie (name, curDoc) 
{
	if (!curDoc)
		curDoc = document;

	var expireNow = new Date();
	curDoc.cookie = name + "=" +
	"; expires=Thu, 01-Jan-70 00:00:01 GMT" +  "; path=/";
}

/* 
	This is the new Common Funtion for Argument substitution in Common_Label_Msg.js,Common_System_Msg.js and 
	AllTitle.inc.This function is called by GetString() in Common_Label_Msg.js and by FormatVBMsg in 
	Common_System_Msg.vbs.

*/	

function GetStringCommon(sText,sArgs)
{

	if(typeof(window) == 'undefined')          //if called from server side call the Resourse DLL directly
	{
		throw "GetString() Function Called from Server Side - Utility.js ";
	}
	else
	{
		if (typeof(sArgs)=="string")
		{
			sArgs = sArgs.split("||");
		}
		var strTest= "";
		if (sText !=null && sText != "" &&  typeof(sText)!='undefined')
			strTest=sText;


		//Fix for Bug # 32408 -- Kiran
        //made Netscape/Firefox/Mozilla compatible
		var oRegExpParam  = new RegExp("\\{[0-9]?[0-9]?\\}","ig"); 
		var oRegExpString = new RegExp("#\\{[0-9]?[0-9]?\\}#","ig");
		var oRegExpRevert = new RegExp("###[0-9]?[0-9]?###","ig");
		var arrString = strTest.match(oRegExpString);
		if(arrString != null)
		{
			for(i = 0;i < arrString.length;i++)
			{
				var Start = strTest.indexOf(arrString[i]);
				var End	  = Start + arrString[i].length;
				strTest = strTest.replace(arrString[i],"###" + strTest.substring(Start+2,End-2) + "###");	
			}
		}
		var arrParam = strTest.match(oRegExpParam);
		if(arrParam != null)
		{
			for(i = 0;i < arrParam.length;i++)
			{
				var Start = strTest.indexOf(arrParam[i]);
				var End	  = Start + arrParam[i].length;
				strTest = strTest.replace(arrParam[i],sArgs[parseInt(strTest.substring(Start+1,End-1))]);	
			}	
		}
		if(arrString != null)
		{		
			var arrRevert = strTest.match(oRegExpRevert);
			for(i = 0;i < arrRevert.length;i++)
			{
				var Start = strTest.indexOf(arrRevert[i]);
				var End	  = Start + arrRevert[i].length;
				strTest = strTest.replace(arrRevert[i],"{" + strTest.substring(Start+3,End-3) + "}");	
			}
		}	
		return strTest;
		//End of fix # 32408 -- Kiran
	}
}

//RT Functions for popup's off of BASE element 
//Moved\Modified by kiran 
function myShowModalDialog(arg1,arg2,arg3)
{
	if (!(arg3 == "" || typeof(arg3)=="undefined" || arg3 == null))
	{
		var dictDlg = UtilInitDlg(arg3);
		arg3 = UtilRemoveFeature(dictDlg.FDel,arg3,dictDlg.ds);
		arg3 = UtilRemoveFeature(dictDlg.FDel,arg3,dictDlg.dr);
		arg3 = UtilSetFeature(dictDlg.FDel, arg3,dictDlg.ds,"yes");
		arg3 = UtilSetFeature(dictDlg.FDel, arg3,dictDlg.dr,"yes");
	}
	var oBaseColl = document.getElementsByTagName('BASE')
	if(oBaseColl[0] != null)
	{
		return showModalDialog347(oBaseColl[0].href + arg1,arg2,arg3)
	}
	else
	{
		return showModalDialog347(arg1,arg2,arg3)
	}
}

function myOpenWindow(arg1,arg2,arg3)
{
	// fix for bug# 32100 - Vaishali 17 Feb 2005
	//if (!(arg3 == "" || typeof(arg3)=="undefined" ))
	if (!(arg3 == "" || typeof(arg3)=="undefined" || arg3==null ))
	//Bug# 32100 end
	{
		var dictDlg = UtilInitDlg(arg3);
		arg3 = UtilRemoveFeature(dictDlg.FDel,arg3,dictDlg.ds);
		arg3 = UtilRemoveFeature(dictDlg.FDel,arg3,dictDlg.dr);
		arg3 = UtilSetFeature(dictDlg.FDel, arg3,dictDlg.ds,"yes");
		arg3 = UtilSetFeature(dictDlg.FDel, arg3,dictDlg.dr,"yes");
	}
	else
	{
		var arg3 = "";
		var dictDlg = UtilInitDlg(arg3);
		arg3 = UtilSetFeature(dictDlg.FDel, arg3,dictDlg.ds,"yes");
		arg3 = UtilSetFeature(dictDlg.FDel, arg3,dictDlg.dr,"yes");
	}
	var oBaseColl = document.getElementsByTagName('BASE')
	if(oBaseColl[0] != null)
	{
		return window.open(oBaseColl[0].href + arg1,arg2,arg3)
	}
	else
	{
		return window.open(arg1,arg2,arg3)
	}
}

function UtilIsHashEmpty(inData)
{
	for (key in inData)
		return false;
		
	return true;	
}

/*Elm Feature 347*/
var modalDialogWindow;
var modalDialogInterval;

function showModalDialog347(arg1, arg2, arg3)
{
	if(navigator.appName == "Microsoft Internet Explorer")
	{
		if (arg3.length > 0)
		{
			var arrFeatures, re;
			var strFeatures = arg3.toLowerCase();
			arrFeatures = strFeatures.split(",");
			for (var i=0; i< arrFeatures.length; i++)
			{
				if ((arrFeatures[i].match(/height=/) != null) || (arrFeatures[i].match(/width=/) != null))
				{
					arrFeatures[i] += "px"
				}
			}
			strFeatures = arrFeatures.join(";");
			
			if (strFeatures.match(/dialogleft/) == null)
			{
				strFeatures = strFeatures.replace(/left/,"dialogleft");
				strFeatures = strFeatures.replace(/screenx/,"dialogleft");
			}
			if (strFeatures.match(/dialogtop/) == null)
			{
				strFeatures = strFeatures.replace(/top/,"dialogtop");
				strFeatures = strFeatures.replace(/screeny/,"dialogtop");
			}
			if (strFeatures.match(/dialogheight/) == null)
				strFeatures = strFeatures.replace(/height/,"dialogheight");
			if (strFeatures.match(/dialogwidth/) == null)
				strFeatures = strFeatures.replace(/width/,"dialogwidth");
			strFeatures = strFeatures.replace(/pxpx/g,"px");
			strFeatures = strFeatures.replace(/=/g,":");
		}
		return window.showModalDialog(arg1, arg2, strFeatures);
	}
	else
	{
		modalDialogWindow=window.open(arg1, arg2 ,arg3); 
		modalDialogWindow.focus(); 
		modalDialogInterval = window.setInterval("ModalDialogMaintainFocus()",5);
		return modalDialogWindow;
	}
}
 
function ModalDialogMaintainFocus()
{
	try
	{
		if (modalDialogWindow.closed)
		{
			window.clearInterval(modalDialogInterval);
			return;
		}
		modalDialogWindow.focus(); 
	}
  	catch (e) {}
}

function closeModalDialog347()
{
	if (modalDialogWindow != undefined)
	{
		modalDialogWindow.close();
	}
		
}

function converIntToColor(iColor)
{
	var fString = "#000000"
	var sBGColor =  ""
	iColor = parseInt(iColor)
	if (iColor.toString(16).toUpperCase().length > 0)
		sBGColor = fString.substring(0,(7-iColor.toString(16).toUpperCase().length))+ iColor.toString(16).toUpperCase()
	return sBGColor		
}

function converColorToInt(sColor)
{
	var iColor = -1
	if(sColor.indexOf("#")!=-1) 
	{
		sColor=sColor.substring(sColor.indexOf("#")+1,sColor.length);
		iColor = parseInt(sColor,16);
	}
	return iColor;
}

function UtilConvertSecondsToTime(stime)
{
	if ((stime==null)||(stime=="")) return "00:00:00"

	stime		= Math.round(stime)
	var hr		= Math.floor(stime/3600)
	var stemp	= stime-(hr*60*60)
	var min		= Math.floor(stemp/60)
	var sec		= stemp - min * 60
		
	return ((hr < 10) ? "0"+hr :hr)+":"+((min < 10) ? "0"+min :min) +":"+((sec < 10) ? "0"+sec :sec)
}

function UtilTimeToSeconds(sInterval)
{
	lDuration = 0;
	if(sInterval=="")
		sInterval="00:00:00"
	
	sInterval = sInterval.split(":")
	
	if(sInterval.length < 3)
		return 0;
	
	lDuration = lDuration + sInterval[0] * 3600
	lDuration = lDuration + sInterval[1] * 60
	
	return lDuration;
}

function getResponseExpiresAbsoluteDate()
{
   return "1/1/81";
}
/* For blocking SQL-Injection/Cross-site scripting in HelpDesk */
function checkForScripts(strVar)
{
    if(strVar != "" && strVar != "undefined" && strVar != undefined)
    {
    strVar = strVar.replace(/</g, "").replace(/>/g, "").replace(/javascript:(.*)/gi, "");
    strVar = strVar.replace(/eval(.*)/gi, "");
    strVar = strVar.replace(/script(.*)/gi, "");
        strVar = strVar.replace(/alert(.*)/gi, "");
    }
    return strVar;
}

/* For blocking SQL-Injection/Cross-site scripting in HelpDesk */
function checkForInjection(strVar)
{
    strVar = checkForScripts(strVar);
    if(isNaN(strVar))
    {
      Response.Redirect("timeout.asp") 
    }
}
/**
 * Check for valid characters in a filename
 */
function UtilValidateFileName(str) 
{
    if (!(/^[^\\\/\:\*\?\"\<\>\|\.]+(\.[^\\\/\:\*\?\"\<\>\|\.]+)+$/.test(str)))
    {
       Response.End();
    }
}

/*Elm Feature 347*/
/* © Copyright 1998, 2004-2010 BMC Software, Inc. */
/* The source code embodied herein is a trade secret of BMC Software, Inc. All use, disclosure, and/or reproduction not specifically and expressly authorized, in writing, by BMC Software, Inc. is prohibited. */
//%>

