
var errDoc = new ActiveXObject("microsoft.xmldom");
// if you provide an http URL location, the load() method returns immediately and your
// document object will still be empty because the data hasn't come back from the server yet.
errDoc.async = false;
if (bIsIE55)
	errDoc.validateOnParse = false;
errDoc.load("xSSErrors.xml");

// ReturnCode: TC (transfer call)          CC (Call Control)         PC (Place call)              VB (device busy)
// Parameter1: 1@45# (call ID)                                       1000 (number to dial)        1:1001 (device ID)
// parameter2: 1000 (destination)
// parameter3:

// inputCodes:   TC-CC-PC-VB
// parameters:   ^|1@45#|1000^^|1000^|1:1001
// xSSErrorsXML: <TC> Transfer call ({1}) to {2} failed. {*}</TC>
//               <CC> Call Control failure. {*}</CC>
//               <PC> Placing a call to {1} failed. {*}</PC>
//               <VB> Device {1} is busy. </VB>
// results: 'Transfer call (1@45#) to 1000 failed. Call Control failure. Placing a call to 1000 failed. Device 1:1001 is busy.'

// xSSErrorsXML: <TC-CC-PC> Transfer call ({1}) failed because the call to {2} could not be placed. {*}</TC>
//               <VB> Device {1} is busy. </VB>
// results: 'Transfer call (1@45#) failed because the call to 1000 could not be placed. Device 1:1001 is busy.'


// Parameter 'inputCode' is a list of Return code strings such as "-BC-OE-OAI_15" or "-VP".
// Parameter 'subName' is the sub node to select once we locate the string. typically, it's either 'Long' or 'Short'.
// parameter 'parameters' is a delimited list of Strings, where each string is a delimited list
//            of the string parameters that will be required by the return code (such as "^" or "^|34|35" or "^|1000^|1001|1002)
function getErrorString(inputCode, subName, parameters)
{
	// Take the parameters (which is a delimited list of delimited strings)
	// and put them into a an array of arrays (of strings)
	var ParamsAsArrayOfStrings = ParseDelimitedList(parameters);

	// If we can get an exact match, return it
	var root = "ERROR_MESSAGES/";
	// remove the leading delimiter, a hyphen ('-')
	var trimmed = inputCode.substring(1, inputCode.length);

	// An error code is not going to be found if contains any spaces,
	// so we check for them first
	if (inputCode.indexOf(' ') == -1)
	{
		var errorString = GetErrorNode(root+trimmed, subName);
		if (errorString != null)
		{
			// If we enter here, we found the ENTIRE inputCode (which may be a
			// single code, or may be a concatination of codes).
			// Convert the parameters from an array of arrays into a single array.
			var singleArray = new Array;
			for (var i=0 ; i<ParamsAsArrayOfStrings.length ; i++)
			{
				singleArray = singleArray.concat(ParseDelimitedList(ParamsAsArrayOfStrings[i]));
			}
			return insertParameters(errorString.text, singleArray);
		}
	}

	// If couldn't get an exact match, then we need
	// to break this up into smaller strings, and
	// match them individually
	var CodesAsArray = ParseDelimitedList(inputCode);
	// If this is not a list, and we couldn't find it in the XML file
	// then we have an error condition, so just return the code itself.
	if (CodesAsArray.length == 1)
		return "Unrecognized error code: "+inputCode;

	// Get the last item in the list and the last parameter from the lists
	var lastCode         = CodesAsArray[CodesAsArray.length-1];
	var lastParamAsArray = ParseDelimitedList(ParamsAsArrayOfStrings[ParamsAsArrayOfStrings.length-1]);
	// Remove these items from the lists
	CodesAsArray.length--;
	ParamsAsArrayOfStrings.length--;

	// Then rebuild the string back into a single string using the same delimiter
	var reducedInputCodes = DelimitList(CodesAsArray, inputCode.charAt(0));
	var reducedParameters = DelimitList(ParamsAsArrayOfStrings, parameters.charAt(0));

	// Then use that list to get the simpler string recursively
	var translatedSimpleString = getErrorString(reducedInputCodes, subName, reducedParameters);

	// Now, we can parse the string and if a {*}, {#}, {##}, {###}... or {1}, {2}, {3}...
	// exists, we can interperet them correctly
	// Replace the {*} with any sub-reason:
	var nLoc = translatedSimpleString.indexOf('{*}');
	if (nLoc != -1)
	{
		// replace {*} with the nested error code, converted to a string.
		var lastString = GetErrorNode(root+lastCode, subName);
		if (lastString != null)
		{
			// Insert any parameters to this string:
			var returnString = insertParameters(lastString.text, lastParamAsArray);
			return translatedSimpleString.replace('{*}', returnString);
		}
		return translatedSimpleString.replace('{*}', lastCode);
	}
	// Replace all occuances of '{#}' with the last code from the list
	var re = /{#}/g;
	translatedSimpleString = translatedSimpleString.replace(re, lastCode);  //make the replacement
	// Replace all occuances of '{##' with '{#', thereby reducing the number of '#' in all brackets
	re = /{##/g;
	return translatedSimpleString.replace(re, '{#');  //make the replacement and return the results
}
function insertParameters(messageString, parametersArray)
{
	// Replace all occuances of '{n}' with the (n-1)th item in the parameters array
	var i=1;
	// For every parameter that is supplied, find the place(s) where it should be used.
	// If a parameter is supplied, but does not have a corresponding placement holder
	// in the string, it will be ignored.
	for (var i=1 ; i<= parametersArray.length ; i++)
	{
		re = new RegExp("\{["+i+"]\}","g");
		messageString = messageString.replace(re, parametersArray[i-1]);
	}
	// If there were any parameters required, but not suplied, we need
	// to fill in a question mark in their place.
	re = new RegExp("\{[0123456789]\}","g");
	messageString = messageString.replace(re, "?");
	return messageString;
}

function GetErrorNode(path, subName)
{
	return errDoc.selectSingleNode(path+"/"+subName);
}

// ************************************************************
// ****************** DELIMITER FUNCTIONS *********************
// ************************************************************

function ParseMultiValueList(strList)
{
	if (strList)
	{
		var objsArray = ParseDelimitedList(strList);
		var multiValueArray = new Array;
		for (var i=0; i < objsArray.length; i++)
			multiValueArray[multiValueArray.length] = ParseDelimitedList(objsArray[i]);
		return multiValueArray;
	}
}

function ParseDelimitedList(strList)
{
	if (strList)
	{
		var del = strList.charAt(0);
		var strRemainder = strList.substring(1, strList.length)
		return (strRemainder.indexOf(del) != -1) ? strRemainder.split(del) : new Array(strRemainder);
	}
	return new Array;
}

function FindDelimiter(objArray)
{
	delList = "^|~`!@#$%&*()_+/<>?;:,.-=[]\"\'{}¤¶§ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890•¦ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥ƒáíóúñÑªº¿¬½¼¡«»¯ßµ±÷˜°·² "
	var strArray = objArray.toString();
	for (var i=0; i < delList.length; i++)
	{
		if (strArray.indexOf(delList.charAt(i)) == -1)
			return delList.charAt(i);
	}
}

function DelimitList(objArray, custDel)
{
	var cDel = (custDel) ? custDel : FindDelimiter(objArray)
	return cDel + objArray.join(cDel);
}

function DelimitMultiValueList(objArray)
{
	var tVals = new Array
	for (var j=0; j < objArray.length; j++)
	{
		tVals[j] = DelimitList(objArray[j])
	}
	return DelimitList(tVals);
}

