/*
render.js - Written by Todd Moyer - Copyright 2010, 2011.

Unauthorized use is not permitted.
*/

var requestedVersion;
var useVersion;

if (pageRequest == null) pageRequest = '/';
pageRequest = String(pageRequest).toLowerCase();

var siteName = '';
var siteKeywords = '';
var siteDescription = '';
var siteAnalyticsId = '';
var sitePrefix = '';
var siteDomainName = '';
var siteTaxableState = '';
var siteTaxRate = 0;
var SSLenabled = true;
var pageURL = location.href;

var pageTemplate;
var pageKeywords = '';
var pageDescription = '';
var pageName = '';
var pageXML;
var pageNodeCount = 0;
var pageDataXML;
var globalWidgetData;
var pageForms = new Array();
var pageFormIndex = 0;
var pageFormElementIndex = 0;
var currentFormIndex = null;

var deferredImages = new Array();
var pageMaps = new Array(); // for Google Maps (API)
var twitterWidgets = new Array();

var jQueryUIScopeId = 'jqueryui';
var jQueryUIScopeClass = 'jqueryuiClass';

var loadedData = new Array();
var referencesProcessed = new Array();

var transitionQueueCount = 0;

var ajaxLoadImageDark = '/images/ajax-loader5.gif';
var ajaxLoadImageLight = '/images/ajax-loader.gif';

var lastHash = '';


if (getVars != "") {
	var getVarsArray = getVars.split("&");
	for (var i=0; i<getVarsArray.length; i++) {

		tempS = getVarsArray[i].split("=");
		if (tempS[0] == "v") requestedVersion = tempS[1];
	}
}

useVersion = defaultPublishedVersion;



var cookieVersion = getCookie('version');

if (cookieVersion != null) useVersion = cookieVersion;

if (pageRequest.substr(sitePrefix.length + 1, 5) == 'admin') {
	useVersion = defaultEditVersion;
}

if (requestedVersion != null) useVersion = requestedVersion;



var cssUnits = new Array();
cssUnits['px'] = 'pixels';
cssUnits['%']  = 'percent';
cssUnits['in'] = 'inches';
cssUnits['cm'] = 'centimeters';
cssUnits['mm'] = 'millimeters';
cssUnits['em'] = 'X font width';
cssUnits['ex'] = 'X font height';
cssUnits['pt'] = 'points';
cssUnits['pc'] = 'picas (12 points)';

var StateNames = new Array();
var StateCodes = new Array();
 StateNames[0] = "Alabama";         StateCodes[0] = "AL";
 StateNames[1] = "Alaska";          StateCodes[1] = "AK";
 StateNames[2] = "Arizona";         StateCodes[2] = "AZ";
 StateNames[3] = "Arkansas";        StateCodes[3] = "AR";
 StateNames[4] = "California";      StateCodes[4] = "CA";
 StateNames[5] = "Colorado";        StateCodes[5] = "CO";
 StateNames[6] = "Connecticut";     StateCodes[6] = "CT";
 StateNames[7] = "Delaware";        StateCodes[7] = "DE";
 StateNames[8] = "Florida";         StateCodes[8] = "FL";
 StateNames[9] = "Georgia";         StateCodes[9] = "GA";
StateNames[10] = "Hawaii";         StateCodes[10] = "HI";
StateNames[11] = "Idaho";          StateCodes[11] = "ID";
StateNames[12] = "Illinois";       StateCodes[12] = "IL";
StateNames[13] = "Indiana";        StateCodes[13] = "IN";
StateNames[14] = "Iowa";           StateCodes[14] = "IA";
StateNames[15] = "Kansas";         StateCodes[15] = "KS";
StateNames[16] = "Kentucky";       StateCodes[16] = "KY";
StateNames[17] = "Louisiana";      StateCodes[17] = "LA";
StateNames[18] = "Maine";          StateCodes[18] = "ME";
StateNames[19] = "Maryland";       StateCodes[19] = "MD";
StateNames[20] = "Massachusetts";  StateCodes[20] = "MA";
StateNames[21] = "Michigan";       StateCodes[21] = "MI";
StateNames[22] = "Minnesota";      StateCodes[22] = "MN";
StateNames[23] = "Mississippi";    StateCodes[23] = "MS";
StateNames[24] = "Missouri";       StateCodes[24] = "MO";
StateNames[25] = "Montana";        StateCodes[25] = "MT";
StateNames[26] = "Nebraska";       StateCodes[26] = "NE";
StateNames[27] = "Nevada";         StateCodes[27] = "NV";
StateNames[28] = "New Hampshire";  StateCodes[28] = "NH";
StateNames[29] = "New Jersey";     StateCodes[29] = "NJ";
StateNames[30] = "New Mexico";     StateCodes[30] = "NM";
StateNames[31] = "New York";       StateCodes[31] = "NY";
StateNames[32] = "North Carolina"; StateCodes[32] = "NC";
StateNames[33] = "North Dakota";   StateCodes[33] = "ND";
StateNames[34] = "Ohio";           StateCodes[34] = "OH";
StateNames[35] = "Oklahoma";       StateCodes[35] = "OK";
StateNames[36] = "Oregon";         StateCodes[36] = "OR";
StateNames[37] = "Pennsylvania";   StateCodes[37] = "PA";
StateNames[38] = "Rhode Island";   StateCodes[38] = "RI";
StateNames[39] = "South Carolina"; StateCodes[39] = "SC";
StateNames[40] = "South Dakota";   StateCodes[40] = "SD";
StateNames[41] = "Tennessee";      StateCodes[41] = "TN";
StateNames[42] = "Texas";          StateCodes[42] = "TX";
StateNames[43] = "Utah";           StateCodes[43] = "UT";
StateNames[44] = "Vermont";        StateCodes[44] = "VT";
StateNames[45] = "Virginia";       StateCodes[45] = "VA";
StateNames[46] = "Washington";     StateCodes[46] = "WA";
StateNames[47] = "West Virginia";  StateCodes[47] = "WV";
StateNames[48] = "Wisconsin";      StateCodes[48] = "WI";
StateNames[49] = "Wyoming";        StateCodes[49] = "WY";

// Functions for dynamic expressions

function COUNT(dataIdentifier, childrenOnly, widgetDataOnly, dataValue) {
	var returnValue = 0;
	if ((widgetDataOnly != true) && (pageDataXML != null)) {
		if (childrenOnly == true) var dataNodes = $(pageDataXML).children(dataIdentifier);
		else var dataNodes = $(pageDataXML).find(dataIdentifier);
		if (dataNodes!= null) returnValue = dataNodes.length;
	}
	if (returnValue == 0) {
		//alert(globalWidgetData.length);
		if (globalWidgetData != null) {
			if (childrenOnly == true) var dataNodes = $(globalWidgetData).children(dataIdentifier);
			else var dataNodes = $(globalWidgetData).find(dataIdentifier);
			if (dataNodes!= null) returnValue = dataNodes.length;
		}
	}
	if ((returnValue > 0) && (dataValue != null))  {
		returnValue = 0;
		for (var i=0; i<dataNodes.length; i++) {
			if ($(dataNodes[i]).text() == dataValue) returnValue += 1;
		}
		debugOut('COUNT ' + dataIdentifier + ' = ' + dataValue + ' is ' + returnValue);
	}
	//alert('COUNT: ' + dataIdentifier + '=' + returnValue);
	return returnValue;
}
function SIZE(dataIdentifier) {
	var returnValue = 0;
	if (pageDataXML != null) {
		var dataNodes = $(pageDataXML).find(dataIdentifier);
		if (dataNodes.length == 1) returnValue = String($(dataNodes).text()).length;
	}
	if (returnValue == 0) {
		//alert(globalWidgetData.length);
		if (globalWidgetData != null) {
			var dataNodes = $(globalWidgetData).children(dataIdentifier);
			if (dataNodes.length == 1) returnValue = String($(dataNodes).text()).length;
		}
	}
	debugOut('SIZE: ' + dataIdentifier + '=' + returnValue);
	return returnValue;
}

// End functions for dynamic expressions

function debugOut(msg) {
	try {
		console.log(msg);
	}
	catch (e) { }
}
function newXML(xmlString) {
	if (xmlString == null) xmlString = '';

	if (window.DOMParser) {
		var parser = new DOMParser();
		try {
			var xmlDoc = parser.parseFromString(xmlString, "text/xml");
		}
		catch (e) {
			var xmlDoc = false;
		}
	}
	else {
		// Internet Explorer
		var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async = "false";
		try {
			xmlDoc.loadXML(xmlString); 
		}
		catch (e) {
			var xmlDoc = false;
		}
  	}
	return xmlDoc;
}

function moneyFormat(moneyValue) {
	var moneyValueString = String(moneyValue);
	moneyValue = parseFloat(moneyValueString);
	return Number(moneyValue).toFixed(2);
}

function echeck(str) {
	// check email address
	invalidChars = new Array("(", ")", "[", "]", "\\", ";", ":", ",", "<", ">", "__");
	var at="@"
	var dot="."
	var lat=str.indexOf(at)
	var lstr=str.length
	var ldot=str.indexOf(dot)
	if (str.indexOf(at) == -1) return false;

	if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr) return false;
	// does not have @, starts or ends with @
		
	
	if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr) return false;


	if (str.indexOf(at,lat+1)!=-1) return false;
	// has more than one @
		
	if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot) return false;

	if (str.indexOf(dot,(lat+2))==-1) return false;

	if (str.indexOf(" ")!=-1) return false;
	
	for (var i=0; i<invalidChars.length; i++) {
		if (str.indexOf(invalidChars[i]) != -1) return false;
	}

	return true;
}

function sortNodes(sNodes, sortedBy, sortType, sortDirection) {
	if (sortType == 'number') {
		var sortFunction = function(a, b) {
			var rVal = 0;
			var aVal = parseFloat($(a).find(sortedBy + ':first').text());
			var bVal = parseFloat($(b).find(sortedBy + ':first').text());
			if (aVal < bVal) rVal = -1;
			else if (aVal > bVal) rVal = 1;
			if (sortDirection == 'descending') rVal *= -1;
			return rVal;
		}
	}
	else if (sortType == 'date') {
		var sortFunction = function(a, b) {
			var rVal = 0;
			var aVal = new Date($(a).find(sortedBy + ':first').text());
			var bVal = new Date($(b).find(sortedBy + ':first').text());
			if (aVal < bVal) rVal = -1;
			else if (aVal > bVal) rVal = 1;
			if (sortDirection == 'descending') rVal *= -1;
			return rVal;
		}
	}
	else {
		// text or other
		var sortFunction = function(a, b) {
			var rVal = 0;
			var aVal = String($(a).find(sortedBy).text()).toUpperCase();
			var bVal = String($(b).find(sortedBy).text()).toUpperCase();
			if (aVal < bVal) rVal = -1;
			else if (aVal > bVal) rVal = 1;
			if (sortDirection == 'descending') rVal *= -1;
			return rVal;
		}
	}
	
	sNodes.sort(sortFunction);
}

function renderPage() {

	pageTemplate = $(pageXML).attr('Template');

	$.ajax({
		type: "GET",
		url: sitePrefix + "/xml/v" + useVersion + "/templates/" + pageTemplate + ".xml",
		dataType: "xml",
		success: function(templateXML) {
			//alert("Template '" + pageTemplate + "' loaded for page " + $(pageXML).attr('Name'));
			var templateNode = $(templateXML).find('Template');
			
			pageNodeCount = 0;
			var bodyRef = document.getElementsByTagName("body").item(0);
			applyTagAttributes(bodyRef, templateNode, null, 'template');

			applyTagAttributes(bodyRef, pageXML, null, 'page');

			$(bodyRef).attr('id','theBody');

			insertElements(bodyRef, $(templateXML.childNodes[0]).contents(), 0);
			var tempTitle = sitePageNamePrefix;

			if ((pageName != "") && (pageName != null)) {
				
				if ((pageDataXML != null) && (pageName.indexOf('%') > -1)) {
					pageName = replaceData(pageName);
				}

				if ((tempTitle == '') || (tempTitle == null)) tempTitle = pageName;
				else tempTitle += " - " + pageName;
			}
			
			document.title = tempTitle;
			
			onAfterRender();

		},
		error: function(req, textStatus, errorThrown) {
			alert("error loading template xml: textStatus=" + textStatus);
		}
	});
}

function bindInputEvents(inputNode, inputSelectAction, inputSelectTarget, inputUnSelectAction, inputUnSelectTarget) {
	if (inputNode == null) return false;

	var inputNodeType = $(inputNode).attr('type');
	if ($(inputNode).is('select')) inputNodeType = 'select';
	
	//alert('inputNode=' + inputNode);
	//alert('inputNodeType=' + inputNodeType);

	
	var onInputFunction = function(action, targ) {
		//alert(action + ', ' + targ);
		var thisTarg = $('#' + targ);
		if (thisTarg != null) {
			if (action == 'hide') {
				thisTarg.fadeOut(300);
			}
			else if (action == 'show') {
				thisTarg.fadeIn(1000);
			}
		}
	}

	var onInputEventFunction = function(e) {
		if (inputNodeType == 'checkbox') {
			if (inputNode.checked) onInputFunction(inputSelectAction, inputSelectTarget);
			else onInputFunction(inputUnSelectAction, inputUnSelectTarget);
		}
		else if (inputNodeType == 'select') {
			//alert(inputNode.selectedIndex);
			var selA = inputSelectAction.split(',');
			var targA = inputSelectTarget.split(',');
			onInputFunction(selA[inputNode.selectedIndex], targA[inputNode.selectedIndex]);

			if (inputUnSelectAction != null) {
				var unSelA = inputUnSelectAction.split(',');
				var unTargA = inputUnSelectTarget.split(',');
				if (inputNode.lastSelectedIndex != null) onInputFunction(unSelA[inputNode.lastSelectedIndex], unTargA[inputNode.lastSelectedIndex]);
			}
			inputNode.lastSelectedIndex = inputNode.selectedIndex;
		}
		else {
			onInputFunction(inputSelectAction, inputSelectTarget);
		}
	};

	if (inputNodeType == 'checkbox') inputNode.onclick = onInputEventFunction;
	else if (inputNodeType == 'select') inputNode.onchange = onInputEventFunction;
	else inputNode.onfocus = onInputEventFunction;

}

function bindFormSubmitEvent(bNode, fIndex) {
	var onInputEventFunction = function(e) {
		processForm(fIndex);
	};

	bNode.onclick = onInputEventFunction;
}
function replaceQuotes(inStr) {
	inStr = String(inStr).split('"').join('&quot;');
	return inStr;
}
function processForm(formIndex) {

	if (isNaN(formIndex)) {
		for (i=0; i<pageForms.length; i++) {
			if (pageForms[i].formName == formIndex) {
				formIndex = i;
				break;
			}
		}
	}

	var formIsValid = true;
	var formXML = pageForms[formIndex].definition;
	var formElements = pageForms[formIndex].inputElements;
	var sendData = pageForms[formIndex].sendData;
	var sendDataNode = pageForms[formIndex].sendDataNode;
	var formName = pageForms[formIndex].formName;
	var submitButtonName = pageForms[formIndex].submitButtonName;
	var notesName = pageForms[formIndex].submitNotesName;
	var validationMsgName = pageForms[formIndex].validationMsgName;
	var showValidationMessage = pageForms[formIndex].showValidationMessage;
	var showSubmitMessage = pageForms[formIndex].showSubmitMessage;
	var validationMessage = '';
	var validationMessageAlert = '';
	var lastFieldSetName = '_';
	var fieldSetOpen = false;
	var formEmailDataTo = $(formXML).attr('EmailDataTo');
	var formEmailNoticeTo = $(formXML).attr('EmailNoticeTo');
	var formAppendDataTo = $(formXML).attr('AppendDataTo');
	var formScript = $(formXML).attr('Script');
	var formClass = $(formXML).attr('Class');
	var formAjaxGraphic = $(formXML).attr('AjaxGraphic');
	var formAjaxURL = $(formXML).attr('AjaxURL');
	var formAjaxMethod = $(formXML).attr('AjaxMethod');
	var formAjaxDataType = $(formXML).attr('AjaxDataType');
	var xmlBody = 'xmldoc=';
	var formDataQuery = '';

	if (formAjaxGraphic == null) formAjaxGraphic = ajaxLoadImageLight;

	xmlBody += '<Data><FormData Page="' + encodeURIComponent(pageRequest) + '" PageName="' + encodeURIComponent(pageName) + '"';
	xmlBody += ' FormIndex="' + encodeURIComponent(formIndex) + '"';
	if (formEmailDataTo != null) xmlBody += ' EmailDataTo="' + encodeURIComponent(formEmailDataTo) + '"';
	if (formEmailNoticeTo != null) xmlBody += ' EmailNoticeTo="' + encodeURIComponent(formEmailNoticeTo) + '"';
	if (formAppendDataTo != null) xmlBody += ' AppendDataTo="' + encodeURIComponent(formAppendDataTo) + '"';
	if (formScript != null) xmlBody += ' Script="' + encodeURIComponent(formScript) + '"';
	if (formName != null) xmlBody += ' Name="' + encodeURIComponent(formName) + '"';
	if (formClass != null) xmlBody += ' Class="' + encodeURIComponent(formClass) + '"';

	if (formAjaxURL == null) formAjaxURL = sitePrefix + '/forms.php';
	if (formAjaxMethod == null) formAjaxMethod = 'POST';
	if (formAjaxDataType == null) formAjaxDataType = 'xml';

	xmlBody += '>';

	$('#' + validationMsgName).css('display','none');

	if (formElements == null) {
		return false;
	}

	for (var i=0; i<formElements.length; i++) {
		var fieldIsValid = true;
		var eXML = formElements[i].definition;
		var inputElement = $('#' + formElements[i].inputName);
		var labelElement = $('#' + formElements[i].labelName);
		var inputType = $(eXML).attr('Type');
		var inputNote = $(eXML).attr('Note');
		var inputLabelText = $(eXML).attr('Label');
		var inputRequired = $(eXML).attr('Required');
		var inputName = formElements[i].inputName;
		var inputMultiLine = $(eXML).attr('MultiLine');
		var inputOldValue = formElements[i].oldValue;
		var inputHidden = false;

		if (inputType == null) inputType = 'text';

		if ((inputLabelText == '') || (inputLabelText == null)) {
			inputLabelText = inputName;
		}
		if (inputLabelText == null) inputLabelText = '';

		var fieldSetName = formElements[i].fieldSetLabel;
		
		if (fieldSetName != lastFieldSetName) {
			if (fieldSetOpen) xmlBody += '</FieldSet>';
			xmlBody += '<FieldSet';
			if ((fieldSetName != null) && (fieldSetName!='')) xmlBody += ' Name="' + encodeURIComponent(fieldSetName) + '"';
			xmlBody += '>'
			fieldSetOpen = true;
		}

		if (inputElement.is(':hidden') && (inputType != 'hidden')) {
			// hidden field
			inputHidden = true;
		}
		
		if (true) {
			if (inputRequired == 'true') {
				if (inputType == 'checkbox') {
					if (!inputElement[0].checked) fieldIsValid = false;
				}
				else {
					// works for text and select input types
					if (inputElement.val() == '') fieldIsValid = false;
				}
			}
			if (!fieldIsValid) {
				labelElement.attr('class', 'formError');
				formIsValid = false;
				validationMessage += '<span class="formError">'+ inputLabelText + '</span> is required.<br/>';
				validationMessageAlert += inputLabelText + ' is required. ';
			}
			else {
				labelElement.removeClass('formError');
				if (inputType == 'email') {
					var inputValue = inputElement.val();
					if (inputValue != '') {
						if (!echeck(inputValue)) {
							fieldIsValid = false;
							validationMessage += '<span class="formError">'+ inputValue + '</span> is not a valid email address.<br/>';
							validationMessageAlert += inputValue + ' is not a valid email address. ';
						}
					}
				}
				else if (inputType == 'checkbox') {
					if (inputElement[0].checked) inputValue = 'yes';
					else inputValue = 'no';
				}
				else {
					var inputValue = inputElement.val();
				}

				if (!fieldIsValid) {
					labelElement.attr('class', 'formError');
					formIsValid = false;
				}
				else {
					var fieldName = encodeURIComponent(inputLabelText);
					
					
					xmlBody += '<Field Name="' + fieldName + '" Type="' + encodeURIComponent(inputType) + '" ';
					if (inputNote != null) xmlBody += 'Note="' + encodeURIComponent(inputNote) + '" ';
					if (inputRequired != null) xmlBody += 'Required="' + encodeURIComponent(inputRequired) + '" ';
					if (inputMultiLine != null) xmlBody += 'MultiLine="' + encodeURIComponent(inputMultiLine) + '" ';
					if (inputHidden) xmlBody += 'Hidden="true" ';
					if (inputOldValue != null)  xmlBody += 'OldValue="' + encodeURIComponent(replaceQuotes(inputOldValue)) + '" ';
					if (inputType == 'select') {
						var inputOptions = $('#' + formElements[i].inputName + ' option');
						var optionsString = '';
						for (var j=0; j<inputOptions.length; j++) {
							optionsString += inputOptions[j].text;
							if (j < inputOptions.length - 1) optionsString += '|';
						}
						xmlBody += 'InputOptions="' + encodeURIComponent(optionsString) + '" ';
					}
					
					xmlBody += '>';
					xmlBody += encodeURIComponent(inputValue);
					xmlBody += '</Field>';

					if (formDataQuery != '') formDataQuery += '&';
					formDataQuery += fieldName + '=' + encodeURIComponent(inputValue);
				}
			}
		}	
		lastFieldSetName = fieldSetName;
	}

	//alert(formElements.length + ", " + submitButtonName);
	if (fieldSetOpen) xmlBody += '</FieldSet>';
	xmlBody += '</FormData>';

	if (formIsValid) {
		// submit ajax data
		$('#' + submitButtonName).css('display','none');
		$('#' + notesName).html('<img src="' + formAjaxGraphic + '" valign="middle" hspace="4"/> Sending... <a href="javascript:cancelForm(' + formIndex + ')">cancel</a>');
		$('#' + notesName).fadeIn(1200);

		

		if ((sendData != null) && (sendData != '')) {
			var formSendData = getDataSource(sendData);
			if ((sendDataNode != null) && (sendDataNode != '')) formSendData = $(formSendData).find(sendDataNode);
			var formSendDataSerialized = serialize(formSendData, 0, true, true);
			xmlBody += formSendDataSerialized;
		}

		xmlBody += '</Data>';

		//alert(xmlBody);
		debugOut('formDataQuery=' + formDataQuery);

		var ajaxSendData = xmlBody;
		// if a custom AJAX url is provided send the form query string instead of the XML
		if ($(formXML).attr('AjaxURL') != null) ajaxSendData = formDataQuery;
		
		$.ajax({
			type: formAjaxMethod,
			processData: false,
			dataType: formAjaxDataType,
			url: formAjaxURL,
			data: ajaxSendData,
			success: function(data, textStatus, XMLHttpRequest) {
				formSuccess(data, textStatus, XMLHttpRequest, formIndex);
			},
			error: function(XMLHttpRequest, textStatus, errorThrown) {
				alert('Error sending form data: ' + textStatus + ', ' + errorThrown);
			}
		});
	}
	else {
		if (showSubmitMessage != 'false') {
			$('#' + notesName).html('Please check <span class="formError">highlighted</span> fields.');
			$('#' + notesName).fadeIn(1200);
		}
		
		$('#' + validationMsgName).html(validationMessage);
		
		if (showValidationMessage != 'false') $('#' + validationMsgName).slideDown(300);
		else alert(validationMessageAlert);
	}
}

function formSuccess(data, textStatus, XMLHttpRequest, formIndex) {

	debugOut('formSuccess. formIndex=' + formIndex);

	var formXML = pageForms[formIndex].definition;
	var formAjaxDataType = $(formXML).attr('AjaxDataType');
	var formAjaxResponseMessage = $(formXML).attr('AjaxResponseMessage');

	if (formAjaxDataType == null) formAjaxDataType = 'xml';

	if ((formAjaxDataType == 'xml') && (formAjaxResponseMessage == null)) {
		var responseNode = $(data).find('FormResponse');
		if (responseNode != null) {
			var formIndex = $(responseNode).attr('FormIndex');
			var formSuccess = $(responseNode).attr('Success');
			var formValidationMessage = $(responseNode).attr('ValidationMessage');
			var formNotes = $(responseNode).attr('Notes');
			var successPage = $(responseNode).attr('SuccessPage');
			var failPage = $(responseNode).attr('FailPage');

			if (formSuccess == 'true') {
				var notesName = pageForms[formIndex].submitNotesName;
				var successMessageName = pageForms[formIndex].successMessageName;
				if ((successPage == null)||(successPage == '')) successPage = pageForms[formIndex].successPage;	

				if (successMessageName != null) {
					var successMessageNode = $('#' +  successMessageName);
					$('#' + notesName).html(successMessageNode.html());
				}
				else {
					$('#' + notesName).html('Successfully sent.');
				}

				if (successPage != null) {
					setTimeout('window.location="' + sitePrefix + successPage + '";', 500);
				}
			}
			else {
				cancelForm(formIndex);

				if (formValidationMessage != null) {
					var validationMsgName = pageForms[formIndex].validationMsgName;
					var showValidationMessage = pageForms[formIndex].showValidationMessage;
					if (showValidationMessage != 'false') {
						$('#' + validationMsgName).html('<span class="formError">' + formValidationMessage + '</span>');
						$('#' + validationMsgName).slideDown(300);
					}
				}
				if (formNotes != null) {
					var notesName = pageForms[formIndex].submitNotesName;
					$('#' + notesName).html(formNotes);
					$('#' + notesName).fadeIn(1200);
				}
				if (failPage != null) {
					setTimeout('window.location="' + failPage + '";', 500);
				}
			}
		}
		else {
			alert('There was a problem processing your form data.');
			cancelForm(formIndex);
		}
	}
	else if (formAjaxDataType == 'json') {
		var successMessage = '';
		var notesName = pageForms[formIndex].submitNotesName;
		var successMessageName = pageForms[formIndex].successMessageName;

		if (formAjaxResponseMessage != null) successMessage = data[formAjaxResponseMessage];
		else if (successMessageName != null) {
			var successMessageNode = $('#' +  successMessageName);
			successMessage = successMessageNode.html();
		}
		else successMessage = 'Successfully sent.'

		debugOut('successMessage=' + successMessage);

		$('#' + notesName).html(successMessage);
		$('#' + notesName).show('drop', null, 400);

		cancelForm(formIndex);
	}
}

function cancelForm(formIndex) {
	if (formIndex == null) return;

	var submitButtonName = pageForms[formIndex].submitButtonName;
	var notesName = pageForms[formIndex].submitNotesName;

	//alert('cancelForm: ' + formIndex + ', submitButtonName=' + submitButtonName);
	$('#' + submitButtonName).fadeIn(1000);
	$('#' + notesName).css('display', 'none');
}
function updateFormValue(inputLabel, newValue) {
	// takes either a label or ID of form element
	
	if (document.forms) {
		for (var i=0; i<pageForms.length; i++) {
			var formElements = pageForms[i].inputElements;
			for (var j=0; j<formElements.length; j++) {
				var eXML = formElements[j].definition;
				var thisInputLabel = $(eXML).attr('Label');
				var inputType = String($(eXML).attr('Type')).toLowerCase();
				var inputElement = $('#' + formElements[j].inputName);
				if (thisInputLabel == inputLabel) {
					//alert(thisInputLabel);
					inputElement.val(newValue);
				}
				else if (inputLabel == formElements[j].inputName) {
					inputElement.val(newValue);
				}
			}
		}
	}
}
function updateFormOptions(inputLabel, newOptions) {
}
function bindImageMouseEvents(imgNode, imgId, imgSrc, imgSrcMouseOver) {
	var imgOverFunc = function() {
		$('#' + imgId).attr('src', imgSrcMouseOver);
	}
	var imgOutFunc = function() {
		$('#' + imgId).attr('src', imgSrc);
	}
	imgNode.onmouseover = imgOverFunc;
	imgNode.onmouseout = imgOutFunc;
}
var scrollingTimer;
function scrollPageRight(containerElementId, loop) {
	var container = $('#' + containerElementId);
	var currentScroll = container.scrollLeft();
	var containerWidth = container.width();
	var newScroll = currentScroll + containerWidth;
	debugOut('scrollPageRight: ' + containerElementId + ', ' + newScroll);
	scrollToH(containerElementId, newScroll, loop)
}
function scrollPageLeft(containerElementId, loop) {
	var container = $('#' + containerElementId);
	var currentScroll = container.scrollLeft();
	var containerWidth = container.width();
	var newScroll = currentScroll - containerWidth;
	debugOut('scrollPageLeft: ' + containerElementId + ', ' + newScroll);
	scrollToH(containerElementId, newScroll, loop)
}
function scrollToH(containerElementId, positionH, loop) {
	clearTimeout(scrollingTimer);

	var container = $('#' + containerElementId);
	var currentScroll = container.scrollLeft();
	var incrementalPosition;

	if (currentScroll == positionH) {
		//alert('done');
		return;
	}
	
	var delta = positionH - currentScroll;

	if (delta > 0) {
		incrementalPosition = currentScroll + (delta / 5) + 2;
		if (incrementalPosition > positionH) incrementalPosition = positionH;
	}
	else {
		incrementalPosition = currentScroll + (delta / 5) - 2;
		if (incrementalPosition < positionH) incrementalPosition = positionH;
	}
	incrementalPosition = Math.round(incrementalPosition);
	
	container.scrollLeft(incrementalPosition);

	currentScroll = container.scrollLeft();

	if (currentScroll == incrementalPosition) scrollingTimer = setTimeout('scrollToH("' + containerElementId + '", ' + positionH + ')', 33);
	else if (loop === true) {
		// scroll value hasn't changed because we've reached the end of content
		if (delta > 0) scrollingTimer = setTimeout('scrollToH("' + containerElementId + '", 0)', 33);
		else {
			var maxScrollH = container.scrollWidth;
			scrollingTimer = setTimeout('scrollToH("' + containerElementId + '", ' + maxScrollH + ')', 33);
		}
	}
}

var lastInputLiNode;  // stores the previous LI node for an input
var lastInputFieldSetLabel;  // stores the previous fieldset label for an input

function insertElements(parentElement, insertXML, level, wData, wParamObj, noFx) {

	if (parentElement == null) return false;
	if (insertXML == null) return false;

	var insertNodeCount = insertXML.length;
	var lastConditionResult = false;
	

	
	// check widget parameters
	if (wParamObj == null) {
		wParamObj = new Array();
		wParamObj['sitePrefix'] = sitePrefix;
		wParamObj['pageURL'] = pageURL;
	}
	globalWidgetData = wData;


	for (var i=0; i<insertNodeCount; i++) {
		
		pageNodeCount += 1;
		var newNode = null;
		var newNodeOnPage = null;
		var ignoreChildren = false;
		var unrecognizedTag = false;

		var tagNameLC = String(insertXML[i].tagName).toLowerCase();
		var attrsBeforeReplacement = new Array();
		
		var insertJQ = $(insertXML[i]);

		$.each($(insertXML[i].attributes), function(index) {
			var tempAttrVal = insertXML[i].attributes[index].value;
			attrsBeforeReplacement[index] = tempAttrVal;

			tempAttrVal = replaceParams(tempAttrVal, wParamObj);

			tempAttrVal = replaceData(tempAttrVal, wData);

			if (String(tempAttrVal).substr(0,5) == 'EVAL(') {
				tempAttrVal = tempAttrVal.substring(5,tempAttrVal.length-1);
				try { 
					tempAttrVal = eval(tempAttrVal);
				}
				catch(e) { tempAttrVal = ''; }
				//alert(tempAttrVal);
			}

			insertXML[i].attributes[index].value = tempAttrVal;
		});

		if (tagNameLC == "layout") {
			// insert a div element
			newNode = document.createElement('div');
			var relVal = insertJQ.attr('Rel');
			var roundedCorners = insertJQ.attr('RoundedCorners');
			var isDialog = insertJQ.attr('Dialog');
			var layoutName = insertJQ.attr('Name');
			var jQueryUIScopeWrapperOnPage = null;

			if (roundedCorners == 'yes') roundedCorners = 'true';
			if (isDialog == 'yes') isDialog = 'true';

			if ((layoutName == null) || (layoutName == '')) layoutName = "layout_" + pageNodeCount;
			$(newNode).attr("id", layoutName);

			if (relVal != null) {
				//relVal = replaceParams(relVal, wParamObj);
				$(newNode).attr("rel", relVal);
			}

			var altVal = insertJQ.attr('Alt');

			if (altVal != null) {
				//altVal = replaceParams(altVal, wParamObj);
				$(newNode).attr("alt", altVal);
			}
			if ((roundedCorners == 'true') || (isDialog == 'true')) {
				var jQueryUIScopeWrapper = document.createElement(jQueryUIScopeId);
			
				if (jQueryUIScopeWrapper != null) {
					jQueryUIScopeWrapper.className = jQueryUIScopeClass;
					var jQueryUIScopeWrapperOnPage = parentElement.appendChild(jQueryUIScopeWrapper);
				}
			}
			if (newNode != null) {
				if (jQueryUIScopeWrapperOnPage != null) {
					newNodeOnPage = jQueryUIScopeWrapperOnPage.appendChild(newNode);
					if (newNodeOnPage != null) newNodeOnPage.className = 'ui-widget ui-widget-content ui-corner-all';
				}
				else newNodeOnPage = parentElement.appendChild(newNode);
			}
			if (isDialog == 'true') {
				$('#' + layoutName).dialog({autoOpen: false, close:function (event, ui) { try {handleDialogClose(event, ui, "layoutName")} catch(e){} } });
			}

		}
		else if (tagNameLC == "span") {
			
			newNode = document.createElement('span');
			
			var spanName = insertJQ.attr('Name');
			

			if ((spanName == null) || (spanName == '')) spanName = "span_" + pageNodeCount;
			$(newNode).attr("id", spanName);

			
			if (newNode != null) {
				newNodeOnPage = parentElement.appendChild(newNode);
			}

		}
		else if (tagNameLC == "if") {
			// conditional
			var thisCondition = insertJQ.attr("Condition");
			//alert("thisCondition=" + thisCondition);
			if (thisCondition != null) {
				
				try {
					lastConditionResult = eval(thisCondition);
				}
				catch(e) {
					alert('Invalid condition in IF statement: (' + thisCondition + ')');
					var lastConditionResult = false;
				}
				if (lastConditionResult == false) ignoreChildren = true;
			}
		}
		else if (tagNameLC == "else") {
			// conditional
			if (lastConditionResult == true) {
				ignoreChildren = true;
				lastConditionResult = true;
			}
		}
		else if (tagNameLC == "widget") {
			var thisWidgetId = insertJQ.attr("Id");
			//thisWidgetId = replaceParams(thisWidgetId, wParamObj);
			
			

			var widgetParams = insertJQ.attr("WidgetParams");
			if (widgetParams != null) {
				// parse widget params
				//alert("widgetParams=" + widgetParams);

				widgetParams = widgetParams.split('|');
				for (var p=0; p<widgetParams.length; p++) {
					var tempPair = widgetParams[p].split('=');
					wParamObj[tempPair[0]] = tempPair[1];
				}
			}

			var indentString = '';

			for (ll = 1; ll<level; ll++) {
				indentString += '   ';
			}

			/*
			debugOut(indentString + 'WIDGET: ' + thisWidgetId);
			debugOut(indentString + 'Widget Params output -----------------------------');
			for (var wKey in wParamObj) {
				debugOut(indentString + wKey + '=' + wParamObj[wKey]);
			}
			*/

			// get the widget XML
			var widgetXML = loadWidget(thisWidgetId);
			var widgetNode = $(widgetXML).find('Widget');
			var widgetContents =  $(widgetNode).contents();

			
			if (insertJQ.attr("ForEach") != null) {
				// insert a widget for each data record
				
				var widgetDataSource = insertJQ.attr("DataSource");
				var widgetForEach = insertJQ.attr("ForEach");
				//debugOut(indentString + 'widget ForEach=' + widgetForEach);
				var widgetChildrenOnly = insertJQ.attr("ChildrenOnly");
				var widgetDataOnly = insertJQ.attr("WidgetDataOnly");
				var dataNodes = null;
				var sortedBy = insertJQ.attr("SortedBy");
				var sortDirection = insertJQ.attr("SortDirection");
				var sortType = insertJQ.attr("SortType");

				if (widgetChildrenOnly == 'true') widgetChildrenOnly = true;
				if (widgetDataOnly == 'true') widgetDataOnly = true;

				dataNodes = getDataNodes(wData, widgetDataSource, widgetForEach, sortedBy, sortDirection, sortType, widgetChildrenOnly, widgetDataOnly);

				if (dataNodes != null) {
					//alert(dataNodes.length + ' nodes in data source');
					for (var k=0; k<dataNodes.length; k++) {
						// insert one widget for each dataNode
						var widgetDataXML = dataNodes[k];
						var wParamObjCopy = new Array();
						for (var wKey in wParamObj) {
							wParamObjCopy[wKey] = wParamObj[wKey];
						}
						wParamObjCopy['ForEachNumber'] = k + 1;
						wParamObjCopy['ForEachTotal'] = dataNodes.length;
						wParamObjCopy['ParentForEachNumber'] = wParamObj['ForEachNumber'];
						//alert('widgetDataXML: ' + widgetDataXML.nodeName + ' = ' + $(widgetDataXML).text());
						insertElements(parentElement, widgetContents, level + 1, widgetDataXML, wParamObjCopy, noFx);
					}
				}
			}
			else if (insertJQ.attr("For") != null) {
				// a data source id for the one widget is specified
				var widgetDataSource = insertJQ.attr("DataSource");
				var widgetFor = insertJQ.attr("For");
				//debugOut(indentString + 'widget For=' + widgetFor);
				var dataNodes;

				if (widgetDataSource != null) {
					var dataSourceXML = getDataSource(widgetDataSource);

					if (widgetFor == "*") $(dataSourceXML).find('Data').children();
					else dataNodes = $(dataSourceXML).find('widgetFor');

					if (dataNodes.length == 0) dataNodes = null;
				}

				if (dataNodes == null) {
					if (widgetFor == "*") {
						// use the parent's data context
						dataNodes = wData;
					}
				}


				if ((dataNodes == null) && (wData != null)) {
					// try the widget's data context next
					dataNodes = $(wData).find(widgetFor);
					if ((dataNodes == null) || (dataNodes.length == 0)) dataNodes = null;
					//else alert('found: ' + widgetFor + ' in wData DOWN');
				}
				if ((dataNodes == null) && (pageDataXML != null)) {
					// try the page's data context
					dataNodes = $(pageDataXML).find(widgetFor);
					if ((dataNodes == null) || (dataNodes.length == 0)) dataNodes = null;
					//else alert('found: ' + widgetFor + ' in pageDataXML DOWN');
				}

				if ((dataNodes == null) && (wData != null)) {
					// try the widget's data context next
					dataNodes = searchUpwards(wData, widgetFor, true);
					if ((dataNodes == null) || (dataNodes.length == 0)) dataNodes = null;
					//else alert('found: ' + widgetFor + ' in wData UP');
				}
				if ((dataNodes == null) && (pageDataXML != null)) {
					// try the page's data context
					dataNodes = searchUpwards(pageDataXML, widgetFor, true);
					if ((dataNodes == null) || (dataNodes.length == 0)) dataNodes = null;
					//else alert('found: ' + widgetFor + ' in pageDataXML UP');
				}


				if (dataNodes == null) {
					// last try using widgetFor as datasource
					var dataSourceXML = getDataSource(widgetFor);
					dataNodes = $(dataSourceXML).find('Data').children();
				}
				//alert(widgetFor + ': ' + dataNodes.length);
				insertElements(parentElement, widgetContents, level + 1, dataNodes, wParamObj, noFx);
			}
			else {
				insertElements(parentElement, widgetContents, level + 1, wData, wParamObj, noFx);
			}
			globalWidgetData = wData;

		}
		else if (tagNameLC == "accordion") {
			var accordionId = "accordion_" + pageNodeCount;

			newNode = document.createElement('div');
			$(newNode).attr('id', accordionId);
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

			addStartupAction('$( "#' + accordionId + '" ).accordion({fillSpace: true, navigation: true});');
		}
		else if (tagNameLC == "accordionsection") {
			var sectionTitle = insertJQ.attr("Title");
			if (sectionTitle == null) sectionTitle = "------";

			newNode = document.createElement('h3');
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

			//newNode = document.createElement('a');
			//$(newNode).attr('href', '#');
			//if (newNode != null) newNodeOnPage = newNodeOnPage.appendChild(newNode);

			newNode = document.createTextNode(sectionTitle);
			if (newNode != null) newNodeOnPage = newNodeOnPage.appendChild(newNode);

			newNode = document.createElement('div');
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
			
		}
		else if (tagNameLC == "contentholder") {
			// insert page content
			var contentAreaId = insertJQ.attr("Area");
			var pageChildren = $(pageXML).children();

			for (var j=0; j<pageChildren.length; j++) {
				var pageTagNameLC = String(pageChildren[j].tagName).toLowerCase();

				if (pageTagNameLC == "content") {
					if ($(pageChildren[j]).attr("Area") == contentAreaId) {
						// found content block in page XML
						insertElements(parentElement, $(pageChildren[j]).contents(), level + 1, wData, wParamObj, noFx);
					}
				}	
			}
		}
		else if (tagNameLC == "p") {
			// insert a paragraph element
			newNode = document.createElement('p');
			var paraName = insertJQ.attr('Name');

			if ((paraName == null) || (paraName == '')) paraName = "para_" + pageNodeCount;
			$(newNode).attr("id", paraName);

			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

		}
		else if (tagNameLC == "image") {
			// Create an image element
			newNode = document.createElement('img');
			var imgSrc = insertJQ.attr('Source');
			var imgLoadDeferred = insertJQ.attr('Deferred');
			var imgSrcMouseOver = insertJQ.attr('MouseOverSource');
			var imgSrcSelected = insertJQ.attr('SelectedSource');
			var imgValign = insertJQ.attr('Valign');
			var imgHspace = insertJQ.attr('Hspace');
			var imgVspace = insertJQ.attr('Vspace');
			var imgName = insertJQ.attr('Name');
			var imgId = 'image_' + pageNodeCount;
			if (imgName != null) imgId = imgName;

			if (imgSrcSelected != null) {
				var parentLink = insertJQ.parents('Link');
				if (parentLink.length == 1) {
					var parentLinkPage = $(parentLink).attr('Page');
					if (pageRequest.indexOf(parentLinkPage) > -1) {
						imgSrc = imgSrcSelected;
					}
				}
			}
			if (imgLoadDeferred == 'true') {
				var deferredIndex = deferredImages.length;
				deferredImages[deferredIndex] = {
					'src': imgSrc,
					'imageId': imgId
				};
				$(newNode).load(function(e) {
					loadDeferredImages();
				});
			}
			else {
				$(newNode).attr("src", imgSrc);
			}
			$(newNode).attr('border', 0);
			$(newNode).attr('id', imgId);
			if (imgValign != null) $(newNode).attr("valign", imgValign);
			if (imgHspace != null) $(newNode).attr("hspace", imgHspace);
			if (imgVspace != null) $(newNode).attr("vspace", imgVspace);
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

			if (imgSrcMouseOver != null) {
				bindImageMouseEvents(newNodeOnPage, imgId, imgSrc, imgSrcMouseOver);
			}
		}
		else if (tagNameLC == "imagefade") {
			newNode = document.createElement('div');
			var layoutName = insertJQ.attr('Name');
			var fadeInterval = insertJQ.attr('Interval');
			var fadeDuration = insertJQ.attr('Duration');
			var showThumbnails = insertJQ.attr('Thumbnails');

			fadeInterval = parseInt(fadeInterval);
			fadeDuration = parseInt(fadeDuration);
			if (isNaN(fadeInterval)) fadeInterval = 2000;
			if (isNaN(fadeDuration)) fadeDuration = 500;

			if ((layoutName == null) || (layoutName == '')) layoutName = "imagefade_" + pageNodeCount;
			
			if (newNode != null) {
				$(newNode).attr("id", layoutName);
				newNodeOnPage = parentElement.appendChild(newNode);
			}
			addStartupAction('startImageFade("' + layoutName + '", ' + fadeInterval + ', ' + fadeDuration + ', ' + showThumbnails + ')');

		}
		else if (tagNameLC == "form") {
			newNode = document.createElement('form');

			var formName = insertJQ.attr("Name");
			if ((formName== null) || (formName == '')) formName = "form_" + pageNodeCount;
			$(newNode).attr("id", formName);

			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

			pageForms[pageFormIndex] = new Object();
			pageForms[pageFormIndex].formName = formName;
			pageForms[pageFormIndex].successPage = insertJQ.attr("SuccessPage");
			pageForms[pageFormIndex].definition = insertXML[i];
			pageForms[pageFormIndex].showValidationMessage = insertJQ.attr("ShowValidationMessage");
			pageForms[pageFormIndex].showSubmitMessage = insertJQ.attr("ShowSubmitMessage");
			pageForms[pageFormIndex].sendData = insertJQ.attr("SendData");
			pageForms[pageFormIndex].sendDataNode = insertJQ.attr("SendDataNode");
			pageForms[pageFormIndex].inputElements = new Array();
			pageFormElementIndex = 0;
			currentFormIndex = pageFormIndex;

		}
		else if (tagNameLC == "fieldset") {
			newNode = document.createElement('fieldset');
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
			
			var fieldSetLabel = insertJQ.attr('Label');
			var fieldSetName = insertJQ.attr('Name');
			if ((fieldSetLabel != null) && (fieldSetLabel != '') && (newNodeOnPage != null)) {
				var legendNode = document.createElement('legend');
				legendNode.innerHTML = fieldSetLabel;
				var legendNodeOnPage = newNodeOnPage.appendChild(legendNode);
				
				lastInputFieldSetLabel = fieldSetLabel;
				
			}
			if ((fieldSetLabel == '') || (fieldSetLabel == null)) {
				if (fieldSetName != null) lastInputFieldSetLabel = fieldSetName;
			}

			if (newNodeOnPage != null) {
				var fieldSetOlNode = document.createElement('ol');
				var legendNodeOnPage = newNodeOnPage.appendChild(fieldSetOlNode);
				if (legendNodeOnPage != null) newNodeOnPage = legendNodeOnPage;
			}
		}
		else if (tagNameLC == "input") {

			var inputType = insertJQ.attr('Type');
			var inputLabel = insertJQ.attr('Label');
			var inputPlaceholder = insertJQ.attr('Placeholder');
			var inputNote = insertJQ.attr('Note');
			var inputRequired = insertJQ.attr('Required');
			var inputValue = insertJQ.attr('Value');
			var inputMultiLine = insertJQ.attr('MultiLine');
			var inputId = "input_" + pageNodeCount;
			var labelId = "label_" + pageNodeCount;
			var inputSelectAction = insertJQ.attr('SelectAction');
			var inputUnSelectAction = insertJQ.attr('UnSelectAction');
			var inputSelectTarget = insertJQ.attr('SelectActionTarget');
			var inputUnSelectTarget = insertJQ.attr('UnSelectActionTarget');
			var inputChecked = insertJQ.attr('Checked');
			var inputSameLine = insertJQ.attr('SameLine');
			var inputName = insertJQ.attr('Name');

			if (inputType == 'checkbox') {
				if (inputChecked == null) {
					if (inputValue == 'true') inputChecked = true;
					else if (inputValue == 'on') inputChecked = true;
					else if (inputValue == 'yes') inputChecked = true;
				}
				else if (inputChecked == 'true') inputChecked = true;
				else if (inputChecked == 'yes') inputChecked = true;
				else inputChecked = false;
			}

			
			if (inputType == 'hidden') {
				inputSameLine = 'true';
				if ((inputLabel != null) && (inputLabel != '')) inputId = inputLabel;
			}
			if (inputName != null) inputId = inputName;

			if (currentFormIndex == null) {
				// creating input outside form structure
				newNodeOnPage = null;
			}
			else {
				if ((inputSameLine != 'true') || (lastInputLiNode == null)) {
					newNode = document.createElement('li');
					if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
					lastInputLiNode = newNodeOnPage;
				}
				else newNodeOnPage = lastInputLiNode;
			}

			if ((newNodeOnPage != null) || (currentFormIndex == null) || (inputType == 'hidden')) {
				if ((inputType != 'hidden') && (currentFormIndex != null)) {
					var newLabelNode = document.createElement('label');
					$(newLabelNode).attr('for', inputId);
					$(newLabelNode).attr('id', labelId);
					if (newLabelNode != null) {
						if (inputSameLine != 'true') newLabelNodeOnPage = newNodeOnPage.appendChild(newLabelNode);
						else if (lastInputLiNode != null) newLabelNodeOnPage = lastInputLiNode.appendChild(newLabelNode);
						else newLabelNodeOnPage = parentElement.appendChild(newLabelNode);
					}
					var labelHTML = inputLabel;
					if(inputRequired) labelHTML = '<span class="formRequired">' + labelHTML + '</span>';
					if (newLabelNodeOnPage != null) {
						try {
							newLabelNodeOnPage.innerHTML = labelHTML;
							if (inputSameLine == 'true') {
								$(newLabelNodeOnPage).css('float', 'none');
							}
						}
						catch (e) { 
							// IE is fucking up?
							debugOut('Unidentified error setting the HTML an input label:' + labelHTML);
							//alert(labelHTML);
						}
					}
				}

				if (inputType == 'checkbox') {
					var inputNode = document.createElement('input');
					$(inputNode).attr('type', 'checkbox');
					$(inputNode).css('margin-top', '7px');
					if (inputChecked) $(inputNode).attr('checked', 'true');
				}
				else if (inputType == 'select') {
					var inputNode = document.createElement('select');
					var inputChildren = insertJQ.contents();
					var optionIndex = 0;
		
					if (inputChildren != null) {
						for (var j=0; j<inputChildren.length; j++) {
							var optionTagNameLC = String(inputChildren[j].tagName).toLowerCase();
							if (optionTagNameLC == "inputoption") {
								var dataNodes = null;
								var optionText = $(inputChildren[j]).text();
								var optionForEach = $(inputChildren[j]).attr('ForEach');
								var optionDataSource = $(inputChildren[j]).attr('DataSource');

								if (optionForEach != null) {
									var sortedBy = insertJQ.attr("SortedBy");
									var sortDirection = insertJQ.attr("SortDirection");
									var sortType = insertJQ.attr("SortType");

									dataNodes = getDataNodes(wData, optionDataSource, optionForEach, sortedBy, sortDirection, sortType);
								}

								if (dataNodes != null) {
									for (var k=0; k<dataNodes.length; k++) {
										// insert one option for each dataNode
										var optionTextR = replaceData(optionText, dataNodes[k]);
										var optionNode = document.createElement('option');
										optionNode.innerHTML = optionTextR;
										$(optionNode).attr('value', optionTextR);
										var optionNodeOnPage = inputNode.appendChild(optionNode);
										optionIndex += 1;
									}
								}
								else {
									var optionNode = document.createElement('option');
									optionNode.innerHTML = optionText;
									$(optionNode).attr('value', optionText);
									var optionNodeOnPage = inputNode.appendChild(optionNode);
									optionIndex += 1;
								}
							}
						}
					}
					inputNode.lastSelectedIndex = 0;
					ignoreChildren = true;
				}
				else if (inputType == 'state') {
					var inputNode = document.createElement('select');
					var optionNode = document.createElement('option');
					optionNode.innerHTML = '';
					$(optionNode).attr('value', '');
					inputNode.appendChild(optionNode);

					for (var stIndex=0; stIndex<StateCodes.length; stIndex++) {
						var optionNode = document.createElement('option');
						optionNode.innerHTML = StateCodes[stIndex];
						$(optionNode).attr('value', StateCodes[stIndex]);
						inputNode.appendChild(optionNode);
					}
					inputNode.lastSelectedIndex = 0;
				}
				else if (inputType == 'date') {
					var inputNode = document.createElement('input');
					addStartupAction('$("#' + inputId + '").datepicker({});');
					addStartupAction("$('#ui-datepicker-div').wrap('<" + jQueryUIScopeId + " class=" + jQueryUIScopeClass + " ></" + jQueryUIScopeId + ">');");
				}
				else if (inputType == 'dob') {
					var inputNode = document.createElement('input');
					addStartupAction('$("#' + inputId + '").datepicker({changeMonth: true, changeYear: true, yearRange: "1900:-13", minDate: new Date("January 1, 1900 00:00:00") });');
					addStartupAction("$('#ui-datepicker-div').wrap('<" + jQueryUIScopeId + " class=" + jQueryUIScopeClass + "></" + jQueryUIScopeId + ">');");
				}
				else if (inputType == 'password') {
					var inputNode = document.createElement('input');
					$(inputNode).attr('type', 'password');
				}
				else if (inputType == 'hidden') {
					var inputNode = document.createElement('input');
					$(inputNode).attr('type', 'hidden');
				}
				else if (inputType == 'submit') {
					var inputNode = document.createElement('input');
					$(inputNode).attr('type', 'button');
					var inputImage = insertJQ.attr('Image');
					if (inputImage != null) {
						$(inputNode).css('background-image', 'url(' + inputImage + ')');
					}

					var notesId = 'notes_' + pageNodeCount;
					var validationId = 'validation_' + pageNodeCount;

					var notesNode = document.createElement('span');
					$(notesNode).attr('id', notesId);
					$(notesNode).css('display', 'none');
					notesNode.innerHTML = 'Sending...';
					lastInputLiNode.appendChild(notesNode);

					var validationNode =  document.createElement('span');
					$(validationNode).attr('id', validationId);
					validationNodeOnPage = lastInputLiNode.appendChild(validationNode);

					pageForms[pageFormIndex].submitButtonName = inputId;
					pageForms[pageFormIndex].submitNotesName = notesId;
					pageForms[pageFormIndex].submitNotes = insertJQ.attr('Notes');
					pageForms[pageFormIndex].validationMsgName = validationId;
					
				}
				else if (inputMultiLine == 'true') {
					var inputNode = document.createElement('textarea');
				}
				else {
					var inputNode = document.createElement('input');
				}
				if (inputNode != null) {
					$(inputNode).attr('id', inputId);

					if (inputType != 'checkbox') $(inputNode).val(inputValue);

					if (inputPlaceholder != null) $(inputNode).attr('placeholder', inputPlaceholder);

					if (currentFormIndex == null) {
						inputNodeOnPage = parentElement.appendChild(inputNode);
					}
					else {
						if (inputSameLine != 'true') {
							inputNodeOnPage = newNodeOnPage.appendChild(inputNode);
						}
						else if ((lastInputLiNode != null) && (inputType != 'hidden')) {
							inputNodeOnPage = lastInputLiNode.appendChild(inputNode);
						}
						else {
							inputNodeOnPage = parentElement.appendChild(inputNode);
						}
						
						if (inputNote != null) {
							var noteNode = document.createElement('span');
							noteNode.innerHTML = inputNote;
							$(noteNode).attr('id', 'note_' + pageNodeCount);
							$(noteNode).attr('class', 'formNote');
							if (inputSameLine != 'true') noteNodeOnPage = newNodeOnPage.appendChild(noteNode);
							else if (lastInputLiNode != null) noteNodeOnPage = lastInputLiNode.appendChild(noteNode);
							else noteNodeOnPage = parentElement.appendChild(noteNode);
						}

						pageForms[pageFormIndex].inputElements[pageFormElementIndex] = new Object();
						pageForms[pageFormIndex].inputElements[pageFormElementIndex].inputName = inputId;
						pageForms[pageFormIndex].inputElements[pageFormElementIndex].labelName = labelId;
						pageForms[pageFormIndex].inputElements[pageFormElementIndex].definition = insertXML[i];
						pageForms[pageFormIndex].inputElements[pageFormElementIndex].fieldSetLabel = lastInputFieldSetLabel;
						pageForms[pageFormIndex].inputElements[pageFormElementIndex].oldValue = inputValue;
						pageFormElementIndex += 1;

						//if (inputType =='hidden') debugOut(inputId + ', ' + lastInputFieldSetLabel);

					}
					if (inputNodeOnPage != null) {
						if ((inputSelectAction != null) || (inputUnSelectAction != null)) {
							bindInputEvents(inputNodeOnPage, inputSelectAction, inputSelectTarget, inputUnSelectAction, inputUnSelectTarget);
						}
						applyTagAttributes(inputNodeOnPage, insertXML[i], wParamObj, tagNameLC, noFx);
						if (inputType == 'submit') bindFormSubmitEvent(inputNodeOnPage, pageFormIndex);
					}
				}	
			}	
		}
		else if (tagNameLC == "successmessage") {
			// Form success - just for form ajax
			newNode = document.createElement('div');
			var messageName = "message_" + pageNodeCount;

			$(newNode).attr("id", messageName);
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

			if (newNodeOnPage != null) {
				$(newNodeOnPage).css('display', 'none');
			}
			
			try { pageForms[pageFormIndex].successMessageName = messageName; }
			catch(e) {}
		}
		else if (tagNameLC == "list") {
			var listType = insertJQ.attr("Type");
			var listIndent = insertJQ.attr("Indent");
			var listSpacing = insertJQ.attr("Spacing");

			if (listType == "numbered") {
				newNode = document.createElement('ol');
			}
			else newNode = document.createElement('ul');

			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

			if (listIndent != null) {
				$(newNodeOnPage).css('padding-left', listIndent);
				$(newNodeOnPage).css('margin-left', '2.5em');
			}
			

			var listChildren = insertJQ.contents();
		
			if (listChildren != null) {
				for (var j=0; j<listChildren.length; j++) {
					var listTagNameLC = String(listChildren[j].tagName).toLowerCase();
					if (listTagNameLC == "listitem") {
						var listItemNode = document.createElement('li');
						var listItemNodeOnPage = newNodeOnPage.appendChild(listItemNode);

						if (listSpacing != null) {
							$(listItemNodeOnPage).css('padding-bottom', listSpacing);
							$(listItemNodeOnPage).css('margin-bottom', '0px');
						}

						var listItemChildren = $(listChildren[j]).contents();
						if (listItemChildren != null) {
							insertElements(listItemNodeOnPage, listItemChildren, level + 1, wData, wParamObj, noFx);
						}
						
					}
				}
			}
			
			ignoreChildren = true;
		}
		else if (tagNameLC == "tabs") {
			var jQueryUIScopeWrapper = document.createElement(jQueryUIScopeId);
			
			if (jQueryUIScopeWrapper != null) {
				jQueryUIScopeWrapper.className = jQueryUIScopeClass;
				var jQueryUIScopeWrapperOnPage = parentElement.appendChild(jQueryUIScopeWrapper);
			}

			newNode = document.createElement('div');
			var tabsName = "tabs_" + pageNodeCount;

			$(newNode).attr("id", tabsName);
			if (newNode != null) {
				if (jQueryUIScopeWrapperOnPage != null) newNodeOnPage = jQueryUIScopeWrapperOnPage.appendChild(newNode);
				else newNodeOnPage = parentElement.appendChild(newNode);
			}
			if (newNodeOnPage != null) {
				var tabScript = '$("#' + tabsName + '").tabs()';
				addStartupAction(tabScript);

				tabScript = '$("#' + tabsName + '").tabs("select", 0)';
				addStartupAction(tabScript);

				var tabsChildren = insertJQ.contents();
				if (tabsChildren != null) {
					var tabsULNode = document.createElement('ul');
					var tabsULNodeOnPage = newNodeOnPage.appendChild(tabsULNode);
					var tabCount = 0;

					for (var j=0; j<tabsChildren.length; j++) {
						var tabNodeNameLC = String(tabsChildren[j].tagName).toLowerCase();
						if (tabNodeNameLC == 'tab') {
							tabCount += 1;
							var tabLabel = $(tabsChildren[j]).attr("Label");
							var tabLINode = document.createElement('li');
							var tabLINodeOnPage = tabsULNodeOnPage.appendChild(tabLINode);

							var tabANode = document.createElement('a');
							$(tabANode).attr('href', '#' + tabsName + '-' + tabCount);
							var tabANodeOnPage = tabLINodeOnPage.appendChild(tabANode);

							var tabLabelNode = document.createTextNode(tabLabel);
							var tabLabelNodeOnPage = tabANodeOnPage.appendChild(tabLabelNode);
						}
					}

					tabCount = 0;
					for (var j=0; j<tabsChildren.length; j++) {
						var tabNodeNameLC = String(tabsChildren[j].tagName).toLowerCase();
						if (tabNodeNameLC == 'tab') {
							tabCount += 1;
							var tabDivNodeName = tabsName + '-' + tabCount;
							var tabDivNode = document.createElement('div');
							$(tabDivNode).attr("id", tabDivNodeName);

							var tabDivNodeOnPage = newNodeOnPage.appendChild(tabDivNode);

							if (tabDivNodeOnPage != null) {
								insertElements(tabDivNodeOnPage, $(tabsChildren[j]).contents(), level + 1, wData, wParamObj, noFx);
							}
						}
					}
				}
			}
			ignoreChildren = true;
		}
		else if (tagNameLC == "br") {
			// Create a bold element
			newNode = document.createElement('br');
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

		}
		else if (tagNameLC == "b") {
			// Create a bold element
			newNode = document.createElement('b');
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

		}
		else if (tagNameLC == "i") {
			// Create a i element
			newNode = document.createElement('i');
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

		}
		else if (tagNameLC == "text") {
			// Create a i element
			newNode = document.createElement('span');
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

		}
		else if (tagNameLC == "link") {
			// Create a link element
			newNode = document.createElement('a');
			var linkHref = insertJQ.attr("Page");
			var linkTitle = insertJQ.attr("Title");
			if (linkHref == null) linkHref = '#';

			if (linkHref.indexOf('sitePrefix') == -1) {
				if ((sitePrefix != '') || (sitePrefix !=null)) {
					if (linkHref.indexOf('/') == 0) {
						linkHref = sitePrefix + linkHref;
					}
				}
			}
			
			
			$(newNode).attr('href', linkHref);
			$(newNode).attr('title', linkTitle);
			if (insertJQ.attr('NewWindow') == 'true') $(newNode).attr('target', '_blank');
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);

		}
		else if (tagNameLC == "youtube") {
			newNode = document.createElement('iframe');

			var youTubeId = insertJQ.attr("Id");
			var youTubeWidth = insertJQ.attr("Width");
			var youTubeHeight = insertJQ.attr("Height");
			

			if (youTubeWidth != null) {
				youTubeWidth = splitUnits(youTubeWidth);
				youTubeWidth = youTubeWidth.unitsValue;
			}
			else youTubeWidth = 640;

			if (youTubeHeight != null) {
				youTubeHeight = splitUnits(youTubeHeight);
				youTubeHeight = youTubeHeight.unitsValue;
			}
			else youTubeHeight = 390;
			
			$(newNode).attr('id', "youTubeIFrame_" + pageNodeCount);
			$(newNode).attr('width', youTubeWidth);
			$(newNode).attr('height', youTubeHeight);
			$(newNode).attr('src', 'http://www.youtube.com/embed/' + youTubeId);
			$(newNode).attr('frameborder', '0');
			$(newNode).attr('allowfullscreen', 'true');

			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
		}
		else if (tagNameLC == "googlemap") {
			newNode = document.createElement('iframe');
			var mapWidth = insertJQ.attr("Width");
			var mapHeight = insertJQ.attr("Height");
			var mapSource = insertJQ.attr("Source");

			if (mapWidth != null) {
				mapWidth = splitUnits(mapWidth);
				mapWidth = mapWidth.unitsValue;
			}
			else mapWidth = 425;

			if (mapHeight != null) {
				mapHeight = splitUnits(mapHeight);
				mapHeight = mapHeight.unitsValue;
			}
			else mapHeight = 350;

			$(newNode).attr('id', 'mapIFrame_' + pageNodeCount);
			$(newNode).attr('width', mapWidth);
			$(newNode).attr('height', mapHeight);
			$(newNode).attr('src', mapSource);
			$(newNode).attr('frameborder', '0');
			$(newNode).attr('allowfullscreen', 'true');

			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
		}
		else if (tagNameLC == "googleapimap") {
			var mapIndex = pageMaps.length;
			pageMaps[mapIndex] = new Object();
			pageMaps[mapIndex].definition = insertJQ;

			newNode = document.createElement('div');
			var layoutName = insertJQ.attr('Name');
			
			if ((layoutName == null) || (layoutName == '')) layoutName = 'mapcanvas_' + pageNodeCount;
			$(newNode).attr('id', layoutName);

			pageMaps[mapIndex].canvasName = layoutName;

			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
		}
		else if (tagNameLC == "twitterfeed") {
			var twitIndex = twitterWidgets.length;
			twitterWidgets[twitIndex] = new Object();
			twitterWidgets[twitIndex].definition = insertJQ;

			newNode = document.createElement('div');
			var layoutName = insertJQ.attr('Name');
			
			if ((layoutName == null) || (layoutName == '')) layoutName = 'twitter_' + pageNodeCount;
			$(newNode).attr('id', layoutName);

			twitterWidgets[twitIndex].canvasName = layoutName;

			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
		}
		else if (tagNameLC == "panoramio") {
			newNode = document.createElement('iframe');
			var iframeWidth = insertJQ.attr("Width");
			var iframeHeight = insertJQ.attr("Height");
			var panoramioTag = insertJQ.attr("Tag");
			var panoramioColumns = insertJQ.attr("Columns");
			var panoramioRows = insertJQ.attr("Rows");
			var panoramioOrientation = insertJQ.attr("Orientation");
			var panoramioUser = insertJQ.attr("User");

			if (iframeWidth != null) {
				iframeWidth = splitUnits(iframeWidth);
				iframeWidth = iframeWidth.unitsValue;
			}
			else iframeWidth = 400;

			if (iframeHeight != null) {
				iframeHeight = splitUnits(iframeHeight);
				iframeHeight = iframeHeight.unitsValue;
			}
			else iframeHeight = 200;

			if (panoramioColumns == null) panoramioColumns = '6';
			if (panoramioRows == null) panoramioRows = '3';
			if (panoramioOrientation == null) panoramioOrientation = 'horizontal';

			var iframeSource = 'http://www.panoramio.com/wapi/template/list.html?';
			iframeSource += 'width=' + iframeWidth + '&amp;height=' + iframeHeight + '&amp;columns=' + panoramioColumns + '&amp;rows=' + panoramioRows;
			iframeSource += '&amp;orientation=' + panoramioOrientation;
			if ((panoramioTag != null) && (panoramioTag != '')) iframeSource += '&amp;tag=' + panoramioTag;
			if ((panoramioUser != null) && (panoramioUser != '')) iframeSource += '&amp;user=' + panoramioUser;
			

			$(newNode).attr('id', "panoramioIFrame_" + pageNodeCount);
			$(newNode).attr('width', iframeWidth);
			$(newNode).attr('height', iframeHeight);
			$(newNode).attr('src', iframeSource);
			$(newNode).attr('frameborder', '0');
			$(newNode).attr('scrolling', 'no');
			$(newNode).attr('allowfullscreen', 'true');

			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
			
		}
		else if (tagNameLC == "flash") {
			newNode = document.createElement('div');
			var containerName = "flashContainer_" + pageNodeCount;
			var flashWidth = insertJQ.attr("Width");
			var flashHeight = insertJQ.attr("Height");
			var flashMovie = insertJQ.attr("Source");
			var flashHTML = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="';
			flashHTML += flashWidth;
			flashHTML += '" height="';
			flashHTML += flashHeight;
			flashHTML += '" id="flash_' + pageNodeCount;
			flashHTML += '" align="middle"><param name="allowScriptAccess" value="always" />';
			flashHTML += '<param name="allowFullScreen" value="true" /><param name="movie" value="';
			flashHTML += flashMovie;
			flashHTML += '" /><param name="menu" value="false" /><param name="quality" value="best" />';
			flashHTML += '<param name="wmode" value="transparent" />';
			flashHTML += '<embed src="';
			flashHTML += flashMovie;
			flashHTML += '" menu="false" quality="best" wmode="transparent" width="';
			flashHTML += flashWidth;
			flashHTML += '" height="';
			flashHTML += flashHeight;
			flashHTML += '" name="flash_' + pageNodeCount;
			flashHTML += '" align="middle" allowScriptAccess="always" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />';
			flashHTML += '</object>';

			$(newNode).attr("id", containerName);
			if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
			$(newNodeOnPage).html(flashHTML);
		}
		else if (tagNameLC == 'meta') {
			var metaProperty = insertJQ.attr("Property");
			var metaContent = insertJQ.attr("Content");
			var newNode = document.createElement('meta');
			$(newNode).attr('property', metaProperty);
			$(newNode).attr('content', metaContent);
			var headElement = $('head');
			newNodeOnPage = headElement[0].appendChild(newNode);
		}
		else if (tagNameLC == 'html') {
			//newNode = document.createElement('span');
			var htmlContent = insertJQ.text();
			htmlContent = replaceParams(htmlContent, wParamObj);
			//if (newNode != null) {
			//	newNode.innerHTML = htmlContent;
			//	
			//	newNodeOnPage = parentElement.appendChild(newNode);
			//}
			parentElement.innerHTML += htmlContent;
			ignoreChildren = true;
		}
		else if (tagNameLC == "script") {
			
			var scriptSource = insertJQ.attr("Source");
			var executionType = insertJQ.attr("Execute");

			if (scriptSource == null) {
				var scriptContent = String(insertXML[i].firstChild.nodeValue);
				scriptContent = replaceData(scriptContent, wData);
				
				if (executionType == 'onStartup') {
					addStartupAction(scriptContent);
				}
				else if (executionType == 'afterStartup') {
					addStartupAction(scriptContent, 1500);
				}
				else {
					var thisScript = document.createElement('script');
					thisScript.setAttribute('type', 'text/javascript');
					thisScript.text = scriptContent;
					parentElement.appendChild(thisScript);
				}
				/*
				else if (executionType == 'immediate') {
					var head = document.getElementsByTagName('head').item(0);
   					var thisScript = document.createElement('script');
					thisScript.setAttribute('type', 'text/javascript');
					thisScript.text = scriptContent;
					head.appendChild(thisScript);
				}
				*/
				//alert(scriptContent);
			}
			else {
				if (executionType == 'onStartup') {
					addStartupAction('loadjscssfile("' + scriptSource + '", "js");');
				}
				else if (executionType == 'afterStartup') {
					addStartupAction("loadjscssfile('" + scriptSource + "', 'js');", 2000);
				}
				else {
					loadjscssfile(scriptSource, 'js', parentElement);
				}
			}
			//else loadjscssfile(scriptSource, 'js', parentElement);
			ignoreChildren = true;
			newNodeOnPage = null;
		}
		else if (insertXML[i].nodeType == 3) {
			// Text node
			var textNodeContent = String(insertXML[i].nodeValue);

			// do any parameter replacements
			textNodeContent = String(replaceParams(textNodeContent, wParamObj));

			// do any data replacements
			var replacementsDone = false;

			if (textNodeContent.indexOf('%') > -1) {
				var replacementObject = replaceData(textNodeContent, wData, 'object');
				
			
				if (replacementObject != null) {
					var pointerS = 0;
					var pointerD = 0;
					for (var k=0; k<replacementObject.assembly.length; k++) {
						if (replacementObject.assembly[k] == 0) {
							newNode = document.createTextNode(replacementObject.statics[pointerS]);
							if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
							pointerS += 1;
						}
						else {
							insertElements(parentElement, replacementObject.dynamics[pointerD], level + 1, wData, wParamObj, noFx);
							pointerD += 1;
						}
					}
					newNode = null;           //--------------------- this could be a PROBLEM?
					replacementsDone = true;
				}
			}

			if (!replacementsDone) {
				try {
					newNode = document.createTextNode(textNodeContent);
					if (newNode != null) newNodeOnPage = parentElement.appendChild(newNode);
				}
				catch(e) {}
			}
		}
		else {
			unrecognizedTag = true;
		}




		if (newNodeOnPage != null) {
			applyTagAttributes(newNodeOnPage, insertXML[i], wParamObj, tagNameLC, noFx);
		}

		if (!ignoreChildren) {
			var insertNodeChildren = insertJQ.contents();

			if (insertNodeChildren != null) {
				var insertNodeChildCount = insertNodeChildren.length;	
			}
			else {
				var insertNodeChildCount = 0;
			}

			//if (unrecognizedTag) {
			//	alert("Unrecognized tag: " + tagNameLC);
			//	alert(insertXML[i].tagName + " has " + insertNodeChildCount + " children.");
			//}

			if (insertNodeChildCount > 0) {
				//alert(insertXML[i].tagName + " has " + insertNodeChildCount + " children.");

				// Note: I'm pretty sure the following was a mistake.
				// Follow-up note: had something to do with data replacements in text nodes.
				// See below for replaced code
				//if (newNode == null) {
				//	alert("This happened!");
				//	insertElements(parentElement, insertXML[i], level + 1, wData, wParamObj);
				//}
				if (newNode == null) {
					insertElements(parentElement, insertNodeChildren, level + 1, wData, wParamObj, noFx);
				}
				else if (newNodeOnPage != null) insertElements(newNodeOnPage, insertNodeChildren, level + 1, wData, wParamObj, noFx);
			}
		}
		// AFTER CHILDERN HAVE BEEN INSERTED:
		if (tagNameLC == 'fieldset') {
			lastInputFieldSetLabel = '';
		}
		else if ((tagNameLC == 'form') && (newNodeOnPage != null)) {

			var showSubmit = String(insertJQ.attr('ShowSubmitButton')).toLowerCase();

			if ((showSubmit != 'false') && (showSubmit !='no')) {
				// make submit button
				var fieldSetNode = document.createElement('fieldset');
				if (fieldSetNode != null) fieldSetNodeOnPage = newNodeOnPage.appendChild(fieldSetNode);
				
				if (fieldSetNodeOnPage != null) {
					//$(fieldSetNodeOnPage).css('height', '40px');
					var buttonId = 'submit_' + pageNodeCount;
					var notesId = 'notes_' + pageNodeCount;
					var validationId = 'validation_' + pageNodeCount;
					var buttonOlNode =  document.createElement('ol');
					buttonOlNodeOnPage = fieldSetNodeOnPage.appendChild(buttonOlNode);

					var buttonLiNode =  document.createElement('li');
					buttonLiNodeOnPage = buttonOlNodeOnPage.appendChild(buttonLiNode);

					var newLabelNode = document.createElement('label');
					$(newLabelNode).attr('for', buttonId);
					newLabelNodeOnPage = buttonLiNodeOnPage.appendChild(newLabelNode);
					newLabelNodeOnPage.innerHTML = '';

					var buttonNode = document.createElement('input');
					buttonNode.value = 'Submit';
					buttonNode.type = 'button';
					$(buttonNode).attr('id', buttonId);
					buttonNodeOnPage = buttonLiNodeOnPage.appendChild(buttonNode);

					bindFormSubmitEvent(buttonNodeOnPage, pageFormIndex);

					var notesNode = document.createElement('span');
					$(notesNode).attr('id', notesId);
					$(notesNode).attr('class', 'formSubmitNotes');
					$(notesNode).css('display', 'none');
					notesNode.innerHTML = 'Sending...';
					buttonLiNodeOnPage.appendChild(notesNode);				

					var validationNode =  document.createElement('div');
					var formValidationMessageClass = insertJQ.attr('ValidationMessageClass');
					if (formValidationMessageClass == null) formValidationMessageClass = 'formValidationMessage';
					$(validationNode).attr('id', validationId);
					$(validationNode).attr('class', formValidationMessageClass);
					validationNodeOnPage = fieldSetNodeOnPage.appendChild(validationNode);

					pageForms[pageFormIndex].submitButtonName = buttonId;
					pageForms[pageFormIndex].submitNotesName = notesId;
					pageForms[pageFormIndex].validationMsgName = validationId;
					
				}
			}
			else {
				var useNotesName = insertJQ.attr("FormNotesName");
				var useValidationMsgName = insertJQ.attr("FormValidationMsgName");
				var useSubmitButtonName = insertJQ.attr("SubmitButtonName");

				if (useNotesName != null) pageForms[pageFormIndex].submitNotesName = useNotesName;
				if (useValidationMsgName != null) pageForms[pageFormIndex].validationMsgName = useValidationMsgName;
				if (useSubmitButtonName != null) pageForms[pageFormIndex].submitButtonName = useSubmitButtonName;
			}
			
			pageFormIndex += 1;
			currentFormIndex = null;
			
		}

		// put back original attribute values
		$.each($(insertXML[i].attributes), function(index) {
			insertXML[i].attributes[index].value = attrsBeforeReplacement[index];
		});
	}
}


function splitUnits(dimString) {

	var returnObj = new Object();

	returnObj.units = "";
	returnObj.unitsName = "";
	returnObj.unitsValue = "";

	if (dimString == "auto") {
		returnObj.unitsValue = "auto";
	}
	else if (dimString.length > 2) {

		var lastTwo = dimString.substr(dimString.length-2, 2);
		var theRest = dimString.substr(0, dimString.length-2);

		if (cssUnits[lastTwo] != null) {
			returnObj.units = lastTwo;
			returnObj.unitsName = cssUnits[lastTwo];
			returnObj.unitsValue = theRest;
		}

	}
	else if (dimString.length > 1) {

		var lastOne = dimString.substr(dimString.length-1, 1);
		var theRest = dimString.substr(0, dimString.length-1);

		if (cssUnits[lastTwo] != null) {
			returnObj.units = lastTwo;
			returnObj.unitsName = cssUnits[lastTwo];
			returnObj.unitsValue = theRest;
		}

	}

	var asNum = parseInt(returnObj.unitsValue);

	if (!isNaN(asNum)) returnObj.unitsValue = asNum;

	return returnObj;

}

function applyTagEvents(domNode, tagXML, wParamObj, tagName) {
	var mouseOverEvent = $(tagXML).attr("OnMouseOver");
	var mouseOutEvent = $(tagXML).attr("OnMouseOut");
	var htmlTagName = String(domNode.tagName).toLowerCase();

	// using two different techniques here... not sure shich is better.

	if (mouseOverEvent != null) {
		//alert(mouseOverEvent);
		$(domNode).bind('mouseover', function(event) {
			eval(mouseOverEvent);
		});
	}
	if (mouseOutEvent != null) {
		//alert(mouseOverEvent);
		$(domNode).bind('mouseout', function(event) {
			eval(mouseOutEvent);
		});
	}

	if ($(tagXML).attr('OnClick') != null) {
		eval("domNode.onclick = function() { " + $(tagXML).attr('OnClick') + "};");
	}
	
	if ((htmlTagName == 'input') || (htmlTagName == 'select') || (htmlTagName == 'textarea') || (htmlTagName == 'password')) {
		if ($(tagXML).attr('OnKeyUp') != null) {
			eval("domNode.onkeyup = function() { " + $(tagXML).attr('OnKeyUp') + "};");
		}
		if ($(tagXML).attr('OnChange') != null) {
			eval("domNode.onchange = function() { " + $(tagXML).attr('OnChange') + "};");
		}
	}
}

function applyTagAttributes(domNode, tagXML, wParamObj, tagName, noFx) {
	// applies attributes and styles
	// applicable to multiple node types
	// tagName = the name of the originating tag in the XML pseudo-code
	
	//tagName = String(tagName).toLowerCase();

	if (domNode == null) return false;

	// nodeType = the name of the tag in the DOM (input, div, li, etc.)
	var nodeType = String($(domNode).attr('tagName')).toLowerCase();


	if ($(tagXML).attr('Align') != null) {
		if ($(tagXML).attr('Align') == "center") {
			$(domNode).css('margin-left','auto');
			$(domNode).css('margin-right','auto');
		}
		else {
			$(domNode).css('align',$(tagXML).attr('Align'));
		}
	}
	if ($(tagXML).attr('Valign') != null) {
		try {
			$(domNode).css('vertical-align', $(tagXML).attr('Valign'));
		}
		catch(e) {
			alert('Error setting Valign to ' + $(tagXML).attr('Valign'));
		}
	}
	if ((tagName != 'input') || ((tagName == 'input') && (nodeType == 'input'))) {
		if ($(tagXML).attr('Width') != null) {
			try {
				$(domNode).css('width', $(tagXML).attr('Width'));
			}
			catch(e) {
				alert('Error setting width to ' + $(tagXML).attr('Width'));
			}
		}
	}
	if ($(tagXML).attr('Height') != null) {
		try {
			$(domNode).css('height', $(tagXML).attr('Height'));
		}
		catch(e) {
			alert('Error setting height to ' + $(tagXML).attr('Height'));
		}
	}
	if ($(tagXML).attr('MinimumWidth') != null) {
		try {
			$(domNode).css('min-width', $(tagXML).attr('MinimumWidth'));
		}
		catch(e) {
			alert('Error setting min-width to ' + $(tagXML).attr('MinimumWidth'));
		}
	}
	if ($(tagXML).attr('MaximumWidth') != null) {
		try {
			$(domNode).css('max-width', $(tagXML).attr('MaximumWidth'));
		}
		catch(e) {
			alert('Error setting max-width to ' + $(tagXML).attr('MaximumWidth'));
		}
	}
	if ($(tagXML).attr('MinimumHeight') != null) {
		try {
			$(domNode).css('min-height', $(tagXML).attr('MinimumHeight'));
		}
		catch(e) {
			alert('Error setting min-height to ' + $(tagXML).attr('MinimumHeight'));
		}
	}
	if ($(tagXML).attr('MaximumHeight') != null) {
		try {
			$(domNode).css('max-height', $(tagXML).attr('MaximumHeight'));
		}
		catch(e) {
			alert('Error setting max-height to ' + $(tagXML).attr('MaximumHeight'));
		}
	}
	if ($(tagXML).attr('Top') != null) {
		$(domNode).css('position', 'absolute');
		try {
			$(domNode).css('top', $(tagXML).attr('Top'));
		}
		catch(e) {
			alert('Error setting top to ' + $(tagXML).attr('Top'));
		}
	}
	if ($(tagXML).attr('Left') != null) {
		$(domNode).css('position', 'absolute');
		try {
			$(domNode).css('left', $(tagXML).attr('Left'));
		}
		catch(e) {
			alert('Error setting left to ' + $(tagXML).attr('Left'));
		}
	}
	if ($(tagXML).attr('Right') != null) {
		$(domNode).css('position', 'absolute');
		try {
			$(domNode).css('right', $(tagXML).attr('Right'));
		}
		catch(e) {
			alert('Error setting right to ' + $(tagXML).attr('Right'));
		}
	}
	
	if ($(tagXML).attr('Opacity') != null) {
		try {
			$(domNode).fadeTo(33, $(tagXML).attr('Opacity'));
		}
		catch(e) {
			alert('Error setting Opacity to ' + $(tagXML).attr('Opacity'));
		}
	}
	if ($(tagXML).attr('ZIndex') != null) {
		try {
			$(domNode).css('z-index', $(tagXML).attr('ZIndex'));
		}
		catch(e) {
			alert('Error setting z-index to ' + $(tagXML).attr('ZIndex'));
		}
	}
	if ($(tagXML).attr('FixedPosition') != null) {
		var positionFixed = String($(tagXML).attr('FixedPosition')).split(',');
		if (positionFixed.length == 2) {
			try {
				$(domNode).css('position', 'absolute');
				addDynamicPositioning(domNode, positionFixed[0], positionFixed[1]);
			}
			catch(e) {
				alert('Error setting Fixed Position');
			}
		}
	}
	if ($(tagXML).attr('Position') != null) {
		try {
			$(domNode).css('position', $(tagXML).attr('Position'));
		}
		catch(e) {
			alert('Error setting Position');
		}
	}
	if ($(tagXML).attr('VerticalAlign') != null) {
		try {
			if ($(tagXML).attr('VerticalAlign') == 'middle') $(domNode).css('display','inline-block');
			$(domNode).css('vertical-align', $(tagXML).attr('VerticalAlign'));
		}
		catch(e) {
			alert('Error setting VerticalAlign');
		}
	}
	if ($(tagXML).attr('TextAlign') != null) {
		try {
			$(domNode).css('text-align', $(tagXML).attr('TextAlign'));
		}
		catch(e) {
			alert('Error setting TextAlign');
		}
	}
	if ($(tagXML).attr('Margin') != null) {
		try {
			$(domNode).css('margin', $(tagXML).attr('Margin'));
		}
		catch(e) {
			alert('Error setting Margin');
		}
	}
	if ($(tagXML).attr('MarginTop') != null) {
		try {
			$(domNode).css('margin-top', $(tagXML).attr('MarginTop'));
		}
		catch(e) {
			alert('Error setting MarginTop');
		}
	}
	if ($(tagXML).attr('MarginRight') != null) {
		try {
			$(domNode).css('margin-right', $(tagXML).attr('MarginRight'));
		}
		catch(e) {
			alert('Error setting MarginRight');
		}
	}
	if ($(tagXML).attr('MarginBottom') != null) {
		try {
			$(domNode).css('margin-bottom', $(tagXML).attr('MarginBottom'));
		}
		catch(e) {
			alert('Error setting MarginBottom');
		}
	}
	if ($(tagXML).attr('MarginLeft') != null) {
		try {
			$(domNode).css('margin-left', $(tagXML).attr('MarginLeft'));
		}
		catch(e) {
			alert('Error setting MarginLeft');
		}
	}
	if ($(tagXML).attr('Padding') != null) {
		$(domNode).css('padding', $(tagXML).attr('Padding'));
	}
	if ($(tagXML).attr('Overflow') != null) {
		$(domNode).css('overflow', $(tagXML).attr('Overflow'));
	}
	if ($(tagXML).attr('Color') != null) {
		$(domNode).css('color', $(tagXML).attr('Color'));
	}
	if ($(tagXML).attr('BackgroundColor') != null) {
		$(domNode).css('background-color', $(tagXML).attr('BackgroundColor'));
	}
	if ($(tagXML).attr('Background') != null) {
		$(domNode).css('background-image', "url('" + $(tagXML).attr('Background') + "')");
	}
	if ($(tagXML).attr('BackgroundRepeat') != null) {
		$(domNode).css('background-repeat', $(tagXML).attr('BackgroundRepeat'));
	}
	if ($(tagXML).attr('BackgroundPosition') != null) {
		$(domNode).css('background-position', $(tagXML).attr('BackgroundPosition'));
	}
	if ($(tagXML).attr('BorderStyle') != null) {
		$(domNode).css('border-style', $(tagXML).attr('BorderStyle'));
	}
	if ($(tagXML).attr('BorderThickness') != null) {
		var borderInfo = splitUnits($(tagXML).attr('BorderThickness'));
		//alert('borderInfo.unitsValue=' + borderInfo.unitsValue);
		if (borderInfo.unitsValue == 0) {
			$(domNode).css('border-style', 'none');
		}
		else if (borderInfo.unitsValue > 0) {
			if ($(tagXML).attr('BorderStyle') == null) $(domNode).css('border-style', 'solid');
			$(domNode).css('border-width', $(tagXML).attr('BorderThickness'));
		}
	}
	if ($(tagXML).attr('BorderColor') != null) {
		$(domNode).css('border-color', $(tagXML).attr('BorderColor'));
	}
	if ($(tagXML).attr('TextColor') != null) {
		$(domNode).css('color', $(tagXML).attr('TextColor'));
	}
	if ($(tagXML).attr('TextSize') != null) {
		$(domNode).css('font-size', $(tagXML).attr('TextSize'));
	}
	if ($(tagXML).attr('FontSize') != null) {
		$(domNode).css('font-size', $(tagXML).attr('FontSize'));
	}
	if ($(tagXML).attr('LineHeight') != null) {
		$(domNode).css('line-height', $(tagXML).attr('LineHeight'));
	}
	if ($(tagXML).attr('LetterSpacing') != null) {
		$(domNode).css('letter-spacing', $(tagXML).attr('LetterSpacing'));
	}
	if ($(tagXML).attr('WordSpacing') != null) {
		$(domNode).css('word-spacing', $(tagXML).attr('WordSpacing'));
	}
	if ($(tagXML).attr('Cursor') != null) {
		$(domNode).css('cursor', $(tagXML).attr('Cursor'));
	}
	if ($(tagXML).attr('Float') != null) {
		$(domNode).css('float', $(tagXML).attr('Float'));
	}
	if ($(tagXML).attr('Clear') != null) {
		$(domNode).css('clear', $(tagXML).attr('Clear'));
	}
	if ($(tagXML).attr('Class') != null) {
		$(domNode).attr('class', $(tagXML).attr('Class'));
	}
	if ($(tagXML).attr('Scroll') != null) {
		if ($(tagXML).attr('Scroll') == 'vertical') $(domNode).css('overflow-y', 'auto');
		else if ($(tagXML).attr('Scroll') == 'horizontal') $(domNode).css('overflow-x', 'auto');
		else if ($(tagXML).attr('Scroll') == 'true') $(domNode).css('overflow', 'auto');
	}
	if ($(tagXML).attr('Rel') != null) {
		// For some reason this does not work all the time.
		// Adding the attribute to the element before insertion
		// into the DOM seems to have fixed the issue
		domNode.rel = $(tagXML).attr('Rel');
		$(domNode).attr('rel', $(tagXML).attr('Rel'));
		//alert("domNode.rel=" + domNode.rel);
	}
	if ($(tagXML).attr('Alt') != null) {
		domNode.alt = $(tagXML).attr('Alt');
	}
	if ($(tagXML).attr('Display') != null) {
		$(domNode).css('display', $(tagXML).attr('Display'));
	}
	if ($(tagXML).attr('Visibility') != null) {
		$(domNode).css('visibility', $(tagXML).attr('Visibility'));
	}
	if ($(tagXML).attr('Name') != null) {
		if (tagName != 'input') $(domNode).attr('id', $(tagXML).attr('Name'));
	}
	

	if ($(tagXML).attr('Alert') != null) {
		alert($(tagXML).attr('Alert'));
	}
	if (($(tagXML).attr('Transition') != null) && (noFx != true)) {
		$(domNode).css('display', 'none');

		var easingFunction = $(tagXML).attr('Easing');
		var duration = $(tagXML).attr('Duration');

		if (duration == null) duration = '0';

		if ($(tagXML).attr('QueueTransition') == "true") {
			var queueTransitionIndex = $(tagXML).attr('QueueTransitionIndex');
			if ((queueTransitionIndex != null) && (queueTransitionIndex != '')) {
				queueTransitionIndex = parseInt(queueTransitionIndex);
				setTimeout('doTrans("' + domNode.id + '", "' + $(tagXML).attr('Transition') + '", "' + easingFunction + '", ' + duration + ')', (100 * queueTransitionIndex) );
			}
			else {
				transitionQueueCount += 1;
				setTimeout('doTrans("' + domNode.id + '", "' + $(tagXML).attr('Transition') + '", "' + easingFunction + '", ' + duration + ')', (100 * transitionQueueCount) );
			}
		}
		else addStartupAction('doTrans("' + domNode.id + '", "' + $(tagXML).attr('Transition') + '", "' + easingFunction + '", ' + duration + ')');
	}
	
	if ($(tagXML).attr('DropShadow') == 'true') {
		addStartupAction('addDropShadow("' + domNode.id + '")');
	}

	applyTagEvents(domNode, tagXML, wParamObj, tagName);
	
}
function doTrans(nodeId, transType, easingFunction, duration) {
	var theNode = $('#' + nodeId);
	theNode.css('display', 'none');
	theNode.css('visibility', 'visible');

	if ((easingFunction == '') || (easingFunction == 'undefined')) easingFunction = null; 
	
	if (transType == 'slide') {
		if ((duration == 0) || (duration == null)) duration = 300;
		theNode.slideDown(duration, easingFunction);
	}
	else if (transType == 'fade') {
		if ((duration == 0) || (duration == null)) duration = 1000;
		theNode.fadeIn(duration, easingFunction);
	}
	else {
		// most effect types need no options passed by default
		var options = {};
		// some effects have required parameters
		if (transType === "scale") {
			options = { percent: 100 };
		}
		else if (transType === "size") {
			options = { to: { width: auto, height: auto } };
		}
		options.easing = easingFunction;

		if ((duration == 0) || (duration == null)) duration = 400;

		//alert(transType);
		theNode.show(transType, options, duration);
	}
}
function addDropShadow(nodeId) {
	transitionQueueCount += 9;
	var dsCommand = '$("#' + nodeId + '").dropShadow({left:-3, top:0, blur:2, opacity:0.25})';
	setTimeout(dsCommand, 100 * transitionQueueCount);
}

function getDataNodes(wData, dataSource, forEach, sortedBy, sortDirection, sortType, childrenOnly, widgetDataOnly) {
	var dataNodes = null;

	//alert('getDataNodes: ' + forEach);

	if (dataSource != null) {
		// explicit data source. load it
		//alert('loading explicit datasource: ' + dataSource);

		if ((String(dataSource)[0] == '/') && (String(dataSource).indexOf('.') > -1)) {
			// absolute path
			var dataSourceXML = getDataSource(dataSource, false, true, null, getVars);
		}
		else var dataSourceXML = getDataSource(dataSource, null, null, null, getVars);

		if ((forEach == "*") || (forEach == null)) dataNodes = $(dataSourceXML).find('Data').children();
		else dataNodes = $(dataSourceXML).find(forEach);

		//alert('found ' + dataNodes.length + ' node(s) matching ' + forEach);

		if (dataNodes.length == 0) dataNodes = null;
	}
	if (dataNodes == null) { 
		if (forEach == "*") {
			// use the existing widget data data context
			dataNodes = wData;
		}
	}


	if (childrenOnly == true) {
		if ((dataNodes == null) && (wData != null)) {
			// try the widget's data context DOWN
			dataNodes = $(wData).children(forEach);
			if ((dataNodes != null) && (dataNodes.length == 0)) dataNodes = null;
			//alert('Found ' + forEach + ' in widget children.');
		}
		if ((dataNodes == null) && (pageDataXML != null) && (widgetDataOnly != true)) {
			// try the page's data context DOWN
			dataNodes = $(pageDataXML).children(forEach);
			if ((dataNodes != null) && (dataNodes.length == 0)) dataNodes = null;
			//alert('Found ' + forEach + ' in page children.');
			
		}
	}
	else {
		if ((dataNodes == null) && (wData != null)) {
			// try the widget's data context DOWN
			dataNodes = $(wData).find(forEach);
			if ((dataNodes != null) && (dataNodes.length == 0)) dataNodes = null;
			//if (dataNodes) alert('Found ' + dataNodes.length + ' ' + forEach + ' Widget DOWN search.');
		}
		
		if ((dataNodes == null) && (pageDataXML != null)) {
			// try the page's data context DOWN
			dataNodes = $(pageDataXML).find(forEach);
			if ((dataNodes != null) && (dataNodes.length == 0)) dataNodes = null;
			//if (dataNodes) alert('Found ' + dataNodes.length + ' ' + forEach + ' Page DOWN search.');
		}
		
		if ((dataNodes == null) && (wData != null)) {
			// try the widget's data context UP
			dataNodes = searchUpwards(wData, forEach, true);
			if ((dataNodes != null) && (dataNodes.length == 0)) dataNodes = null;
			//if (dataNodes) alert('Found ' + dataNodes.length + ' ' + forEach + ' Widget UP search.');
		}
		
		if ((dataNodes == null) && (pageDataXML != null)) {
			// try the page's data context UP
			dataNodes = searchUpwards(pageDataXML, forEach, true);
			if ((dataNodes != null) && (dataNodes.length == 0)) dataNodes = null;
			//if (dataNodes) alert('Found ' + dataNodes.length + ' ' + forEach + ' Page UP search.');
		}
		
		if (dataNodes == null) {
			// try loading the datasource and using the primary elements					
			if (dataSource != null) {
				//alert('Loading data source: ' + dataSource);
				var dataSourceXML = getDataSource(dataSource);
				dataNodes = $(dataSourceXML).find('Data').children();
				if ((dataNodes != null) && (dataNodes.length == 0)) dataNodes = null;
			}
		}
		if (dataNodes == null) {
			// last try using the ForEach attribute as the data source name and use the primary elements					
			//alert('Loading data source for widget: ' + widgetForEach);
			var dataSourceXML = getDataSource(forEach);
			dataNodes = $(dataSourceXML).find('Data').children();
			if ((dataNodes != null) && (dataNodes.length == 0)) dataNodes = null;
		}
	}

	if (dataNodes != null) {			
		if (sortedBy != null) {
			// sort the array of data nodes
			sortNodes(dataNodes, sortedBy, sortType, sortDirection);
		}
	}

	return dataNodes;
}

function loadWidget(wId) {
	//alert("loading widget '" + wId + "'");
	var widgetData;
	$.ajax({
		// load the widget XML
		type: "GET",
		url: sitePrefix + "/xml/v" + useVersion + "/widgets/" + wId + ".xml",
		dataType: "xml",
		async: false,
		success: function(data) {
			//alert("Widget " + wId + " successfully loaded.");
			widgetData = data;
		},
		error: function(req, textStatus, errorThrown) {
			alert("error loading " + wId + " widget xml: textStatus=" + textStatus);
			widgetData = false;
		}
	});
	return widgetData;
}

var refData = new Array();
function includeReferences(dataId) {
	
	// Replaces "Refrence" tags with data from other data sources.
	// Modified 2/26/11 - Creates reusable associative arrays to use as look-up tables.
	//                    One array is created for each DataSource/Find/Match combo.

	var data = loadedData[dataId];
	//loadedData[dataId].referencesProcessed = true;
	referencesProcessed[dataId] = true;

	var refTags = $(data).find('Reference');
	if (refTags != null) {
		debugOut(refTags.length + ' reference(s) found in ' + dataId);

		for (var i=0; i<refTags.length; i++) {
			var refTag = refTags[i];
			var $refTag = $(refTag);

			var refDataSourceName = $refTag.attr('DataSource');
			var refFind = $refTag.attr('Find');
			var refMatch = $refTag.attr('Match');
			var refMatchValue = $refTag.text();
			var pMatches;

			if (refMatchValue != '') {

				var refDataSource = getDataSource(refDataSourceName, true);

				if (refData[refDataSourceName] == null) {
					refData[refDataSourceName] = new Array();
				}
				if (refData[refDataSourceName][refFind] == null) {
					refData[refDataSourceName][refFind] = new Object();

					pMatches = $(refDataSource).find(refFind);
	
					refData[refDataSourceName][refFind].possibleMatches = pMatches;
					refData[refDataSourceName][refFind].match = new Array();
				
				}
				if (refData[refDataSourceName][refFind].match[refMatch] == null) {
					refData[refDataSourceName][refFind].match[refMatch] = new Array();
					
					for (var j=0; j<pMatches.length; j++) {
						// build the look-up table
						refData[refDataSourceName][refFind].match[refMatch][$(pMatches[j]).find(refMatch + ':first').text()] = j;
					}
				}
			
				pMatches = refData[refDataSourceName][refFind].possibleMatches;
			
				var foundIndex = refData[refDataSourceName][refFind].match[refMatch][refMatchValue];
	
				if (foundIndex != null) {
					//debugOut('Found match for ' + refMatchValue + ', index=' + foundIndex);

					var matchClone = pMatches[foundIndex].cloneNode(true);
	
					$refTag.replaceWith(matchClone);
					refTag = matchClone;

					replacementMade = true;
				}
			}
		}
	}
}

function getDataSource(dId, ignoreReferences, absolutePath, forceReload, getVars) {
	//debugOut("getDataSource: '" + dId + "'. ignoreReferences=" + ignoreReferences);
	if (dId == 'user') {
		if ((loadedData[dId] == null) || (forceReload)) {
			loadedData[dId] = initUserData();
		}
		return loadedData[dId];
	}

	if(dId == null) {
		debugOut('Warning: null data id passed to getDataSource()');
		return;
	}

	if (ignoreReferences == null) ignoreReferences = false;
	

	if ((loadedData[dId] == null) || (forceReload)) {
		// XML hasn't been loaded yet.
		// Fetch it and add to the loadedData array.
		//alert("loading data '" + dId + "'. ignoreReferences=" + ignoreReferences);
		var dataXML;
		var dataSrc;

		if (absolutePath) {
			var lastFour = dId.substr(dId.length-4);
			if ((lastFour == '.xml') || (lastFour == '.php')) dataSrc = dId;
			else dataSrc = dId + ".xml";
		}
		else {
			if (dId.indexOf('/') == 0) dataSrc = sitePrefix + "/xml/v" + useVersion + dId + ".xml";
			else                       dataSrc = sitePrefix + "/xml/v" + useVersion + "/data/" + dId + ".xml";
		}

		if (forceReload) dataSrc += '?cc=' + Math.random() + '&' + getVars;
		else dataSrc += '?' + getVars;

		debugOut('Getting data from ' + dataSrc + '. absolutePath=' + absolutePath);

		$.ajax({
			// load the data XML
			type: "GET",
			url: dataSrc,
			dataType: "xml",
			async: false,
			success: function(data) {
				//alert("Data successfully loaded.");
				loadedData[dId] = data;
				if (ignoreReferences != true) {
					includeReferences(dId);
				}
				else {
					//loadedData[dId].referencesProcessed = false;
					referencesProcessed[dId] = false;
				}
			},
			error: function(req, textStatus, errorThrown) {
				debugOut("error loading data xml: textStatus=" + textStatus + ", id=" + dId);
				loadedData[dId] = false;
			}
		});
	}
	//else if (loadedData[dId].referencesProcessed == false) {
	else if (referencesProcessed[dId] == false) {
		// data has been loaded, but references have not been replaced.
		if (ignoreReferences != true) {
			includeReferences(dId);
		}
	}

	return loadedData[dId];
}

function loadjscssfile(filename, filetype, parentElement) {
	if (filetype=="js") {
		var fileref = document.createElement('script');
		fileref.setAttribute("type","text/javascript");
		fileref.setAttribute("src", filename);
		debugOut('Loading JS file: ' + filename);
	}
	else if (filetype=="css") {
		var fileref = document.createElement("link");
		fileref.setAttribute("rel", "stylesheet");
		fileref.setAttribute("type", "text/css");
		fileref.setAttribute("href", filename);
	}
	if (typeof fileref != "undefined") {
		if (parentElement == null) document.getElementsByTagName("head")[0].appendChild(fileref);
		else parentElement.appendChild(fileref);
	}
}
var loadedScripts = new Array();
function loadScriptOnce(filename, parentElement) {
	var alreadyLoaded = false;
	for (var i=0; i<loadedScripts.length; i++) {
		if (loadedScripts[i] == filename) alreadyLoaded = true;
		break;
	}
	if (!alreadyLoaded) {
		debugOut('Loading script: ' + filename);
		var fileref = document.createElement('script');
		fileref.setAttribute("type","text/javascript");
		fileref.setAttribute("src", filename);

		if (parentElement == null) document.getElementsByTagName("head")[0].appendChild(fileref);
		else parentElement.appendChild(fileref);
	}
}

function replaceParam(inString, paramters) {
	// this function takes a single param name for inString
	
	if (paramters[inString] == null) {
		alert(inString + " not found.");
		return inString;
	}
	else {
		//alert(inString + "=" + paramters[inString]);
		return paramters[inString];
	}
}


function replaceParams(inString, parameters) {
	// replace all occurrences of ~ParamName~ with parameter values from widget param object

	// make sure inString is a string
	inString = String(inString);


	// first rule out the easy cases
	
	// string is too short to need replacements
	if (inString.length < 3) return inString;

	var tempLength = inString.split("~").length;

	// there arn't enough ~ to require replacements
	if (tempLength < 3) return inString;

	if ((inString.charAt(0) == "~")  && (inString.charAt(inString.length - 1) == "~")) {
		// begins AND ends with ~
		
		if (tempLength == 3) {
			// there are only 2 ~
			// do simple replacement
			inString = inString.substr(1, inString.length - 2);
			return replaceParam(inString, parameters);
		}
	}

	
	var statics = new Array();
	var dynamics = new Array();
	var assembly = new Array();
	var staticPart = true;
	var tempS = "";
	var thisChar;

	// build array of static and dynamic chunks
	for (var stringPos = 0; stringPos<inString.length; stringPos++) {
		thisChar = inString.charAt(stringPos);
		if ((thisChar == "~") || (stringPos == inString.length-1)) {
			if (thisChar != "~") tempS += thisChar;
			if (staticPart) {
				staticPart = false;
				if (tempS != "") {
					// dump temp string into statics array
					statics[statics.length] = tempS;
					tempS = "";
					assembly.push(0);
				}
			}
			else {
				staticPart = true;
				if (tempS != "") {
					// dump temp string into dynamics array
					dynamics[dynamics.length] = tempS;
					tempS = "";
					assembly.push(1);
				}
			}
		}
		else tempS += thisChar;
	}

	// attempt replacement of dynamic strings with param values
	for (var dIndex=0; dIndex<dynamics.length; dIndex++) {
		//alert("attempting to replace " + dynamics[dIndex]);
		dynamics[dIndex] = replaceParam(dynamics[dIndex], parameters)
	}

	

	// rebuild conjugate string
	var returnString = "";
	var pointerS = 0;
	var pointerD = 0;

	for (var k=0; k<assembly.length; k++) {
		if (assembly[k] == 0) {
			returnString += String(statics[pointerS]);
			pointerS += 1;
		}
		else {
			returnString += String(dynamics[pointerD]);
			pointerD += 1;
		}
	}
	//alert("replaceParams retuns " + returnString);
	return returnString;	
}

function searchUpwards(searchXML, searchFor, multiple, recursionLevel) {
	// searches up th tree for matching elements.
	// if multiple = true a set can be returned
	// otherwise only return one node.

	if (recursionLevel == null) recursionLevel = 0;
	if (multiple == null) multiple = false;

	var foundNode = null;
	var isFound = false;
	var thisParent = $(searchXML).parent();

	//alert(recursionLevel + ': thisParent:' + thisParent);

	if (thisParent == null) return null;
	if (thisParent.length != 1) return null;
	
	if (multiple != true) foundNode = $(thisParent).find(searchFor + ':first');
	else foundNode = $(thisParent).find(searchFor);

	if (foundNode != null) {
		if (foundNode.length >= 1) isFound = true;
	}

	if (isFound) return foundNode;
	else return searchUpwards(thisParent, searchFor, multiple, recursionLevel + 1);
}
function countChars(inString, findChar) {
	var s = "oooooo";
	var re = '/' + findChar + '/g';
	re = eval(re);
	for(var c = 0; re.exec(inString); ++c );
	return c;
}

function replaceData(inString, searchXML, returnStringOrObject) {
	// replace all occurrences of %FieldName% with data from XML

	var delimCount = countChars(inString, '%');
	if (delimCount < 2) {
		if (returnStringOrObject == 'object') {
			var returnObject = new Object();
			returnObject.assembly = new Array();
			returnObject.assembly[0] = 0;
			returnObject.statics = new Array();
			returnObject.statics[0] = inString;
			returnObject.dynamics = new Array();
			return returnObject;
		}
		else return inString;
	}

	var statics = new Array();
	var dynamics = new Array();
	var dynamicsXML = new Array();
	var assembly = new Array();
	var staticPart = true;
	var tempS = "";
	var thisChar;
	
	// build array of static and dynamic chunks
	for (var stringPos = 0; stringPos<inString.length; stringPos++) {
		thisChar = inString.charAt(stringPos);
		if ((thisChar == "%") || (stringPos == inString.length-1)) {
			if (thisChar != "%") tempS += thisChar;
			if (staticPart) {
				staticPart = false;
				if (tempS != "") {
					// dump temp string into statics array
					statics[statics.length] = tempS;
					tempS = "";
					assembly.push(0);
				}
			}
			else {
				staticPart = true;
				if (tempS != "") {
					
					if (tempS.indexOf(' ') > -1) {
						// data identifiers can't have spaces
						if (stringPos < inString.length-1) statics[statics.length] = '%' + tempS + '%';
						else statics[statics.length] = '%' + tempS;
						assembly.push(0);
					}
					else {
						// dump temp string into dynamics array
						dynamics[dynamics.length] = tempS;
						assembly.push(1);
					}
					tempS = "";
				}
			}
		}
		else tempS += thisChar;
	}

	// attempt replacement of dynamic strings with data
	for (var dIndex=0; dIndex<dynamics.length; dIndex++) {
		var foundNode = null;
		var tempFound = '';
		var tempFoundXML;
		var replacmentFound = false;

		//alert('looking for: ' + dynamics[dIndex]);

		if (searchXML != null) {
			if (searchXML.nodeName == dynamics[dIndex]) {
				foundNode = searchXML;
				replacmentFound = true;
				//if (replacmentFound) debugOut('foundNode searchXML is: ' + dynamics[dIndex] + '=' + $(foundNode).text());
			}
		}

		if ((!replacmentFound) && (searchXML != null)) {
			foundNode = $(searchXML).find(dynamics[dIndex] + ':first');
			if (foundNode != null) { if (foundNode.length == 1) replacmentFound = true; }
			//if (replacmentFound) debugOut('foundNode in searchXML DOWN: '+ dynamics[dIndex] + '=' + $(foundNode).text());
		}
		if ((!replacmentFound) && (searchXML != null)) {
			// replacement still not found - search up the searchXML tree:
			foundNode = searchUpwards(searchXML, dynamics[dIndex]);
			if (foundNode != null) { if (foundNode.length == 1) replacmentFound = true; }
			//if (replacmentFound) debugOut('foundNode in searchXML UP: '+ dynamics[dIndex] + '=' + $(foundNode).text());
		}
		
		if ((!replacmentFound) && (pageDataXML != null)) {
			// automatically look for data in the pageDataXML context
			foundNode = $(pageDataXML).find(dynamics[dIndex] + ':first');
			if (foundNode != null) { 
				if (foundNode.length == 1) replacmentFound = true; 
			}
			
			//if (replacmentFound) debugOut('foundNode in pageDataXML DOWN: ' + dynamics[dIndex] + '=' + $(foundNode).text());
		}
		


		
		

		if ((!replacmentFound) && (pageDataXML != null)) {
			// replacement still not found - search up the pageDataXML tree:
			foundNode = searchUpwards(pageDataXML, dynamics[dIndex]);
			if (foundNode != null) { if (foundNode.length == 1) replacmentFound = true; }
			//if (replacmentFound) debugOut('foundNode in pageDataXML UP: ' + dynamics[dIndex] + '=' + $(foundNode).text());
		}
		
		
		if (foundNode != null) {
			tempFound = $(foundNode).text();
			tempFoundXML = $(foundNode).contents();
		}
		else {
			tempFound = '';
			tempFoundXML = null;
		}
		if ((tempFound == '') && (searchXML != null)) {
			// look for matching attribute in searchXML
			tempFound = $(searchXML).attr(dynamics[dIndex]);
			if (tempFound == null) tempFound = '';
			else if (tempFound != '') tempFoundXML = $('<Span>' + tempFound + '</Span>');
		}
		if ((tempFound == '') && (pageDataXML != null)) {
			// look for matching attribute in pageDataXML
			tempFound = $(pageDataXML).attr(dynamics[dIndex]);
			if (tempFound == null) tempFound = '';
			else if (tempFound != '') tempFoundXML = $('<Span>' + tempFound + '</Span>');
		}
	
		dynamics[dIndex] = tempFound;
		dynamicsXML[dIndex] = tempFoundXML;
		
	}

	var pointerS = 0;
	var pointerD = 0;

	if (returnStringOrObject == 'object') {
		// send back objects
		var returnObject = new Object();
		returnObject.assembly = assembly;
		returnObject.statics = statics;
		returnObject.dynamics = dynamicsXML;
		return returnObject;
	}
	else {
		// rebuild conjugate string
		var returnString = "";
		for (var k=0; k<assembly.length; k++) {
			if (assembly[k] == 0) {
				returnString += String(statics[pointerS]);
				pointerS += 1;
			}
			else {
				returnString += String(dynamics[pointerD]);
				pointerD += 1;
			}
		}
		//alert('returnString=' + returnString);
		return returnString;
	
	}
}
var dynamicallyPositionedElements = new Array();

function dynamicallyPositionAll() {
	var bodyRef = document.getElementsByTagName("body").item(0);
	var bodyScrollLeft = $(bodyRef).scrollLeft();
	var bodyScrollTop = $(bodyRef).scrollTop();
	var winWidth = getWindowWidth();
	var winHeight = getWindowHeight();

	for (var i=0; i<dynamicallyPositionedElements.length; i++) {
		 dynamicallyPosition(i, bodyRef, bodyScrollLeft, bodyScrollTop, winWidth, winHeight)
	}
}

function dynamicallyPosition(elementIndex, bodyRef, bodyScrollLeft, bodyScrollTop, winWidth, winHeight) {
	var theElement = dynamicallyPositionedElements[elementIndex].element;
	var pX = dynamicallyPositionedElements[elementIndex].x;
	var pY = dynamicallyPositionedElements[elementIndex].y;

	if (bodyRef == null) var bodyRef = document.getElementsByTagName("body").item(0);
	if (bodyScrollLeft == null) var bodyScrollLeft = $(bodyRef).scrollLeft();
	if (bodyScrollTop == null) var bodyScrollTop = $(bodyRef).scrollTop();
	if (winWidth == null) var winWidth = getWindowWidth();
	if (winHeight == null) var winHeight = getWindowHeight();

	if (pX >= 0) pX = pX + bodyScrollLeft;
	else pX = winWidth + pX + bodyScrollLeft;

	if (pY >= 0) pY = pY + bodyScrollTop;
	else pY = winHeight + pY + bodyScrollTop;

	$(theElement).css('position', 'absolute');
	$(theElement).css('left', pX + 'px');
	$(theElement).css('top', pY + 'px');
}
function addDynamicPositioning(domNode, pX, pY) {
	var nextIndex = dynamicallyPositionedElements.length;
	dynamicallyPositionedElements[nextIndex] = new Object();
	
	dynamicallyPositionedElements[nextIndex].element = domNode;
	dynamicallyPositionedElements[nextIndex].x = parseInt(pX);
	dynamicallyPositionedElements[nextIndex].y = parseInt(pY);

	dynamicallyPosition(nextIndex)
}

var startupActions = new Array();
var autoSlideIntervalIds = new Array();

function addStartupAction(actionCode, delayMS) {
	var newIndex = startupActions.length;
	if (delayMS == null) startupActions[newIndex] = actionCode;
	else startupActions[newIndex] = 'setTimeout("' + actionCode + '", ' + delayMS + ')';
}

function doStartupActions() {
	for (var i=0; i<startupActions.length; i++) {
		debugOut('Executing startup action: ' + startupActions[i]);
		eval(startupActions[i]);
	}
	startupActions = new Array();
}

function clearAutoSlides() {
	for (var i=0; i<autoSlideIntervalIds.length; i++) {
		clearInterval(autoSlideIntervalIds[i]);
	}
}
function startAutoSlides() {
	//alert('startAutoSlides()');
	autoSlideIntervalIds = new Array();

	$('.auto-slider').each( function() {
		var related_group = $(this).attr('rel');
		autoSlideIntervalIds[autoSlideIntervalIds.length] = window.setInterval("simpleSlideAction('.right-button', '" + related_group + "');", 5000);
	});
}
var imageFadeInfo = new Array();
function startImageFade(containerId, fadeInterval, fadeDuration, showThumbnails) {
	var fadeIndex = imageFadeInfo.length;
	var childImages = $('#' + containerId).children('img');

	imageFadeInfo[fadeIndex] = new Object;
	imageFadeInfo[fadeIndex].containerId = containerId;
	imageFadeInfo[fadeIndex].childImageCount = childImages.length;
	imageFadeInfo[fadeIndex].currentIndex = 0;
	imageFadeInfo[fadeIndex].intervalId = setInterval('doNextImgeFade(' + fadeIndex + ')', fadeInterval);
	imageFadeInfo[fadeIndex].fadeDuration = fadeDuration;
	imageFadeInfo[fadeIndex].fadeInterval = fadeInterval;
	
	//$(childImages).css('z-index', fadeIndex + 10);
	$(childImages).position({
			my: 'top left',
			at: 'top left',
			of: $('#' + containerId),
			offset: '0 0'
			});
	$(childImages).css('display', 'none');
	$('#' + containerId).children('img:first').css('display', 'inline');

	if (showThumbnails) {
		var containerWidth = $('#' + containerId).css('width');
		var containerHeight = $('#' + containerId).css('height');

		var thumbsHTML = '<div id="imgFadeThumbCont' + fadeIndex + '" onmouseover="showImageFadeThumbs(' + fadeIndex + ')" onmouseout="hideImageFadeThumbs(' + fadeIndex + ')" style="margin:0px; padding:0px; width:' + containerWidth + '; height:' + containerHeight + ';">';

		for (var i=0; i<childImages.length; i++) {
			thumbsHTML += '<img onclick="doNextImgeFade(' + fadeIndex + ', ' + i + ')" src="' + $(childImages[i]).attr('src') + '" style="width:60px; margin:0px 0px 10px 10px; padding:0px; display:none; vertical-align:top; border-style:solid; border-width:1px; border-color:#666666; cursor:pointer;"/><br/>';
		}
		thumbsHTML += '</div>';
		

		$('#' + containerId).append(thumbsHTML);

		$('#' + containerId).children('div').position({
			my: 'top left',
			at: 'top left',
			of: $('#' + containerId),
			offset: '0 10'
		});
	}
}
function showImageFadeThumbs(fadeIndex) {
	clearTimeout(imageFadeInfo[fadeIndex].thumbTimer);
	imageFadeInfo[fadeIndex].thumbTimer = setTimeout('doShowImageFadeThumbs(' + fadeIndex + ')', 100);
}
function doShowImageFadeThumbs(fadeIndex) {
	debugOut('showImageFadeThumbs: ' + fadeIndex);
	clearInterval(imageFadeInfo[fadeIndex].intervalId);
	$('#imgFadeThumbCont' + fadeIndex).children().fadeIn(100);
}
function hideImageFadeThumbs(fadeIndex) {
	clearTimeout(imageFadeInfo[fadeIndex].thumbTimer);
	imageFadeInfo[fadeIndex].thumbTimer = setTimeout('doHideImageFadeThumbs(' + fadeIndex + ')', 100);
}
function doHideImageFadeThumbs(fadeIndex) {
	debugOut('hideImageFadeThumbs: ' + fadeIndex);
	clearInterval(imageFadeInfo[fadeIndex].intervalId);
	var fadeInterval = imageFadeInfo[fadeIndex].fadeInterval;
	imageFadeInfo[fadeIndex].intervalId = setInterval('doNextImgeFade(' + fadeIndex + ')', fadeInterval);
	$('#imgFadeThumbCont' + fadeIndex).children().fadeOut(100);
}
function doNextImgeFade(fadeIndex, nextIndex) {
	var containerId = imageFadeInfo[fadeIndex].containerId;
	var currentIndex = imageFadeInfo[fadeIndex].currentIndex;
	
	if (nextIndex == null) var nextIndex = currentIndex + 1;
	if (nextIndex >= imageFadeInfo[fadeIndex].childImageCount) nextIndex = 0;

	if (nextIndex == currentIndex) return;
	
	var containerId = imageFadeInfo[fadeIndex].containerId;

	var curElement = $('#' + containerId).children('img:eq(' + currentIndex + ')');
	var nextElement = $('#' + containerId).children('img:eq(' + nextIndex + ')');

	$(curElement).fadeOut(imageFadeInfo[fadeIndex].fadeDuration);
	$(nextElement).fadeIn(imageFadeInfo[fadeIndex].fadeDuration, function() {
		$(this).position({
			my: 'top left',
			at: 'top left',
			of: $('#' + containerId),
			offset: '0 0'
		});
	});

	imageFadeInfo[fadeIndex].currentIndex = nextIndex;

	var childImages = $('#' + containerId).children('img');
	$(childImages).position({
			my: 'top left',
			at: 'top left',
			of: $('#' + containerId),
			offset: '0 0'
			});

	debugOut('Image fade to ' + (nextIndex + 1) + ' of ' + imageFadeInfo[fadeIndex].childImageCount);
}

function startDialogs() {
	var dialogs = $('div[role="dialog"]');
	var wrapper = '<' + jQueryUIScopeId + '></' + jQueryUIScopeId + '>';
	try {
		dialogs.wrap(wrapper);
	}
	catch (e) {
		//alert('Error wrapping dialogs:' + wrapper);
	}
	
	dialogs.addClass(jQueryUIScopeClass);
	dialogs = $('div[role="dialog"]');
	$(dialogs).css('background-color', '#EEEEEE');
}
function drawMaps() {
	if (!google.maps) {
		debugOut('Google Maps API not initialized yet... retrying in 1 second.');
		setTimeout('drawMaps()', 1000);
		return;
	}
	else {
		debugOut('google.maps.MapTypeId=' + google.maps.MapTypeId); 
	}

	for (var i=0; i<pageMaps.length; i++) {
		var mapDef = pageMaps[i].definition;
		var mapCanvasName = pageMaps[i].canvasName;
			
		var mapLatitude = mapDef.attr("Latitude");
		var mapLongitude = mapDef.attr("Longitude");
		var mapZoom = mapDef.attr("Zoom");
		var mapType = mapDef.attr("Type");
		
		var mapOptions = new Object();

		if (mapLatitude != null) {
			mapLatitude = parseFloat(mapLatitude);
			mapLongitude = parseFloat(mapLongitude);
			debugOut('LatLng: ' + mapLatitude + ', ' + mapLongitude);
			var mapLatlng = new google.maps.LatLng(mapLatitude, mapLongitude);
			mapOptions.center = mapLatlng;
		}
		if (mapZoom != null) {
			mapOptions.zoom = parseInt(mapZoom);
		}
		if (mapType != null) {
			mapOptions.mapTypeId = eval('google.maps.MapTypeId.' + mapType);
		}
		pageMaps[i].map = new google.maps.Map(document.getElementById(mapCanvasName), mapOptions);
		pageMaps[i].layers = new Array();

		var mapLayersDef = $(mapDef).find('Layer');
		debugOut(mapLayersDef.length + ' map layers found.');

		for (var j=0; j<mapLayersDef.length; j++) {
			pageMaps[i].layers[j] = new Object;
			pageMaps[i].layers[j].layerType = $(mapLayersDef[j]).attr('Type');
			pageMaps[i].layers[j].layerSrc = $(mapLayersDef[j]).attr('Source');
			pageMaps[i].layers[j].preserveViewport = $(mapLayersDef[j]).attr('PreserveViewport');
			pageMaps[i].layers[j].suppressInfoWindows = $(mapLayersDef[j]).attr('SuppressInfoWindows ');

			if (pageMaps[i].layers[j].preserveViewport == 'true') pageMaps[i].layers[j].preserveViewport = true;
			else pageMaps[i].layers[j].preserveViewport = false;

			if (pageMaps[i].layers[j].suppressInfoWindows == 'true') pageMaps[i].layers[j].suppressInfoWindows = true;
			else pageMaps[i].layers[j].suppressInfoWindows = false;

			debugOut('Adding map layer ' + j);

			if (pageMaps[i].layers[j].layerType == 'KML') {
				var kmlOptions = new Object;
				kmlOptions.preserveViewport = pageMaps[i].layers[j].preserveViewport;
				kmlOptions.suppressInfoWindows = pageMaps[i].layers[j].suppressInfoWindows;
				
				pageMaps[i].layers[j].layer = new google.maps.KmlLayer(pageMaps[i].layers[j].layerSrc, kmlOptions);
				pageMaps[i].layers[j].layer.setMap(pageMaps[i].map);
			}
		}
	}

}
function startMaps() {
	if (pageMaps.length == 0) return;
	loadjscssfile('http://maps.google.com/maps/api/js?sensor=false&callback=drawMaps', 'js');
	//loadjscssfile('http://maps.gstatic.com/intl/en_us/mapfiles/api-3/4/5/main.js', 'js');
	//setTimeout('drawMaps()', 1000);
}
TWTR = false;
function checkTWTR() {
	if (TWTR) {
		debugOut('Initializing ' + twitterWidgets.length + ' twitter widget(s)...');

		for (var i=0; i<twitterWidgets.length; i++) {
			var canvas = twitterWidgets[i].canvasName;
			var canvasElement = $('#' + canvas)[0];
			var twitDef = twitterWidgets[i].definition;
			var twitType = $(twitDef).attr('Type');
			var twitUser = $(twitDef).attr('User');
			var twitList = $(twitDef).attr('List');
			var twitSubject = $(twitDef).attr('Subject');
			var twitTitle = $(twitDef).attr('Title');
			var twitHeight = $(twitDef).attr('Height');
			var twitTextColor = $(twitDef).attr('TextColor');
			var twitBackgroundColor = $(twitDef).attr('BackgroundColor');
			var twitListTextColor = $(twitDef).attr('ListTextColor');
			var twitListBackgroundColor = $(twitDef).attr('ListBackgroundColor');
			var twitLinksColor = $(twitDef).attr('LinksColor');
			var twitScroll = $(twitDef).attr('Scroll');
			var twitTweetNumber = $(twitDef).attr('TweetNumber');
			var twitScript = '';

			if (twitHeight != null) twitHeight = splitUnits(twitHeight).unitsValue;
			else twitHeight = '"auto"';

			if (twitSubject == null) twitSubject = '';
			if (twitTitle == null) twitTitle = '';

			var twitScriptElement = document.createElement('script');
			$(twitScriptElement).attr('type', 'text/javascript');

			//var tDiv = document.createElement('div');
			//$(tDiv).attr('class', 'twtr-widget');
			//$(tDiv).attr('id', 'twtr-widget- ' + (i+1));
			//canvasElement.appendChild(tDiv);
					
			twitScript += 'twitterWidOpt' + i + ' = { '
  			twitScript += 'version: 2, ';
  			twitScript += 'type: "list", ';
			twitScript += 'id: "' + canvas + '", ';
  			if (twitTweetNumber != null) twitScript += 'rpp: ' + twitTweetNumber + ', ';
			else twitScript += 'rpp: 12, ';
  			twitScript += 'interval: 4000, ';
  			twitScript += 'title: "' + twitTitle + '", ';
  			twitScript += 'subject: "' + twitSubject + '", ';
  			twitScript += 'width: "auto", ';
  			twitScript += 'height: ' + twitHeight + ', ';
  			twitScript += 'theme: { ';
    			twitScript += 'shell: { ';
			twitScript += 'dummy: 0, ';
      			if (twitBackgroundColor != null) twitScript += 'background: "' + twitBackgroundColor + '", ';
      			if (twitTextColor != null) twitScript += 'color: "' + twitTextColor + '", ';
			twitScript += 'dummy2: 0 ';
    			twitScript += '}, ';
    			twitScript += 'tweets: { ';
			twitScript += 'dummy: 0, ';
      			if (twitListBackgroundColor != null) twitScript += 'background: "' + twitListBackgroundColor + '", ';
      			if (twitListTextColor != null) twitScript += 'color: "' + twitListTextColor + '", ';
      			if (twitLinksColor != null) twitScript += 'links: "#' + twitLinksColor + '", ';
			twitScript += 'dummy2: 0 ';
    			twitScript += '} ';
  			twitScript += '}, ';
  			twitScript += 'features: { ';
			twitScript += 'fullscreen: false, ';
    			if (twitScroll != null) twitScript += 'scrollbar: ' + twitScroll + ', ';
    			twitScript += 'loop: true, ';
    			twitScript += 'live: true, ';
    			twitScript += 'hashtags: true, ';
    			twitScript += 'timestamp: true, ';
    			twitScript += 'avatars: true, ';
    			twitScript += 'behavior: "all" ';
  			twitScript += '}';
			twitScript += '}; ';

			twitScript += 'twitterWid' + i + '  = new TWTR.Widget(twitterWidOpt' + i + ').render(); ';

			if (twitType == 'list') {
				twitScript += 'twitterWid' + i + '.setList("' + twitUser + '", "' + twitList + '"); ';
			}
			else {
				twitScript += 'twitterWid' + i + '.setUser("' + twitUser + '"); ';
			}
			twitScript += 'twitterWid' + i + '.start(); ';
			
			//debugOut('Twitter widget script: ' + twitScript);

			twitScriptElement.text = twitScript;
			canvasElement.appendChild(twitScriptElement);
		}
	}
	else {
		debugOut('TWTR not ready. Retrying in 1 second...');
		setTimeout('checkTWTR()', 1000);
	}
}
function startTwitterWidgets() {
	if (twitterWidgets.length > 0) {
		//loadScriptOnce("/js/twitter/widget.js");
		loadScriptOnce("http://widgets.twimg.com/j/2/widget.js");
		checkTWTR();
	}
}
function centerDialogs() {

	$.each($('div[role="dialog"]'), function(index) {
		var thisDialog = $('div[role="dialog"]:eq(' + index + ')');
		var dialogWidth = 300;
		var dialogHeight = 400;
		var actualDialogWidth = $(thisDialog).css('width');
		//var actualDialogHeight = $(thisDialog).css('height');

		if ((actualDialogWidth != null) && (actualDialogWidth != '')) {
			actualDialogWidth = splitUnits(actualDialogWidth);
			dialogWidth = actualDialogWidth.unitsValue;
		}
		//if ((actualDialogHeight != null) && (actualDialogHeight != '') && (actualDialogHeight != 'auto')) {
		//	actualDialogHeight = splitUnits(actualDialogHeight);
		//	dialogHeight = actualDialogHeight.unitsValue;
		//}

		//var bodyRef = document.getElementsByTagName("body").item(0);
		//var bodyScrollTop = $(bodyRef).scrollTop();

		//alert(dialogHeight + ',' + bodyScrollTop);

		var dialogX = Math.round(getWindowWidth()/2 - (dialogWidth/2));
		//var dialogY = Math.round(getWindowHeight()/2 - (dialogHeight/2) + bodyScrollTop);
		//alert(dialogX + ',' + dialogY);

		thisDialog.css('left', dialogX + 'px');
		//thisDialog.css('top', dialogY + 'px');
	});
}
var deferredImageNext;
function loadDeferredImages() {
	if (deferredImages.length > 0) {
		var thisImage = deferredImages.shift();
		debugOut('Loading deferred image: ' + thisImage.src);
		$('#' + thisImage.imageId).attr('src', thisImage.src);
	}
}
function checkHashSlides() {
	var hash = window.location.hash;
	if (hash != '') {
		hash = String(hash);
		if (hash.indexOf('#') == 0) {
			hash = hash.substr(1);
		}
		hash = hash.split(',');
		if (hash.length == 2) {
			simpleSlideAction('.jump-to-slide', hash[0], hash[1]);
		}
	}
}
function slideCallback() {
	checkHashSlides();
}
function locationHashChanged() {
	var newHash = window.location.hash;
	newHash = String(newHash);
	if (newHash.indexOf('#') == 0) {
		newHash = newHash.substr(1);
	}

	if (newHash != lastHash) {
		debugOut('hash changed to: ' + newHash);
		checkHashSlides();
		lastHash = newHash;
	}
}

function messageBox(messageHTML) {
	var messageBoxElement = $('#messageBoxElement');
	if (messageBoxElement.length == 0) {
		
		var jQueryUIScopeWrapperOnPage = null;
		var roundedCorners = 'true';
		var parentElement = $('body')[0];

		var newNode = document.createElement('div');
		$(newNode).attr('id', 'messageBoxElement');
		$(newNode).css('position', 'fixed');
		//$(newNode).css('height', '100%');
		$(newNode).css('bottom', '30px');
		$(newNode).css('left', '20px');
		$(newNode).css('padding', '10px 16px 12px 15px');
		


		if ((roundedCorners == 'true') || (isDialog == 'true')) {
			var jQueryUIScopeWrapper = document.createElement(jQueryUIScopeId);
			
			if (jQueryUIScopeWrapper != null) {
				jQueryUIScopeWrapper.className = jQueryUIScopeClass;
				var jQueryUIScopeWrapperOnPage = parentElement.appendChild(jQueryUIScopeWrapper);
			}
		}
		if (newNode != null) {
			if (jQueryUIScopeWrapperOnPage != null) {
				newNodeOnPage = jQueryUIScopeWrapperOnPage.appendChild(newNode);
				if (newNodeOnPage != null) newNodeOnPage.className = 'ui-widget ui-widget-content ui-corner-all';
			}
			else newNodeOnPage = parentElement.appendChild(newNode);
		}
		messageBoxElement = $('#messageBoxElement');	
	}
	messageBoxElement.css('background-color', '#FF0000');
	messageBoxElement.css('display', 'none');
	messageBoxElement.html(messageHTML);
	messageBoxElement.fadeIn(500);
}

function onAfterRender() {
	simpleSlide({'set_speed': 300,
	'status_width': 20,
	'status_color_outside': '#aaa',
	'status_color_inside': '#333333',
	'fullscreen': 'false',
	'swipe': 'true',
	'callback': slideCallback });

	startAutoSlides();
	loadDeferredImages();
	startDialogs();
	startMaps();
	startTwitterWidgets();

	setTimeout(doStartupActions, 34);

	window.onscroll = function (e) {
  		dynamicallyPositionAll();
	}
	window.onresize = function (e) {
  		dynamicallyPositionAll();
	}
	try { window.onhashchange = locationHashChanged; } catch (e) {}

	if (useVersion != defaultPublishedVersion) {
		var messageBoxHTML = '';
		if (pageRequest.substr(sitePrefix.length + 1, 5) == 'admin') {
			messageBoxHTML += 'You are editing version: <B>' + useVersion + '</B><Br/>';
		}
		else {
			messageBoxHTML += 'You are viewing version: <B>' + useVersion + '</B><Br/>';
		}
		messageBoxHTML += 'The published version is: <B>' + defaultPublishedVersion + '</B>';
		messageBox(messageBoxHTML);
	}
}

function getWindowWidth() {
	var x = 0;
	if (self.innerHeight) {
		x = self.innerWidth;
	}
	else if (document.documentElement && document.documentElement.clientHeight) {
                x = document.documentElement.clientWidth;
	}
	else if (document.body) {
		x = document.body.clientWidth;
	}
	return x;
}
function getWindowHeight() {
	var x = 0;
	if (self.innerHeight) {
		x = self.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientHeight) {
                x = document.documentElement.clientHeight;
	}
	else if (document.body) {
		x = document.body.clientHeight;
	}
	return x;
}
function checkBrowser() {
	var browserOk = true;
	var agent = navigator.userAgent;
	var browserCheck = getCookieCrumbs('browser-check');

	if (browserCheck != 'false') {
	
		agent = String(agent);
		
		if (agent.indexOf('MSIE 7') > -1) {
			browserOk = false;
		}
		else if (agent.indexOf('MSIE 6') > -1) {
			browserOk = false;
		}
	}

	return browserOk;
}
function checkBrowserIE() {
	var browserIE = false;
	var agent = navigator.userAgent;
	
	agent = String(agent);
		
	if (agent.indexOf('MSIE') > -1) {
		browserIE = true;
	}
	return browserIE;
}
function isTouchDevice() {
	try {
		document.createEvent("TouchEvent");
		return true;
	}
	catch (e) {
		return false;
	}
}
function doRedirect(newURL, linkText) {
	var bodyRef = document.getElementsByTagName("body").item(0);
	var tempXML = newXML('<Layout Padding="10px">Redirecting to <Link Page="' + newURL + '">' + linkText + '.<Br/>Please click here</Link> if you are not automatically redirected.</Layout>');
	insertElements(bodyRef, $(tempXML), 0);

	window.location.href = newURL;
}
$(document).ready(function() {

	var browserOk = checkBrowser();

	if (browserOk) {

		loadjscssfile(sitePrefix + "/xml/v" + useVersion + "/styles/styles.css", "css")


		$.ajax({
			// load the site XML
			type: "GET",
			url: sitePrefix + "/xml/v" + useVersion + "/site.xml",
			dataType: "xml",
			success: function(data) {
				var siteNode = $(data).find('Site');
				sitePageNamePrefix = $(siteNode).attr('PageNamePrefix');
				siteKeywords = $(siteNode).attr('Keywords');
				siteDescription = $(siteNode).attr('Description');
				siteAnalyticsId = $(siteNode).attr('AnalyticsId');
				siteDomainName = $(siteNode).attr('DomainName');
				siteTaxableState = $(siteNode).attr('TaxableState');
				siteTaxRate = parseFloat($(siteNode).attr('TaxRate'));

				checkClearUserIdCookie();
	
				var headElement = document.getElementsByTagName("head")[0];         
				var metaElement = document.createElement('meta');
				metaElement.name = "keywords";
				metaElement.content = siteKeywords;
				headElement.appendChild(metaElement);
			},
			error: function(req, textStatus, errorThrown) {
				alert("error loading site.xml: textStatus=" + textStatus);
			}
		});

		$.ajax({
			// load the pages XML
			type: "GET",
			url: sitePrefix + "/xml/v" + useVersion + "/pages.xml",
			dataType: "xml",
			success: function(data) {
				// look for the requested page in the pages XML
			
				var pageNodes = $(data).find('Page');
				var pageFound = false;
				var pageSetFound = false;
				var closestMatch = null;
				var closestMatchLength = 0;

				for (var i=0; i<pageNodes.length; i++) {
					var findPage = sitePrefix + $(pageNodes[i]).attr('Location');
					if (findPage == pageRequest) {
						pageFound = true;
						pageXML = pageNodes[i];
						break;
					}
					else {
						var findPageLength = findPage.length;
						var closeMatchName = pageRequest.substr(0, findPageLength);
						if ((closeMatchName == findPage) && (findPageLength > closestMatchLength)) {
							closestMatchLength = findPageLength;
							closestMatch = pageNodes[i];
						}
					}
				}
			
				if (!pageFound) {
					// look for data driven page set
					var pageSetNodes = $(data).find('PageSet');
					
					for (var i=0; i<pageSetNodes.length; i++) {
						var skipTest = false;
						var pageSetDataSource = $(pageSetNodes[i]).attr('DataSource');
						var pageSetForEach = $(pageSetNodes[i]).attr('ForEach');
						var pageSetLocation = sitePrefix + $(pageSetNodes[i]).attr('Location');
						var pageSetLocationPrefixEnd = pageSetLocation.indexOf('%');
						if (pageSetLocationPrefixEnd != -1) {
							var pageSetLocationPrefix = pageSetLocation.substr(0, pageSetLocationPrefixEnd);
							var pageRequestPrefix = pageRequest.substr(0, pageSetLocationPrefixEnd);
							//alert(pageSetLocationPrefix + "," + pageRequestPrefix);
							if (pageSetLocationPrefix != (pageRequestPrefix)) skipTest = true;
						}
					
						if (!skipTest) {
							//alert('pageSetDataSource=' + pageSetDataSource);
							var dataSourceXML = getDataSource(pageSetDataSource, true);
					

							if (pageSetForEach != null) var dataNodes = $(dataSourceXML).find(pageSetForEach);
							else var dataNodes = $(dataSourceXML).find('Data').children();
					
						
							for (j=0; j<dataNodes.length; j++) {
								var conjugateLocation = replaceData(pageSetLocation, dataNodes[j]);
								conjugateLocation =  String(conjugateLocation).toLowerCase();
								//alert("conjugateLocation=" + conjugateLocation);

								if (pageRequest == conjugateLocation) {
									// found page
									pageFound = true;
									pageSetFound = true;

									// load data references
									includeReferences(pageSetDataSource);

									pageXML = pageSetNodes[i];
									pageDataXML = dataNodes[j];
								
									
									break;
								}
							}
						}
						if (pageFound) break;
					}
				}
				
				if (!pageFound) {
					if (closestMatch != null) {
						pageFound = true;
						pageXML = closestMatch;
					}
				}

				if (!pageFound) {
					// requested page not found
					// use default
					pageRequest = "/"
			
					for (var i=0; i<pageNodes.length; i++) {
						if ($(pageNodes[i]).attr('Location') == pageRequest) {
							pageFound = true;
							pageXML = pageNodes[i];
						
							break;
						}
					}
				}
				var redirect = false;
				var pageSecure = $(pageXML).attr('Secure');
				if ((pageSecure == 'true') && SSLenabled) {
					if (window.location.protocol != 'https:') {
						redirect = true;
						var redirectHref = 'https' + String(window.location.href).substr(4);
						doRedirect(redirectHref, 'secure page');
						
					}
				}
				else if (pageSecure == 'false') {
					if (window.location.protocol == 'https:') {
						redirect = true;
						var redirectHref = 'http' + String(window.location.href).substr(5);
						doRedirect(redirectHref, 'unencrypted page');
					}
				}

				if (!redirect) {
					if ($(pageXML).attr('Name') != null) pageName = $(pageXML).attr('Name');
					if (!pageSetFound && ($(pageXML).attr('For') != null)) pageDataXML = getDataSource($(pageXML).attr('For'));
					renderPage();
				}
			},
			error: function(req, textStatus, errorThrown) {
				alert("error loading pages.xml: textStatus=" + textStatus);
			}
		});
	}
	else {
		// browser not ok
		var redirectHref = sitePrefix + '/browser.html';
		document.write('Redirecting to <a href="' + redirectHref + '">browser compatibility page</a>.');
		window.location.href = redirectHref;
	}
});

// overwrite document.write!
(function() {
	var _write = document.write;
	document.write = function(t) {
		debugOut('document.write blocked: ' + t);
		//t = '<!--##DEFER'+t+'DEFER##-->';
		//return 'v'=='v' ? _write(t) : _write.call(document, t);
	}
})();

function resolve() {
	//document.body.innerHTML = document.body.innerHTML.replace(/<!--##DEFER(.+)DEFER##-->/g, '$1');
}
