/*******************************************************************************************
 * Component:  DataCogs.js - Client scripts reused by applications.
 *
 *
  ********************************************************************************************/

// Variable to track whether page is dirty.
var _doCheckPageIsDirty = false;
var _pageIsDirty = false;
var _dirtyMessage = "WARNING: There is unsaved data.\n\n" +
                     "Press OK - Proceed and abort changes made.\n" +
                     "Press Cancel - Retain the changes and cancel your action.";
var _controlPrefix = "ctl00";

/*------------------------------------------------------------------------------------------
 * Name:         GetApplicationPath
 * Description:  Based on the current url work out the system path.
 *               So if the url is:-
 *                 http://DOMAINNAME/ApplicationName/dir/page1.aspx
 *               Then '/ApplicationName' should be returned.
 * Notes:        Sometimes the pathname returned does not include a forward slash "/" and
 *               this needs to be added manually.  
 ------------------------------------------------------------------------------------------*/
function GetApplicationPath() {
	var applicationPath = top.location.pathname.substring(0, top.location.pathname.indexOf("/", 1));
	if (applicationPath.indexOf("/", 0) != 0) {
		applicationPath = '/' + applicationPath;
	}
	return applicationPath;  
}

/*------------------------------------------------------------------------------------------
 * Name:         InitialiseFormControls
 * Description:  Initialise controls on the form and set the dirty page check if changes are 
 *               made to controls.
 * Parameters:   doCheckPageIsDirty - Indicate if dirty check is performed for the page.
 ------------------------------------------------------------------------------------------*/
function InitialiseFormControls(doCheckPageIsDirty) {
	if (doCheckPageIsDirty)
	{
		_doCheckPageIsDirty = doCheckPageIsDirty;
	}
	
	// DOM check.
	if (document.getElementById) {

		// Get all <input> elements.
		var inputFields = document.getElementsByTagName('input');
		var i = 0;
		// Loop through all input elements.
		while (inputFields[i]) {
			if (navigator.userAgent.indexOf('Opera') == -1) {
				if (inputFields[i].getAttribute("case")) {
					SetCase(inputFields[i], inputFields[i].getAttribute("case"));
				}
			}
			if (_doCheckPageIsDirty) {
				AddDirtyCheckToField(inputFields[i]);
			}
			i++;
		}

		// Get all <textarea> elements (don't do this for opera because of bug with onchange event).
		var textareas = document.getElementsByTagName('textarea');
		var j = 0;
		// Loop through all textarea elements.
		while (textareas[j]) {
			if (navigator.userAgent.indexOf('Opera') == -1) {
				if (textareas[j].getAttribute("case")) {
					SetCase(textareas[j], textareas[j].getAttribute("case"));
				}
			}
			// Add dirty check if required.
			if (_doCheckPageIsDirty) {
				AddDirtyCheckToField(textareas[j]);
			}
			j++;
		}

		// Get all <select> elements and add onchange event.
		var selectFields = document.getElementsByTagName('select');
		// If applying dirty check...
		if (_doCheckPageIsDirty) {
			var k = 0;
			// Loop through all select elements.
			while (selectFields[k]) {
				AddDirtyCheckToField(selectFields[k]);
				k++;
			}
		  
			// Get all <a> elements and add onclick event that will run when
			// user tries to exit the page to test if details have changed.
			var anchorFields = document.getElementsByTagName('a');
			var l = 0;
			// Loop through all anchor elements.
			while (anchorFields[l]) {
				CheckPageIsDirty(anchorFields[l]);
				l++;
			}
		}

	}
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         SetCase
 * Description:  Function to set the case of a editable textbox or textarea.
 *               Adds onchange event to field to convert to either upper or lower case.
 * Parameters:   control = the field object.
 *               textCase = "upper" or "lower".
 ------------------------------------------------------------------------------------------*/
function SetCase(control, textCase) {
	if (textCase == "upper") {
		AddToOnChange(control, "this.value = this.value.toUpperCase();", false);
	}
	else if (textCase == "lower") {
		AddToOnChange(control, "this.value = this.value.toLowerCase();", false);
	}
}

/*------------------------------------------------------------------------------------------
 * Name:         AddDirtyCheckToField
 * Description:  Function that adds onchange event to field to set page level variable to
 *               indicate whether values have been changed.
 *               If the field contains attribute "disabledirtycheck", dirty check
 *               for that field is ignored.
 * Parameters:   control = the field object.
 ------------------------------------------------------------------------------------------*/
function AddDirtyCheckToField(control) {
	var controlType = control.getAttribute('type');

	// Ignore changes made to the field which has attribute "disabledirtycheck"
	if (!control.getAttribute("disabledirtycheck")) {

		// Don't apply to hidden fields or button.
		if (controlType == "hidden") {
			return;
		}

		// If submit button then apply confirmation message.
		if (controlType == "submit" || controlType == "image" || controlType == "button") {
			// Ignore More button from DbCombo
			if (controlType == "button" && control.id.indexOf("MoreResultsButton") >= 0) {
				return;
			}
			CheckPageIsDirty(control);
			return;
		}

		// If reset button then reset dirty flag back to false onreset of form.
		if (controlType == "reset") {
			CheckPageIsDirty(control);
			AddToOnReset(control.form, 'setTimeout(\'_pageIsDirty = false;\', 5);', false);
			return;
		}

		// Check for radio button or checkbox and add onclick event.
		// If radio then don't apply onclick event to checked radio button.
		if (controlType == 'checkbox' || 
		   (controlType == 'radio' && !control.checked)) {
			AddToOnClick(control, "_pageIsDirty = true;", true);
		} else {
			// If textbox, textarea or select then add onchange event.
			AddToOnChange(control, "_pageIsDirty = true;", true);
		}
	}
}

/*------------------------------------------------------------------------------------------
 * Name:         CheckPageIsDirty
 * Description:  Function that adds onclick event to submit button or link that will check
 *               if page has changed and alert the user before they attempt to leave.
 *               If class name of 'disabledirtycheck' is added to the button or link then this check will not
 *               take place.  So add this class name to all submit buttons or links where
 *               this check should not occur.
 * Parameters:   control = the field object.
 ------------------------------------------------------------------------------------------*/
function CheckPageIsDirty(control) {
	var addCheck = true;
	var addAfter = false;

	// If field is a link
	if (control.tagName == "A") {
		addAfter = true;
	}

	// Check if "disabledirtycheck" attribute supplied
	if (control.getAttribute("disabledirtycheck")) 
	{
		addCheck = false;
	} 
	// Check if "disabledirtycheck" CSS definition is applied.
	else if (control.className.indexOf("disabledirtycheck") >= 0) 
	{
		addCheck = false;
	}

	if (addCheck) {  
		AddToOnClick(control, "if (_doCheckPageIsDirty && _pageIsDirty && !confirm(_dirtyMessage)) return false;", addAfter);
	}
}

/*------------------------------------------------------------------------------------------
 * Name:         AddToOnClick
 * Description:  Allows code to be added to the onclick event of a button.
 *               This function is useful when microsoft uses its own code for the onclick
 *               event (validation of a form), but other javascript code also needs to be
 *               run.
 * NOTE: If there is no microsoft code on the onclick event on the button then don't use 
 *       this function.  Just add the onclick event in your code behind page.
 ------------------------------------------------------------------------------------------*/
function AddToOnClick(control, functionCode, addAfterFlag) {
	control.onclick = new Function(AddToFunction(control.onclick, functionCode, addAfterFlag));
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         AddToOnSubmit
 * Description:  Allows code to be added to the onsubmit event of a form.
 ------------------------------------------------------------------------------------------*/
function AddToOnSubmit(control, functionCode, addAfterFlag) {
	control.onsubmit = new Function(AddToFunction(control.onsubmit, functionCode, addAfterFlag));
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         AddToOnChange
 * Description:  Allows code to be added to the onchange event of an element.
 ------------------------------------------------------------------------------------------*/
function AddToOnChange(control, functionCode, addAfterFlag) {
	control.onchange = new Function(AddToFunction(control.onchange, functionCode, addAfterFlag));
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         AddToOnReset
 * Description:  Allows code to be added to the onreset event of a form.
 ------------------------------------------------------------------------------------------*/
function AddToOnReset(control, functionCode, addAfterFlag) {
	control.onreset = new Function(AddToFunction(control.onreset, functionCode, addAfterFlag));
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         AddToOnKeyup
 * Description:  Allows code to be added to the onkeyup event of a form.
 ------------------------------------------------------------------------------------------*/
function AddToOnKeyup(control, functionCode, addAfterFlag) {
	control.onkeyup = new Function(AddToFunction(control.onkeyup, functionCode, addAfterFlag));
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         AddToOnKeydown
 * Description:  Allows code to be added to the onkeydown event of a form.
 * NOTES: This doesn't work in FireFox very well.
 ------------------------------------------------------------------------------------------*/
function AddToOnKeydown(control, functionCode, addAfterFlag) {
	control.onkeydown = new Function(AddToFunction(control.onkeydown, functionCode, addAfterFlag));
	return true;
}

function AddToOnLoad(control, functionCode, addAfterFlag) {
alert(control);
	control.onload = new Function(AddToFunction(control.onload, functionCode, addAfterFlag));
	alert(control.onload);
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         AddToFunction
 * Description:  Function to create a function based on the old function code (if exists)
 *               Add new code that is passed in.
 * Parameters:   oldFunctionCode = current event function applied to element (onclick, etc).
 *               newFunctionCode = new code to add to the event.
 *               addAfterFlag = whether to add the new code before or after existing event.
 ------------------------------------------------------------------------------------------*/
function AddToFunction(oldFunctionCode, newFunctionCode, addAfterFlag) {
	var updatedFunction = "";
	var semiColon = "";
	// If the event currently exists on the element.
	if (oldFunctionCode) {
		var pos = oldFunctionCode.toString().indexOf("{");
		// Remove the last } character from the old function code.
		updatedFunction = oldFunctionCode.toString().substr(0, oldFunctionCode.toString().lastIndexOf("}") - 1);
		// Remove all code before and including the first { character.
		updatedFunction = RTrim(updatedFunction.substr(pos + 1));

		if (addAfterFlag) {
			// Add a semi-colon (;) in case the original function does not have one.
			// This can happen in the case where the original code is generated by .NET Framework
			if (updatedFunction.substr(updatedFunction.length, 1) != ";") {
				semiColon = ";";
			}
			// Add the function code after the existing code.
			updatedFunction = updatedFunction + semiColon + " " + newFunctionCode;
		} else {
			// Determine if semi-colon (;) is required to separate the old and new functions
			if (newFunctionCode.substr(newFunctionCode.length, 1) != ";") {
				semiColon = ";";
			}
			// Add the function code before the existing code.
			updatedFunction = newFunctionCode + " " + updatedFunction;
		}
	} else {
		// The event does not currently exist on the element so just add the new function code.
		updatedFunction = newFunctionCode;
	}
	return updatedFunction;
}

/*++++++++++++++++++*
 * String functions *
 *++++++++++++++++++*/

/*------------------------------------------------------------------------------------------
 * Name:         LTrim
 * Description:  Remove leading spaces.
 ------------------------------------------------------------------------------------------*/
function LTrim(value) {
	if (value == null) {
		return "";
	}
	return value.replace(/[ ]*/, "");
}

/*------------------------------------------------------------------------------------------
 * Name:         RTrim
 * Description:  Remove trailing spaces.
 ------------------------------------------------------------------------------------------*/
function RTrim(value) {
	if (value == null) {
		return "";
	}
	return value.replace(/[ ]*$/, "");
}

/*------------------------------------------------------------------------------------------
 * Name:         Trim
 * Description:  Remove leading and trailing spaces.
 ------------------------------------------------------------------------------------------*/
function Trim(value) {
	if (value == null) {
		return "";
	}
	return value.replace(/(^\s+)|(\s+$)/g,"");
}

/*------------------------------------------------------------------------------------------
 * Name:         ClearValidationSummary
 * Description:  Clear the validation summary text.
 * Parameters:   None
 ------------------------------------------------------------------------------------------*/
function ClearValidationSummary() {
	// If the validation summary has been turned off (page has been validated).
	var validatorId = AddPrefixToId("ValidationSummary1");
	if (document.getElementById(validatorId))
	{
		document.getElementById(validatorId).style.color = "red";
		document.getElementById(validatorId).innerHTML = "";
	}  
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         DisableRightClick
 * Description:  Disable the mouse right click.
 ------------------------------------------------------------------------------------------*/
function DisableRightClick() {
	var message = "";
	function clickIE() {
		if (document.all) {
			(message);
			return false;
		}
	}
	function clickNS(e) {
		if (document.layers || (document.getElementById && !document.all)) {
			if (e.which == 2 || e.which == 3) {
				(message);
				return false;
			}
		}
	}
	if (document.layers) {
		document.captureEvents(Event.MOUSEDOWN);
		document.onmousedown = clickNS;
	}
	else {
		document.onmouseup = clickNS;
		document.oncontextmenu = clickIE;
	}

	document.oncontextmenu = new Function("return false");
}

/*------------------------------------------------------------------------------------------
 * Name:         SetFocus
 * Description:  Function that sets focus on an element.
 * Parameters:   controlId - id of the element.
 ------------------------------------------------------------------------------------------*/
function SetFocus(controlId) {
	// DOM check.
	if (document.getElementById) {
		// Test if ctrl exists.
		if (document.getElementById(controlId)) {
			var ctrl = document.getElementById(controlId);

			// If ctrl is container (span or table).
			// This happens when custom controls are wrapped inside container.
			if (ctrl.tagName == "SPAN" || ctrl.tagName == "TABLE") {
				// Determine in input or select control is the first control in container.
				var inputPos = ctrl.innerHTML.toLowerCase().indexOf('<input');
				var selectPos = ctrl.innerHTML.toLowerCase().indexOf('<select');

				// Elements weren't found so exit doing nothing.        
				if (inputPos == -1 && selectPos == -1) {
					if (ctrl.tagName == "TABLE")
						ctrl.focus();
					return;
				} 
				else {
					// Default to search for input element.
					var tagName = "input";
					// No input element found so search for "select" element.
					if (inputPos == -1) {
						tagName = "select";
						// If both an input and select element was found within the container...
					} 
					else if (selectPos > -1) {
						// Select element came before input element and thus should receive focus.
						if (selectPos < inputPos) {
							tagName = "select";
						}
					}
				}
				// Get the first element to receive focus.
				var element = ctrl.getElementsByTagName(tagName)[0];
				ctrl = element;
			}

			// Test to make sure ctrl can receive focus.
			if (!ctrl.disabled) {
				ctrl.focus();
			}
		}
	}
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenWindow
 * Description:  Generic function used to popup a window with specified settings.
 ------------------------------------------------------------------------------------------*/
function OpenWindow(url, name, width, height, left, top, options, isModal, title) {
	// If modal is specified and the current browser supports the showModalDialog method.
	if (isModal && window.showModalDialog) {
		// Call function to open a modal window.
		OpenModalWindow(url, name, width, height, left, top, options, title);
	} 
	else {
		var win;
		if (!width && !height && !left && !top && !options) {
			win = window.open(url, name);
		} 
		else {
			win = window.open(url, name, 'width=' + width + ',height=' + height + ',' + options);
		}
		if (!win.opener) {
			win.opener = window;
		}
		
		// Check if url that is opening is on another server.
		// If so then don't run the resizeTo and moveTo methods as they will cause 
		// a javascript error.
		if (url.substring(0, 7).toLowerCase() != "http://") {
			win.resizeTo(width, height);
			if (left && top && screen) {
				if (left < 0) {
					left += screen.availWidth - width;
				}
				if (top < 0) {
					top += screen.availHeight - height;
				}
				win.moveTo(left, top);
			}
		}
		win.focus();
	}
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenModalWindow
 * Description:  Generic function used to popup a modal window with specified settings.
 *               Make sure the entry <base target="_self"> is set between the <head> tags
 *               on the popup page.
 ------------------------------------------------------------------------------------------*/
function OpenModalWindow(url, name, width, height, left, top, options, title) {
	var options = 'dialogHeight=' + height + 'px;dialogWidth=' + width + 'px;help=no;status=no;' + options;
	var topPos = top;
	var leftPos = left;
	// If top or left are not specified then set to 0.
	if (!topPos) topPos = 0;
	if (!leftPos) leftPos = 0;

	// Center the modal window if position has not been specified.
	if (topPos == 0 && leftPos == 0) {
		options = 'center=yes;' + options;
	} 
	else {
		options = 'dialogleft=' + leftPos + 'px;dialogTop=' + topPos + 'px;' + options;
	}

	// Replace 'scrollbars' with 'scroll' in options (if exists).
	options = options.replace(/scrollbars/gi, 'scroll');

	// Replace any ',' with ';' in the option list.
	options = options.replace(/,/g, ';');


	// Add title parameter
	url = AppendUrlParameter(url, 'Title', title);
	// Indicate to the popup page that the page is opened in modal mode
	url = AppendUrlParameter(url, 'Modal', 'true');

	var returnValue = window.showModalDialog(url, name, options);

	// Check if the returnValue is an array
	if (returnValue != null) {
		// Assign the selected value back to the controls
		var i;
		var paramItem;
		var controlObject;
		for (i = 0; i < returnValue.length; i++) {
			paramItem = returnValue[i].split('|');
			if (document.getElementById(paramItem[0])) {
				var controlObject = document.getElementById(paramItem[0]);      
				controlObject.setAttribute(paramItem[2], paramItem[1]);
				if (paramItem[2] != 'innerHTML') {
					// Activate dirty check
					RunOnChange(controlObject);
				}
			}  
		}  
	}  
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenCalendar
 * Description:  Popup a Calendar modal window.
 ------------------------------------------------------------------------------------------*/
function OpenCalendar(controlId, displayFormat) {
	var dateControl = document.getElementById(controlId); 
	var defaultDateValue = dateControl.value.replace(/\s/g, '');
	var calUrl = GetApplicationPath() + "/Popups/PopupCalendar.aspx?ControlId=" + controlId + "&DefaultDateValue=" + defaultDateValue + "&DisplayFormat=" + displayFormat;
	var popupWidth = 230;
	var popupHeight = 222;
	var topPos = null; 
	var leftPos = null;
	var options = "resizable=yes,scrollbars=no";
	var isModal = true;
	var title = 'Select a date';
	if (!IsBrowserIE()) {
		popupHeight = 234;
	}
	OpenWindow(calUrl, "PopupCalendar", popupWidth, popupHeight, leftPos, topPos, options, isModal, title);
}

/*------------------------------------------------------------------------------------------
 * Name:         PopupReturnSelectedItem
 * Description:  Return the selected item from the popup window to the original caller control.
 ------------------------------------------------------------------------------------------*/
function PopupReturnSelectedItem(controlId, returnValue, isModal) {
	// Modal mode	
	if (isModal && window.showModalDialog) {
		var returnList = new Array(0);
		returnList = AddModalReturnValue(returnList, controlId, returnValue);
		window.returnValue = returnList;
	} 
	else if (window.opener != null) {
		var controlObject = window.opener.document.getElementById(controlId);
		controlObject.value = returnValue;
		// force dirty check
		RunOnChange(controlObject);
	}

	window.close();
}

/*******************************************************************************************
 * Name:         PopupReturnSelectedItemWithDescription
 * Description:  Return the selected item with description from the popup window to the 
 *               original caller control.
 *******************************************************************************************/
function PopupReturnSelectedItemWithDescription(codeControlId, descriptionControlId, codeValue, descriptionValue, isModal) {
	// Modal mode
	if (isModal && window.showModalDialog) {
		var returnList = new Array(0);
		returnList = AddModalReturnValue(returnList, codeControlId, codeValue);
		returnList = AddModalReturnValue(returnList, descriptionControlId, descriptionValue, 'innerHTML');
		window.returnValue = returnList;
	}
	else if (window.opener != null && document.getElementById) {
		window.opener.document.getElementById(codeControlId).value = codeValue;
		//Need to run the OnChange first so that the description is not cleared out
		RunOnChange(window.opener.document.getElementById(codeControlId));
		// Only passback description if the description span is present on the opener form.
		if (window.opener.document.getElementById(descriptionControlId)) {
			window.opener.document.getElementById(descriptionControlId).innerHTML = descriptionValue;
		}
	}
	window.close();
}

/*******************************************************************************************
 * Name:         AddModalReturnValue
 * Description:  Add the return value for Modal popup as an array of parameter items with
 *               pipe '|' as the delimiter to separate the field, value and property.
 *               E.g. if the control is a textbox with id txtSurname and value returned is 
 *               'Smith', and the property name which has a default value of 'value', 
 *               the parameter item stored would be: txtSurname|Smith|value
 *               The return array is then used to populate controls if data is passed back.
 *******************************************************************************************/
function AddModalReturnValue(listArray, controlId, controlValue, propertyName) {
	if (controlId == null && controlValue == null) {
		return listArray;
	}
	
	// default control property is 'value'
	if (propertyName == null) {
		propertyName = 'value';
	}
	
	// Add new entry to existing array
	var data = controlId + '|' + controlValue + '|' + propertyName;
	listArray[listArray.length] = data;

	return listArray;
}

/*******************************************************************************************
 * Name:         RunOnChange
 * Description:  If onchange event exist on the field then fire the event.
 *******************************************************************************************/
function RunOnChange(controlObject) {
	if (controlObject.onchange) {
		// If 'validatoronchange' method exists in onchange event (IE) then call FireEvent
		// otherwise simply call the onchange method (other browsers).
		if (controlObject.onchange.toString().toLowerCase().indexOf('validatoronchange') > -1) {
			// check if fireEvent is supported, e.g. IE 5x does not support this
			if (controlObject.fireEvent) {
				controlObject.fireEvent("onchange");
			}
		} 
		else {
			controlObject.onchange();
		}
	}
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenWindowPostBack
 * Description:  Generic function used to popup a window with specified settings after a postback.
 * Notes:        Prevents the same action from executed again if the browser Back button is activated.
 ------------------------------------------------------------------------------------------*/
function OpenWindowPostBack(url, name, width, height, left, top, options) {
	// The flag is used to prevent the same script from running
	// when the browser Back button is activated.
	var actionFlagControl = document.getElementById(AddPrefixToId("HiddenFieldJavascriptActionFlag"));
	if (!actionFlagControl || (actionFlagControl && actionFlagControl.value != "")) {	
		OpenWindow(url, name, width, height, left, top, options);
		// Clear the value to indicate that the same window should not be opened if the
		// Back button is activated
		if (actionFlagControl) {
			actionFlagControl.value = "";
		}
	}
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenWindowDefault
 * Description:  Generic function used to popup a window with default settings.
 ------------------------------------------------------------------------------------------*/
function OpenWindowDefault(url, name) {
	OpenWindow(url, name);
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenWindowDefaultPostBack
 * Description:  Generic function used to popup a window with default settings after a postback.
 * Notes:        Prevents the same action from executed again if the browser Back button is activated.
 ------------------------------------------------------------------------------------------*/
function OpenWindowDefaultPostBack(url, name) {
	OpenWindowPostBack(url, name);
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenReport
 * Description:  Function used to popup the report window to run report using URL access.
 ------------------------------------------------------------------------------------------*/
function OpenReport(url) {
	var popupWidth = 900;
	var popupHeight = 600;
	var topPos = 1; 
	var leftPos = 1;
	var options = "resizable=yes,scrollbars=yes";
	OpenWindow(url, "OpenReport", popupWidth, popupHeight, leftPos, topPos, options);
	return false;
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenApplication
 * Description:  Function used to popup the application window.
 ------------------------------------------------------------------------------------------*/
function OpenApplication(url) {
	var popupWidth = 900;
	var popupHeight = 600;
	var topPos = 1; 
	var leftPos = 1;
	var options = "resizable=yes,scrollbars=yes";
	OpenWindow(url, "OpenApplication", popupWidth, popupHeight, leftPos, topPos, options);
	return false;
}

/*------------------------------------------------------------------------------------------
 * Name:         OpenReportPostBack
 * Description:  Function used to popup the report window after a postback.
 * Notes:        Prevents the same action from executed again if the browser Back button is activated.
 ------------------------------------------------------------------------------------------*/
function OpenReportPostBack(url) {
	var popupWidth = 900;
	var popupHeight = 600;
	var topPos = 1; 
	var leftPos = 1;
	var options = "resizable=yes,scrollbars=yes";
	OpenWindowPostBack(url, "OpenReport", popupWidth, popupHeight, leftPos, topPos, options);
	return false;
}

/*------------------------------------------------------------------------------------------
 * Name:         IsBrowserIE
 * Description:  Function to check if the browser is IE.
 *               Returns true is IE, false otherwise.
 ------------------------------------------------------------------------------------------*/
function IsBrowserIE() {
	return (navigator.appName == "Microsoft Internet Explorer");
}

/*------------------------------------------------------------------------------------------
 * Name:         AppendUrlParameter
 * Description:  Append a parameter to the existing Url.
 ------------------------------------------------------------------------------------------*/
function AppendUrlParameter(url, paramName, paramValue) {
	var returnValue = url;

	if (paramValue) {
		if (url.indexOf('?') > 0) {
			returnValue += '&' + paramName + '=' + paramValue;
		}
		else {
			returnValue += '?' + paramName + '=' + paramValue;
		}
	}  
	return returnValue;
}

/*------------------------------------------------------------------------------------------
 * Name:         ClearValidationSummary
 * Description:  Clear the validation summary text.
 * Parameters:   None
 ------------------------------------------------------------------------------------------*/
function ClearValidationSummary() {
	// If the validation summary has been turned off (page has been validated).
	var validatorId = AddPrefixToId("vsValidationSummary");
	if (document.getElementById(validatorId))
	{
		document.getElementById(validatorId).style.color = "red";
		document.getElementById(validatorId).innerHTML = "";
	}  
	return true;
}

/*------------------------------------------------------------------------------------------
 * Name:         GridCheckBoxSelectDeselectAll
 * Description:  Function used to select/deselect all checkboxes in a
 *               given group (p_group is the id of the group, such as a table).
 ------------------------------------------------------------------------------------------*/
function GridCheckBoxSelectDeselectAll(groupId, selectAllchecked) {
	var inputs = document.getElementById(groupId).getElementsByTagName('input');
	for (var i = 0; i < inputs.length; i++) {
		if (inputs[i].getAttribute('type') == 'checkbox') {
			inputs[i].checked = selectAllchecked;
		}
	}
	GridSetSelectDeselectLabel(selectAllchecked);
}

/*------------------------------------------------------------------------------------------
 * Name:         GridCheckBoxSelectionCheck
 * Description:  Function to determine if the SelectAll checkbox should be checked or not.
 *               If any of the delete checkboxes are unchecked, then the SelectAll checkbox
 *               should be unchecked.
 * Parameters:   None
 ------------------------------------------------------------------------------------------*/
function GridCheckBoxSelectionCheck(groupId, selectAllCheckboxId, checkboxId) {
	if (document.getElementById) {
		var inputs = document.getElementById(groupId).getElementsByTagName('input');
		var selectAllchecked = true;
		var i = 0;
		// While there are input fields and selectAllchecked is still true ...
		while (i < inputs.length && selectAllchecked) {
			// If the field is a checkbox ...
			if (inputs[i].getAttribute('type') == 'checkbox') {
				// If it is not the CheckAll checkbox ...
				if (inputs[i].getAttribute('id') != selectAllCheckboxId) {
					// If it is one of the delete checkboxes ...
					if (inputs[i].getAttribute('id').indexOf(checkboxId) >= 0) {
						selectAllchecked = inputs[i].checked;
					}
				}
			}
			i++;
		}
	}
	document.getElementById(selectAllCheckboxId).checked = selectAllchecked;
	GridSetSelectDeselectLabel(selectAllchecked);
}

/*------------------------------------------------------------------------------------------
 * Name:         GridSetSelectDeselectLabel
 * Description:  Function to determine the value in the checkall label whick is either 
 *               "Select All" or "Deselect All".
 * Parameters:   None
 ------------------------------------------------------------------------------------------*/
function GridSetSelectDeselectLabel(selectAllchecked) {
	if (document.getElementById) {
		if (selectAllchecked) {
			document.getElementById('lblSelectDeselectAll').innerHTML = "Deselect All";
		}
		else {
			document.getElementById('lblSelectDeselectAll').innerHTML = "Select All";
		}
	}
}


/*++++++++++++++++++++++++++*
 * Default button functions *
 *++++++++++++++++++++++++++*/

/*------------------------------------------------------------------------------------------
 * Name:         DefaultButtonHandler
 * Description:  Trap keydown against textbox to force default button click
 * NOTES: This doesn't work in FireFox very well.
 ------------------------------------------------------------------------------------------*/
function DefaultButtonHandler(buttonId, windowEvent) {

	var btn = GetObject(buttonId);

	if (windowEvent) {  
		if (document.all) {
			if (windowEvent.keyCode == 13) {      
				windowEvent.returnValue = false;
				windowEvent.cancel = true;
				btn.focus();
				btn.click();
			}
		}
		else if (document.getElementById) {
			if (windowEvent.keyCode == 13) {
				windowEvent.returnValue = false;
				windowEvent.cancel = true;
				btn.click();      
			}    
		}
		else if (document.layers) {
			if (windowEvent.which == 13) {
				windowEvent.returnValue = false;
				windowEvent.cancel = true;
				btn.focus();
				btn.click();
			}
		}
	}  
}

/*------------------------------------------------------------------------------------------
 * Name:         GetObject
 * Description:  Find the object base on the object Id and return it.
 ------------------------------------------------------------------------------------------*/
function GetObject(objectId, doc) { 
	var pos, i, retObj;  
	if (!doc) {
		doc = document; 
	}
	if ((pos = objectId.indexOf("?")) >= 0 && parent.frames.length) {
		doc = parent.frames[objectId.substring(pos + 1)].document; 
		objectId = objectId.substring(0, pos);
	}
	if (!(retObj = doc[objectId]) && doc.all) {
		retObj = doc.all[objectId]; 
	}
	for (i = 0; !retObj && i < doc.forms.length; i++) {
		retObj = doc.forms[i][objectId];
	}
	for (i = 0; !retObj && doc.layers && i < doc.layers.length; i++) {
		retObj = GetObject(objectId, doc.layers[i].document);
	}
	if (!retObj && doc.getElementById) {
		retObj = doc.getElementById(objectId); 
	}
	return retObj;
}

/*------------------------------------------------------------------------------------------
 * Name:         AddPrefixToId
 * Description:  Add prefix to a control id.
 ------------------------------------------------------------------------------------------*/
function AddPrefixToId(id)
{
	if (id.indexOf(_controlPrefix) >= 0) {
		return id;
	}
	else {
		return _controlPrefix + "_" + id;
	}
}


// FOR SOME REASON, THE FOLLOWING CODE FROM RESOURCE FILE VALIDATEDATE.JS FOR THE SELECTDATE CONTROL IS NOT LOADED.
// All days in full format.
var _validDay = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
// All months in full format.
var _validMonth = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
// All months in abbreviated format.
var _validMonthAbbrev = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
// Valid number of days for each month.
var _validDaysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

/*------------------------------------------------------------------------------------------
 * Name: ValidateDate
 * Description: Check if a value entered is a valid date.
 ------------------------------------------------------------------------------------------*/
function ValidateDate(source, args) {
	var myDateID = document.getElementById(source.controltovalidate);
	args.IsValid = true;
	if (!CheckDate(myDateID)) {
		args.IsValid = false;
	}
	return args.IsValid;
}

/*------------------------------------------------------------------------------------------
 * Name: CheckDate
 * Description: Receive a date from a textbox in any format, validate that date and
 * convert it to 'dd-MMM-yyyy' format.
 * This function accepts dates in the following formats:
 * 1) ddmmyy
 * 2) ddmmyyyy
 * 3) dd-mm-yy
 * 4) dd-mm-yyyy
 * 5) dd-mon-yy
 * 6) dd-mon-yyyy
 * 7) dd-month-yy
 * 8) dd-month-yyyy
 * *) In examples 3-8 the '-' character can be replaced with
 * either '/', '.', '' or a space.
 * --> All converted to dd-MMM-yyyy.
 ------------------------------------------------------------------------------------------*/
function CheckDate(ctrl) {
	var dd;
	var mm;
	var yy;
	var yyyy;
	var mon = "";
	var currentDate = new Date();
	var format = "dd-mmm-yyyy";

	// Determine if just numbers have been used or combination.
	if (ctrl.value == "") {
		return true;
	}

	if (ctrl.getAttribute("displayformat") != null) {
		format = ctrl.getAttribute("displayformat");
	}

	// Defaults to today's date
	if (ctrl.value == "t") {
		ctrl.value = currentDate.getDate() + "-" + (currentDate.getMonth() + 1) + "-" + currentDate.getFullYear();
	}

	// Defaults to tomorrow's date
	if (ctrl.value == "+") {
		ctrl.value = (currentDate.getDate() + 1) + "-" + (currentDate.getMonth() + 1) + "-" + currentDate.getFullYear();
	}

	// Defaults to yesterday's date
	if (ctrl.value == "-") {
		ctrl.value = (currentDate.getDate() - 1) + "-" + (currentDate.getMonth() + 1) + "-" + currentDate.getFullYear();
	}

	// Defaults to next week's date
	if (ctrl.value == "w") {
		var nextWeekDate = new Date(currentDate.getTime() + (7 * 86400000));
		ctrl.value = nextWeekDate.getDate() + "-" + (nextWeekDate.getMonth() + 1) + "-" + nextWeekDate.getFullYear();
	}

	// If numbers and characters were entered.
	if (isNaN(ctrl.value)) {
		var dateSeparator = "-";
		// Replace the following: ' ', ',', '/', '\', '.' with the split character.
		var dateValue = ctrl.value
		dateValue = dateValue.replace(/\s/g, dateSeparator);
		dateValue = dateValue.replace(/,/g, dateSeparator);
		dateValue = dateValue.replace(/\./g, dateSeparator);
		dateValue = dateValue.replace(/\\/g, dateSeparator);
		//the following may look like it is partly commented but it actually works!
		dateValue = dateValue.replace(/\//g, dateSeparator);

		// If the split character wasn't found then date is invalid.
		if (dateValue.indexOf(dateSeparator) == -1) {
			return false;
		}

		// Split the date up based on the split character used.
		var splitDate = dateValue.split(dateSeparator);
		dd = splitDate[0];
		mm = splitDate[1];
		yy = splitDate[2];

		// If no values are given, default day to today's date, month to current month,
		// and year to current year.
		if (dd == "") {
			dd = currentDate.getDate();
		}

		if (mm == "") {
			mm = currentDate.getMonth() + 1;
		}
		if (yy == "") {
			yy = currentDate.getFullYear().toString().substr(2, 2);
		}

	// if date is just numbers (eg. 010301 or 01032001).
	} 
	else {
		// Check if a decimal point was entered in the date.
		if (ctrl.value.indexOf('.') >= 0) {
			return false;
		}

		// Date value must be in 6 or 8 digit format.
		if (ctrl.value.length != 6 && ctrl.value.length != 8) {
			return false;
		}
		else {
			dd = ctrl.value.substr(0, 2);
			mm = ctrl.value.substr(2, 2);
			yy = ctrl.value.substr(4, 4);
		}
	}

	// Check if dd is a number.
	if (isNaN(dd)) {
		return false;
	// if date value is a number check it is between 1 and 31.
	}
	else if (dd < 1 || dd > 31) {
		return false;
	}
	// Check if yy value is a number and has 2 or 4 characters.
	if (isNaN(yy)) {
		return false;
	}
	else if (yy.length != 4 && yy.length != 2) {
		return false;
	}
	else {
		// Expand the year to 4 digits if only 2 digits.
		if (yy.length == 4) {
			yyyy = yy;
		}
		else {
			var currentCentury = currentDate.getFullYear().toString().substr(0, 2);
			var currentYear = currentDate.getFullYear().toString().substr(2, 2);
			// prefix current century to the year entered if current year > 50
			if (currentYear > 50)
			{
				yyyy = currentCentury + yy;
			}
			else if (yy < 50)
			{
				yyyy = currentCentury + yy;
			}
			else
			{
				yyyy = currentCentury - 1 + yy;
			}
		}
	}

	// Check if the mm value is already in character format (eg. "Jun").
	if (isNaN(mm)) {
		// Check that the month entered is a valid 3 character month.
		var i = 0;
		var valid = false;

		while (_validMonthAbbrev[i] && !valid) {
			if (_validMonthAbbrev[i].toUpperCase() == mm.toUpperCase()) {
				valid = true;
				mon = _validMonthAbbrev[i];
				mm = i;
			}
			i++;
		}
		if (!valid) {
			return false;
		}
	}
	else {
		// if month value is a number check it is between 1 and 12.
		if (mm > 0 && mm < 13) {
			// Subtract 1 from the month As array starts at 0.
			mm = mm - 1;
			mon = _validMonthAbbrev[mm];
		}
		else {
			return false;
		}
	}

	var febDaysToAdd = 0;
	// if february then check for leap year.
	if (mm == 1 && (yyyy%4) == 0) {
		// it is not a leap year if year ends with '00' and is not divisible
		// by 400. eg 1900, 2100, etc. 1600, 2000 & 2400 are leap years.
		if (yyyy.substr(2, 2) == "00" && (yyyy%400) != 0) {
			febDaysToAdd = 0;
		}
		else {
			febDaysToAdd = 1;
		}
	}

	// Check that the number of days entered is valid for that month.
	if (dd > (_validDaysInMonth[mm] + febDaysToAdd)) {
		return false;
	}

	// Pad 0 to the day value if a single digit.
	if (dd.length == 1) {
		dd = "0" + dd;
	}

	//Convert date value into Date object
	newDate = new Date();
	newDate.setFullYear(yyyy, mm, dd);
	// Format the date
	ctrl.value = FormatDate(newDate, format);

	return true;
}

/*------------------------------------------------------------------------------------------
 * Name: FormatDate
 * Description: Format the date object.
 ------------------------------------------------------------------------------------------*/
function FormatDate(dateValue, format) {
	var dValue = dateValue.getDate();
	var ddValue = (dValue < 10) ? '0' + dValue : dValue;
	var mValue = dateValue.getMonth() + 1;
	var mmValue = (mValue < 10) ? '0' + mValue : mValue;
	var mmmmValue = _validMonth[dateValue.getMonth()];
	var mmmValue = _validMonthAbbrev[dateValue.getMonth()];
	var yyyyValue = dateValue.getFullYear() + "";
	var yyValue = yyyyValue.substr(2, 2);
	var wwValue = _validDay[dateValue.getDay()];
	var wValue = wwValue.substr(0, 3);

	format = format.toLowerCase();

	if (format.indexOf("dd") > -1) {
		format = format.replace("dd", "ddValue");
	}
	else if (format.indexOf("d") > -1) {
		format = format.replace("d", "dValue");
	}

	if (format.indexOf("mmmm") > -1) {
		format = format.replace("mmmm", "mmmmValue");
	}
	else if (format.indexOf("mmm") > -1) {
		format = format.replace("mmm", "mmmValue");
	}
	else if (format.indexOf("mm") > -1) {
		format = format.replace("mm", "mmValue");
	}
	else if (format.indexOf("m") > -1) {
		format = format.replace("m", "mValue");
	}

	if (format.indexOf("yyyy") > -1) {
		format = format.replace("yyyy", "yyyyValue");
	}
	else if (format.indexOf("yy") > -1) {
		format = format.replace("yy", "yyValue");
	}

	if (format.indexOf("ww") > -1) {
		format = format.replace("ww", "wwValue");
	}
	else if (format.indexOf("w") > -1) {
		format = format.replace("w", "wValue");
	}

	format = format.replace("ddValue", ddValue);
	format = format.replace("dValue", dValue);
	format = format.replace("mmmmValue", mmmmValue);
	format = format.replace("mmmValue", mmmValue);
	format = format.replace("mmValue", mmValue);
	format = format.replace("mValue", mValue);
	format = format.replace("yyyyValue", yyyyValue);
	format = format.replace("yyValue", yyValue);
	format = format.replace("wwValue", wwValue);
	format = format.replace("wValue", wValue);

	return format;
}

/*------------------------------------------------------------------------------------------
 * Name:         FormatNumber
 * Description:  Function to format a number for a control.
 * Parameters:   
 ------------------------------------------------------------------------------------------*/
function FormatNumber(controlID, decimalPlaces) {
	if (document.getElementById(controlID)) {
		var ctrlValue = document.getElementById(controlID).value;
		if (ctrlValue.length > 0) {
			if (!isNaN(ctrlValue)) {
				ctrlValue = parseFloat(ctrlValue);
				document.getElementById(controlID).value = ctrlValue.toFixed(decimalPlaces);
			}
		}
	}
}

