// EFM Community Client Side Survey API
// Copyright 1997-2008 Vovici Corporation. All rights reserved.
// Version: 4.0.0

/// <summary>
/// Creates a new instance of the Client Side Survey API.
/// </summary>
function PerseusSurvey() {	
	this.NumberDecimalSeparator = ".";
	this.NumberGroupSeparator = ",";
	this.NumberGroupSizes = 3;
}

/// <summary>
/// Returns the form element containing the survey.
/// </summary>
PerseusSurvey.prototype.SurveyForm = function() {
	var form = document.getElementById("PdcSurvey");
	if (!form) form = document.forms["PdcSurvey"];
	return form;
}

/// <summary>
/// Gets a value from the query string and returns it or blank if not found.
/// </summary>
// <param name="parameterName">A valid url parameter</param>
PerseusSurvey.prototype.GetUrlParameter = function(parameterName) {
	// Get the query string minus the ?
	var queryString = location.search.substring(1);

	// Convert plus to space
	queryString = queryString.replace(/\+/g, " ");
	// Split the args by & and the look at each named pair.
	var params = queryString.split("&");
	for (var x = 0; x < params.length; x++) {
		var pair = params[x].split("=");
		if ((pair.length == 2) && (pair[0] == parameterName)) {
			return decodeURI(pair[1]);
		}
	}
	
	return '';
}

/// <summary>
/// Gets a value from the query string and sets it to the
/// specified fill in the blank, essay or hidden question.
/// </summary>
// <param name="heading">A valid dbHeading</param>
// <param name="parameterName">A valid url parameter</param>
PerseusSurvey.prototype.SetUrlParameter = function(heading, parameterName) {
	this.SetTextValue(heading, this.GetUrlParameter(parameterName));
}

/// <summary>
/// Auto Advances the survey to the next page, 
/// or submits if on the last page.
/// </summary>
PerseusSurvey.prototype.AutoAdvance = function() {
	if (document.PdcSurvey.next) {
		document.PdcSurvey.next.click();
	} else if (document.PdcSurvey.submit) {
		document.PdcSurvey.submit.click();
	} else {
		document.PdcSurvey.submit();
	}
}
	
/// <summary>
/// Returns the value for a fill in the blank or essay question as a string.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
PerseusSurvey.prototype.GetTextValue = function(heading) {
	var value = '';
	var inputField = document.getElementById(heading);
	if (inputField) value = inputField.value;
	return value.toString();
}

/// <summary>
/// Sets the value for a fill in the blank, essay or hidden question.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="newValue">Value to assign to field</param>
PerseusSurvey.prototype.SetTextValue = function(heading, newValue) {
	var inputField = document.getElementById(heading);
	if (inputField) inputField.value = newValue;
}

/// <summary>
/// Returns the value for a fill in the blank  as number.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
PerseusSurvey.prototype.GetNumericValue = function(heading) {
	var textValue = this.GetTextValue(heading);
	var numValue = this.ToEnglishNumber(textValue);
	return Number(numValue);
}

/// <summary>
/// Indicates if the specified essay question, fill in the blank topic
/// or choose one list/dropdown has been answered. Does not indicate whether
/// its a valid answer.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
PerseusSurvey.prototype.IsAnswered = function(heading) {
	var inputField = document.getElementById(heading);
	if (inputField) {
		switch (inputField.tagName) {
			// Fill In
			case "INPUT":
				switch(inputField.type) {
					case "text":
					case "password":
					case "hidden":
						var value = inputField.value;
						return (value != '');				
				}
				break;
			// Essay
			case "TEXTAREA":
				var value = inputField.value;
				return (value != '');	
				break;
			// Choose One List/Dropdown
			case "SELECT":
				var selectedIndex = inputField.selectedIndex;
				var value = inputField.options[selectedIndex].value;
				return (value != '0' && value != '');
				break;
		}
	} else {
		if (document.getElementById(heading + "_DD")) {
			var monthElement = document.getElementById(heading + "_MM");
			var selectedIndex = monthElement.selectedIndex;
			var month = Number(monthElement.options[selectedIndex].value);
			var day = Number(document.getElementById(heading + "_DD").value);
			var year = Number(document.getElementById(heading + "_YYYY").value);
			if (month != 0 || day != 0 || year != 0) return true;
			
		}
	}
	return false;
}

/// <summary>
/// Given an list of field headings, returns true 
/// if any of them have been answered.
/// </summary>
/// <param>List of dbHeadings e.g. 'Q1_1', 'Q1_2', 'Q1_3'</param>
PerseusSurvey.prototype.AnyAnswered = function(heading) {
	for (var x = 0; x < arguments.length; x++) {
		if (this.IsAnswered(arguments[x])) return true;
	}
	return false;
}

/// <summary>
/// Given an list of field headings, returns true 
/// if any of them have not been answered.
/// </summary>
/// <param>List of dbHeadings e.g. 'Q1_1', 'Q1_2', 'Q1_3'</param>
PerseusSurvey.prototype.AnyNotAnswered = function(heading) {
	for (var x = 0; x < arguments.length; x++) {
		if (!this.IsAnswered(arguments[x])) return true;
	}
	return false;
}

/// <summary>
/// Given a fill in the blank heading, returns true if the length 
/// of the respondents answer is less than the specified length.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="length">Minimum Length</param>
PerseusSurvey.prototype.IsMinLength = function(heading, length) {
	return (this.GetTextValue(heading).length < length);
}

/// <summary>
/// Given a fill in the blank heading, returns true if the length 
/// of the respondents answer is greater than the specified length.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="length">Maximum Length</param>
PerseusSurvey.prototype.IsMaxLength = function(heading, length) {
	return (this.GetTextValue(heading).length > length);
}

/// <summary>
/// Given a fill in the blank heading, returns true if the value 
/// of the respondents answer is within than the specified range.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="minValue">Minimum Value</param>
/// <param name="maxValue">Maximum Value</param>
PerseusSurvey.prototype.IsInRange = function(heading, minValue, maxValue) {
	var numValue = this.GetNumericValue(heading);
	if (minValue != null && numValue < minValue) return false;
	if (maxValue != null && numValue > maxValue) return false;
	return true;
}

/// <summary>
/// Indicates if the specified fill in topic contains a whole number.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
PerseusSurvey.prototype.IsInteger = function(heading) {
	var inputField = document.getElementById(heading);
	if (inputField) {
		var text = inputField.value;
		// If number contains both a group seperator and a decimal seperator
		// We can determine if they entered the number for the wrong region.
		var groupSep = text.indexOf(this.NumberGroupSeparator);
		// If seperator is ascii 160 space, and was not found, also search for ascii 32 space
		if (groupSep == -1 && this.NumberGroupSeparator == "\u00A0") {
			groupSep = text.indexOf("\ ");
		}			
		var decimalSep = text.indexOf(this.NumberDecimalSeparator);
		if (groupSep != -1 && decimalSep != -1 && (groupSep > decimalSep)) return false;
		// Test Concurrent Separators
		var reGroup = new RegExp("\\" + this.NumberGroupSeparator + "{2,}");
		var reDecimal = new RegExp("\\" + this.NumberDecimalSeparator + "{2,}");
		if(reGroup.exec(text) != null || reDecimal.exec(text) != null) return false;
		var number = this.ToEnglishNumber(text);		
		if (number.match(/^-?\d+$/)) return true;
	}
	return false;
}

/// <summary>
/// Indicates if the specified fill in topic contains a real number.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
PerseusSurvey.prototype.IsFloat = function(heading) {
	var inputField = document.getElementById(heading);
	if (inputField) {
		var text = inputField.value;
		// If number contains both a group seperator and a decimal seperator
		// We can determine if they entered the number for the wrong region.
		var groupSep = text.indexOf(this.NumberGroupSeparator);
		// If seperator is ascii 160 space, and was not found, also search for ascii 32 space
		if (groupSep == -1 && this.NumberGroupSeparator == "\u00A0") {
			groupSep = text.indexOf("\ ");
		}			
		var decimalSep = text.indexOf(this.NumberDecimalSeparator);
		if (groupSep != -1 && decimalSep != -1 && (groupSep > decimalSep)) return false;
		// Test Concurrent Separators
		var reGroup = new RegExp("\\" + this.NumberGroupSeparator + "{2,}");
		var reDecimal = new RegExp("\\" + this.NumberDecimalSeparator + "{2,}");
		if(reGroup.exec(text) != null || reDecimal.exec(text) != null) return false;		
		var number = this.ToEnglishNumber(text);
		if (number.match(/^-?\d*(\.\d+)?$/)) return true;			
	}
	return false;
}

/// <summary>
/// Indicates if the specified fill in topic contains a valid e-mail address.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
PerseusSurvey.prototype.IsEmail = function(heading) {
	var inputField = document.getElementById(heading);
	if (inputField) {
		var email = inputField.value;
		if (email.match(/^[\w_\-\.\']+[\%\+]?[\w_\-\']*\@[0-9a-zA-Z\-]+\.[0-9a-zA-Z\-\.]+$/)) return true;
	}
	return false;
}

/// <summary>
/// Indicates if the specified fill in topic contains a valid date.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
PerseusSurvey.prototype.IsDate = function(heading) {
	// Get Month/Day/Year Values
	var monthElement = document.getElementById(heading + "_MM");
	var selectedIndex = monthElement.selectedIndex;
	var month = Number(monthElement.options[selectedIndex].value);
	var day = Number(document.getElementById(heading + "_DD").value);
	var year = Number(document.getElementById(heading + "_YYYY").value);
	var yearSize = document.getElementById(heading + "_YYYY").value.length;
	// Not a number
	if (isNaN(month) || isNaN(day) || isNaN(year)) return false;
	// Month out of range
	if (month < 1 || month > 12) return false;
	// Day out of range
	if (day < 1 || day > 31) return false;
	// 30 Day Months
	if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) return false;
	// Leap Year Check
	if (month == 2) {
		var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
		if (day > 29 || (day == 29 && !isleap)) return false;
	}
	// Years must be a positive 4 digit integer.
	if (year <= 0 || yearSize != 4 || !this.IsInteger(heading + "_YYYY")) return false;
	return true;
}

/// <summary>
/// Private - Given an array of field headings, returns their total as a number.
/// </summary>
/// <param name="heading">Array of dbHeadings</param>
PerseusSurvey.prototype.calculateTotal = function(headings) {
	var total = 0;
	var decimalPlaces = 0;

	for (var i = 0; i < headings.length; i++) {
		var heading = headings[i];
		var inputField = document.getElementById(heading);
		if (inputField) {
			var number = this.ToEnglishNumber(inputField.value);
			// Add leading 0 if missing
			if (number.indexOf(".") == 0) number = "0" + number;
			// Get decimal precision
			var decimalIndex = number.indexOf(".");
			if (decimalIndex != -1) {
				var decimalPlacesCount = number.length - (decimalIndex + 1);
				if (decimalPlacesCount > decimalPlaces) decimalPlaces = decimalPlacesCount;
			}
			if (number.match(/^-?\d+(\.\d+)?$/)) {
				total += parseFloat(number);
			}
		}
	}

	if (decimalPlaces > 0) total = total.toFixed(decimalPlaces);		

	return total;		
}

/// <summary>
/// Given an list of field headings, returns their total as a number.
/// </summary>
/// <param>List of dbHeadings e.g. 'Q1_1', 'Q1_2', 'Q1_3'</param>
PerseusSurvey.prototype.NumericTotal = function() {		
	return this.calculateTotal(arguments);
}

/// <summary>
/// Given an list of field headings, returns their total as a string
/// formatted for the surveys culture.
/// </summary>
/// <param>List of dbHeadings e.g. 'Q1_1', 'Q1_2', 'Q1_3'</param>
PerseusSurvey.prototype.StringTotal = function() {
	var total = this.calculateTotal(arguments);	
	return this.ToRegionNumber(total);
}	

/// <summary>
/// Converts a number to a string with regional formatting.
/// </summary>
/// <param name="number">Number</param>
PerseusSurvey.prototype.ToRegionNumber = function(number) {
	var negative = (number < 0);
	
	// Convert to string
	number = number.toString();		
					
	// Insert group seperators
	var parts = number.split('.');
	var base = Math.abs(parts[0]).toString();
	var groups = [];
	while(base.length > this.NumberGroupSizes) {
		var temp = base.substr(base.length - this.NumberGroupSizes);
		groups.unshift(temp);
		base = base.substr(0, base.length - this.NumberGroupSizes);
	}
	if(base.length > 0) { groups.unshift(base); }
	base = groups.join(this.NumberGroupSeparator);
	
	// Add decimal places if any with decimal symbol
	if (parts.length > 1) {
		number = base + this.NumberDecimalSeparator + parts[1];
	} else {
		number = base;
	}

	// Add minus sign if negative value
	if (negative) number = "-" + number;
	
	return number;		
}

/// <summary>
/// Converts a region based number to US English Format.
/// </summary>
/// <param name="number">Number string for survey region</param>
PerseusSurvey.prototype.ToEnglishNumber = function(number) {
	while (number.indexOf(this.NumberGroupSeparator) != -1)
		number = number.replace(this.NumberGroupSeparator, "");
	// If seperator is ascii 160 space, also strip out ascii 32 space
	if (this.NumberGroupSeparator == "\u00A0") {
		while (number.indexOf("\ ") != -1)
			number = number.replace("\ ", "");
	}
	number = number.replace(this.NumberDecimalSeparator, ".");
	return number;
}

/// <summary>
/// Hides rows (topics) in a table question based on a previous choose many's answers
/// And optionally sets odd/even row indicators.
/// </summary>
/// <param>
/// First arguement is value to test 1 for selected, 0 for not selected
/// Second arguement is true to display odd/even rows. false to not display odd/even rows.
/// Remaining arguements are the dependent value (Usually a placeholder e.g. %Q1_1%) and the row id.
/// e.g. 1, true, '1|Q2T1', '0|Q2T2', '0|Q2T3', '1|Q2T4', '0|Q2T5'
/// </param>
PerseusSurvey.prototype.DisplayDynamicRows = function() {	
	var viscount = 0;
	var value = arguments[0];
	var oddeven = arguments[1];
	for (var i = 2; i < arguments.length; i++) {		
		var pair = arguments[i].split("|");
		var row = document.getElementById(pair[1]);
		if (row) {
			if (pair[0] != value) {			
				row.style.display="none";
			} else if (oddeven) {
				viscount++;
				row.className = (viscount % 2 == 1) ? "odd-row" : "even-row";
			}
		}
	}
}

/// <summary>
/// Hides columns (choices) in a table question based on a previous choose many's answers
/// </summary>
/// <param>
/// First arguement is value to test 1 for selected, 0 for not selected
/// Remaining arguements are the dependent value (Usually a placeholder e.g. %Q1_1%) and the column id.
/// e.g. 1, '1|Q2_A_C1', '0|Q2_A_C2', '0|Q2_A_C3', '1|Q2T4', '0|Q2_A_C4'
/// </param>
PerseusSurvey.prototype.DisplayDynamicColumns = function() {	
	var value = arguments[0];
	for (var i = 1; i < arguments.length; i++) {		
		var pair = arguments[i].split("|");
		var cells = document.getElementsByName(pair[1]);
		if (pair[0] != value) {
			for(j = 0; j < cells.length; j++) {
				cells[j].style.display = "none";
			}
		}
	}
}

/// <summary>
/// Hides choices in a table question dropdown based on a previous choose many's answers
/// </summary>
/// <param>
/// First arguement is value to test 1 for selected, 0 for not selected
/// Second arguement is the dropdown prefix
/// Third arguement is number of topics
/// Remaining arguements are the dependent values (Usually a placeholder e.g. %Q1_1%).
/// e.g. 1, 'Q3_A', 5, '1', '0', '0', '1', '0'
/// </param>
PerseusSurvey.prototype.DisplayDynamicList = function() {		
	var value = arguments[0];
	var tableSide = arguments[1];
	var topicCount = arguments[2];
	for (var i = 1; i <= topicCount; i++) {
		var dbHeading = tableSide + "_" + i;
		for (var j = 3; j < arguments.length; j++) {					
			if (arguments[j] != value) {
				var choice = j - 2;
				this.RemoveListChoice(dbHeading, choice);
			}
		}		
	}
}

/// <summary>
/// Removes all choices with the specified value from a dropdown or list box.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="choiceValue">Value of choice to remove</param>
PerseusSurvey.prototype.RemoveListChoice = function(heading, choiceValue) {
	var choiceList = document.getElementById(heading);
	var optionCount = choiceList.options.length - 1;
	
	for (var i = optionCount; i > 0; i--) {
		if (choiceList.options[i].value == choiceValue) choiceList.options[i] = null;				
	}
}

/// <summary>
/// Jumps to the specified question on the current page and displays an optional alert message.
/// </summary>
/// <param name="heading">Anchor Heading to jump to e.g. A1 for Question Q1</param>
/// <param name="message">Alert message to display</param>
PerseusSurvey.prototype.GotoQuestion = function(heading, message) {
	window.location = "#" + heading;
	if (message) {
		alert(message);
	}
}

/// <summary>
/// Shows a Tool Tip for the specified glossary id relative to the calling word.
/// </summary>
/// <param name="heading">The element triggering the tool tip</param>
/// <param name="glossaryId">A valid glossary id</param>
PerseusSurvey.prototype.ShowToolTip = function(element, glossaryId) {
	var glossaryElement = document.getElementById(glossaryId);
	if (glossaryElement) {
		glossaryElement.style.visibility = "visible";
		// Set Top
		var top = 0;
		var topElement = element;
		while(topElement.offsetParent) {
			top += topElement.offsetTop;
			topElement = topElement.offsetParent;
		}
		top -= glossaryElement.offsetHeight
		if (top < 0) top = element.offsetTop + element.offsetHeight;
		glossaryElement.style.top = top + "px";
		// Set Left
		var width = document.body.offsetWidth;		
		var left = 0;
		var leftElement = element;
		while(leftElement.offsetParent) {
			left += leftElement.offsetLeft;
			leftElement = leftElement.offsetParent;
		}
		if ((left + glossaryElement.offsetWidth) > width) {
			left = Math.max(0, width - glossaryElement.offsetWidth);
		}
		glossaryElement.style.left = left + "px";	
	}	
}

/// <summary>
/// Hides the Tool Tip with the specified glossary id for the calling word.
/// </summary>
/// <param name="heading">The element triggering the tool tip</param>
/// <param name="glossaryId">A valid glossary id</param>
PerseusSurvey.prototype.HideToolTip = function(element, glossaryId) {
	var glossaryElement = document.getElementById(glossaryId);
	if (glossaryElement) {		
		glossaryElement.style.visibility = "hidden";
	}
}

/// <summary>
/// Populates the following list based on the
/// item selected in the specified list. 
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="index">Index of list who's value has changed</param>
PerseusSurvey.prototype.GetNextList = function(heading, index) {
	this.ClearSubsequentLists(heading, index);
	var listElement = document.getElementById(heading + "_" + index);
	var selectedIndex = listElement.selectedIndex;
	var selectedItem = listElement.options[selectedIndex];
	var listId = selectedItem.getAttribute("listid");
	if (listId && listId != 0) {
		var args = "GETLIST;" + heading + ";" + index + ";" + listId;
		this.AjaxRequest(args);
	}
}

/// <summary>
/// Populates the first list based on the listid.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="index">Index of list who's value has changed</param>
PerseusSurvey.prototype.GetFirstList = function(heading, listId) {
	var args = "GETLIST;" + heading + ";" + 0 + ";" + listId;
	this.AjaxRequest(args);
}

/// <summary>
/// Populates the following list using a web service call.
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="index">Index of list who's value has changed</param>
PerseusSurvey.prototype.GetNextListWS = function(heading, index) {
    // Get selected values of list items up to and including this list
    var listValues;
    for(var i = 1; i <= index; i++) {
        var nextListElement = document.getElementById(heading + "_" + i);    
        if (nextListElement && nextListElement.tagName == "SELECT") {
            var selectedIndex = nextListElement.selectedIndex;
            if (selectedIndex >= 0) {
                var selectedValue = nextListElement.options[selectedIndex].value;
                listValues += ";" + heading + "_" + i + "=" + selectedValue;
            }
        }
    }
	this.ClearSubsequentLists(heading, index);
	var args = "GETLISTWS;" + heading + ";" + index + listValues;
	this.AjaxRequest(args);
}

/// <summary>
/// Removes all the choices in the list following the
/// specified index except for the list caption. 
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="index">Index of list after which choices should be removed</param>
PerseusSurvey.prototype.ClearSubsequentLists = function(heading, index) {	
	var nextListIndex = parseInt(index) + 1;
	var nextListElement = document.getElementById(heading + "_" + nextListIndex);
	while (nextListElement && nextListElement.tagName == "SELECT") {
		var optionCount = nextListElement.options.length;
		for(var i = 0; i < optionCount; i++) {
			nextListElement.options[1] = null;
		}
		nextListElement.disabled = true;
		nextListIndex++;
		nextListElement = document.getElementById(heading + "_" + nextListIndex);
	}	
}

/// <summary>
/// Populates the specified list from an XML collection of ListItems. 
/// </summary>
/// <param name="heading">A valid dbHeading</param>
/// <param name="index">Index of list after to populate</param>
PerseusSurvey.prototype.PopulateList = function(heading, index, xml) {	
	var listElement = document.getElementById(heading + "_" + index);
	var listItems = xml.documentElement;
	var optionCount = 1;
	for (i = 0; i < listItems.childNodes.length; i++) {
		var listItem = listItems.childNodes[i];
		if (listItem.nodeType == 1) {
			listElement.options[optionCount] = new Option(listItem.firstChild.firstChild.nodeValue, listItem.getAttribute('value'));
			listElement.options[optionCount].setAttribute("listid", listItem.getAttribute('targetlistid'));
			optionCount++;
		}
    }
	listElement.disabled = false;
}

/// <summary>
/// Creates an instance of the XML HTTP Request object
/// Used for subsequent Ajax Requests.
/// </summary>
PerseusSurvey.prototype.GetXmlHTTP = function() {
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		return new ActiveXObject("Microsoft.XMLHTTP");
	}
}

/// <summary>
/// Submits an Ajax Request to the Survey Engine.
/// </summary>
/// <param name="parameters">Arguments to submit with Ajax Request</param>
PerseusSurvey.prototype.AjaxRequest = function(parameters) {
	var xmlhttp = this.GetXmlHTTP();
	if (xmlhttp != null) {
		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState == 4) {
    				// Safari may return undefined
        			if (xmlhttp.status == 200 || typeof(xmlhttp.status) == 'undefined') {
        				var parts = parameters.split(';');
					var xml = null;
					if (window.ActiveXObject) {
						var xml = new ActiveXObject("Microsoft.XMLDOM");
						xml.loadXML(xmlhttp.responseText);
					} else {
						xml = xmlhttp.responseXML;
					}
					switch(parts[0]) {
						case "GETLIST":
						case "GETLISTWS":
							survey.PopulateList(parts[1], parseInt(parts[2]) + 1, xml);        				
							break;
					}
				} else {
					alert("Ajax Request Failed: " + xmlhttp.status);
				}
		    }
		}
		// Strip server path
		var url = this.SurveyForm().action;
		if(url.indexOf("/") != 0) {
			var pos = url.indexOf("//");
			pos = url.indexOf("/", pos + 2);
			url = url.substr(pos);
		}
		url = url.replace("se.ashx", "list.ashx");
		xmlhttp.open("GET", url, true);
		// Safari Caching Bug
		xmlhttp.setRequestHeader('If-Modified-Since','Wed, 15 Nov 1995 00:00:00 GMT');
		xmlhttp.setRequestHeader("isajaxrequest", "1");
		xmlhttp.setRequestHeader("ajaxargs", parameters);
		xmlhttp.setRequestHeader("PdcSessionId", this.GetTextValue("PdcSessionId"));		
		xmlhttp.send('');
	}
}