/*
'Author					: Stefan Kruger
'Date Created			: 21-Feb-2005
'Last Changed by		: KDT
'Date Changed			: 19-Apr-2006
'Version				: 1.0.19042006
'Comments:
'Date:			Desc:															
'--------------------------------------------------------------------------------------------
'18-Mar-2005	Much refined the working of action handling.
'29-Mar-2005	Added capability to use different loader images for different situations
'				and refined general loading processes for compatibility with grid.
'30-Mar-2005	Made preload javascript common identifiers (page and component) non-static.
'31-Mar-2005	Made all common component and page identifiers non-static.
'05-Apr-2005	Added a stopProcessing flag to genericSubmit that allows you to stop the
'				loading of a component's URL into a page position even if it is specified
'				in the component description - used mostly for dynamic grid loading.
'12-Apr-2005	Add trim, isValidEmail, isInteger functions
'18-Apr-2005	Add isDecimal function
'22-Apr-2005	Added generic versions of getComponentRelations and the action checker,
				that is not limited to grid use only, as well as some tweaks to allow
				the sending of global querystring data to the grid creation function.
'25-Apr-2005	Minor tweaks in checkAction 
'20-May-2005	Added history integration
'23-May-2005	Tweaked the getPage method to be history add toggleable.
'27-Jun-2005	Tweaked the createXMLHttp method to try and load the latest xmlhttp (ver 4.0)
				first before loading any other xmlhttp. 
				(Trying to work around IE bug that crashes on intense searching process in grid)
'06-Jul-2005	Add maskAmount
'10-Jul-2005	Changed the executePageAction function to always pass strings to default function
				executions because of breakage of "number strings seen in popup grid scenarios"
'22-Aug-2005	Added Left/Right functions for Javascript
				Added MaskMe function which would take 100 -> 100.00 and 100. -> 100.00 and 
				100.1 -> 100.10
'08-Sep-2005	Added a event cancellation function
'14-Sep-2005	Tweaked maskMe function added by PlR on 22-Sep-2005
'17-Sep-2005	Added a popup window function

'ToDoList:
'Date:			Desc:															Status:
'--------------------------------------------------------------------------------------------
22-Aug-2005		Make Left/Right functions a prototype of String					Not done
*/

//////////////////////////////////////////////////////////////////////////////////////////////
//CONSTANTS
//////////////////////////////////////////////////////////////////////////////////////////////
/*
Defines some extra string functionality
*/
String.prototype.LTrim = new Function("return this.replace(/^\\s+/,'')");
String.prototype.RTrim = new Function("return this.replace(/\\s+$/,'')");
String.prototype.Trim = new Function("return this.replace(/^\\s+|\\s+$/g,'')");
String.prototype.TrimForSearch = new Function("return this.replace(/^\(\\+|\\s)+|\(\\+|\\s)+$/g,'')");

/*
Defines different page loaders that can be used in the genericSubmit function
*/
var regularloadingstring = "<TABLE WIDTH=100% HEIGHT=100%><TR VALIGN=MIDDLE><TD ALIGN=CENTER height=200><IMG border=0 SRC='images/preloaderreg.gif'></TD></TR></TABLE>";
var tabloadingstring = "<TABLE WIDTH=100% HEIGHT=100%><TR VALIGN=MIDDLE><TD ALIGN=LEFT height=18><IMG border=0 SRC='images/preloadertop.gif'></TD></TR></TABLE>";

/*
Defines different error page notification display messages used in the pageLoadChecker function
*/
var servererror = "There has been a server error while processing your request.|^^|Click <a href='javascript:void(0)' onclick='alert(lasterror);' class='drillmenu'>here</a> to view the complete error.";
var error404 = "The page you requested cannot be found.|^^|Click <a href='javascript:void(0)' onclick='alert(lasterror);' class='drillmenu'>here</a> to view the complete error.";
var error403 = "You do not have permission to view the page you requested. Method|^^|Click <a href='javascript:void(0)' onclick='alert(lasterror);' class='drillmenu'>here</a> to view the complete error.";
var error405 = "Access to the resource you requested not allowed.|^^|Click <a href='javascript:void(0)' onclick='alert(lasterror);' class='drillmenu'>here</a> to view the complete error.";
var memberiderror = "Please select a valid member in the \"Member Selection\" area on the left hand side of the page before continuing."
var lasterror = "";

/*MOdal path change global*/
var modalpathchange = "../../";

/*
Defines common regular expressions
*/
var spaceregex = / /g
var ampregex = /\&/g
var singlequoteregex = /\'/g
var stefanregex = /\|\^\^\|/g
var inversestefanregex = /\^\|\|\^/g
var compidmarkerregex = /\^ComponentIDMarker\^/g
var compnamemarkerregex = /\^ComponentNameMarker\^/g
var compurlmarkerregex = /\^ComponentURLMarker\^/g
var posnamemarkerregex = /\^PositionNameMarker\^/g
var pageidmarkerregex = /\^PageIDMarker\^/g
var comptitlemarkerregex = /\^ComponentTitleMarker\^/g
var gqsmarkerregex = /\^GQSMarker\^/g

//////////////////////////////////////////////////////////////////////////////////////////////
//MOUSE CURSOR HANDLING
//////////////////////////////////////////////////////////////////////////////////////////////

/*
Mouse cursor handling and loading functions (Used in submissions to display activity)
*/

function busyCursor(){
	try { document.body.style.cursor = "busy";}
	catch(e) { alert(e.message);}
}

function linkCursor(){
	try { document.body.style.cursor = "hand";}
	catch(e) { alert(e.message);}
}

function regularCursor(){
	try { document.body.style.cursor = "auto";}
	catch(e) { alert(e.message);}
}

function showLoading(){
	busyCursor();
	var loaddiv = document.getElementById("loadingDiv");
	if (loaddiv){
		loaddiv.style.display = "";
		loaddiv.innerHTML = "Loading...";
	}
	loaddiv = null;
}

function hideLoading(){
	regularCursor();
	var loaddiv = document.getElementById("loadingDiv");
	if (loaddiv){
		loaddiv.style.display = "none";
	}
	loaddiv = null;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//GENERAL STRING HANDLING
//////////////////////////////////////////////////////////////////////////////////////////////

/*
Function to remove ampersand
*/
function ampEncode(strMessage){
	return strMessage.replace(ampregex,"%26")
}

/*
Function to fix single quotes for database use (ie:replace one with two)
*/
function fixSingleQuote(strMessage){
	return strMessage.replace(singlequoteregex,"''")
}

//////////////////////////////////////////////////////////////////////////////////////////////
//COMPONENT LOADING FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////
/*
Load the most recent XMLHTTP object available for IE or XMLHttpRequest for Mozilla
*/
function createXMLHttp(){
	var myobj;
	try {myobj = new ActiveXObject("Msxml2.XMLHTTP.4.0");}
	catch (ex) { try {myobj = new ActiveXObject("Msxml2.XMLHTTP.3.0");}
	catch (ex) { try {myobj = new ActiveXObject("Msxml2.XMLHTTP");}
	catch (ex) { try {myobj = new ActiveXObject("Microsoft.XMLHTTP");}
	catch (ex) { try {myobj = new XMLHttpRequest();}
	catch (ex) { myobj = false; alert("Could not load XMLHTTP component");}}}}}
	return myobj;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//PREDEFINED USER FUNCTIONS USED IN THE POST-LOADING OF PAGES
//////////////////////////////////////////////////////////////////////////////////////////////

/*
This function is used when displaying a database defined load  (--> getPage)
*/
var loadContent = function (oXML,gqs) {
	//Check for expiry of content before loading
	if (oXML.responseText.substr(2,35) == "<!-- Message box start delimiter-->"){
		expireSession();
	}
	else {
		var retar = new Array();
		retar = (oXML.responseText).split("|^^|");
		//alert(retar);
		if ((retar.length >= 10) && ((retar.length - 2) % 8 == 0)){
			//Process Page Preload
			try {
				//Substitute the pageID(first found at arrayvalue 3 and then repeated every 5) into pagepreloadexecute when needed
				retar[0] = retar[0].replace(pageidmarkerregex,[retar[3]]);
				eval(retar[0]);
			}
			catch (ex) {}
			//Load each component of page
			for (k = 2; k < retar.length; k++){
				//Substitute the common identifiers (page and component) into componentpreloadexecute when needed
				retar[k+3] = retar[k+3].replace(compurlmarkerregex,[retar[k]]);
				retar[k+3] = retar[k+3].replace(pageidmarkerregex,[retar[k+1]]);
				retar[k+3] = retar[k+3].replace(compidmarkerregex,[retar[k+2]]);
				retar[k+3] = retar[k+3].replace(posnamemarkerregex,[retar[k+4]]);
				retar[k+3] = retar[k+3].replace(compnamemarkerregex,[retar[k+5]]);
				retar[k+3] = retar[k+3].replace(comptitlemarkerregex,[retar[k+7]]);
				retar[k+3] = retar[k+3].replace(gqsmarkerregex,gqs);
				//alert("Preload is :" + retar[k+3]);
				genericSubmit(retar[k],gqs + "&gridfunction=" + retar[1] + "&pageid=" + retar[++k] + "&compid=" + retar[++k] + "&loadedin=" + retar[k+2],retar[++k],retar[++k],completedSingleLoad,regularloadingstring,eval((retar[k+2].toString()).toLowerCase()));
				//Increment to get past componentName and isGrid that will be used in future.
				k += 3;
			}
		}
		else {
			getMessageBox("Page Load Error","Page not loaded.|^^|Reason: Invalid array received from the page template loader.","topcontent");
		}
	}
	regularCursor();
	oXML = null;
};

/*
This function is used when displaying a single page load
*/
var completedSingleLoad = function (oXML,outputDiv) {
	var display = pageLoadChecker(oXML,outputDiv)
	if (display) {
		eval(outputDiv).innerHTML = display;
	}
	regularCursor();
	display = null;
	oXML = null;
};

/*
This function is used when simply alerting return values from a background page submission
*/
var alertHiddenResponse = function (oXML) {
	alert(oXML.responseText);
	/*bottomcontent.style.display = "";
	bottomcontent.innerHTML = oXML.responseText;*/
	regularCursor();
	oXML = null;
};

//////////////////////////////////////////////////////////////////////////////////////////////
//CONTENT LOADING FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////

/*
A function to hide and clear the regular content display.
*/
function contentHider(){
	topcontent.innerHTML = '';
	topcontent.style.display = 'none';
	bottomcontent.innerHTML = '';
	bottomcontent.style.display = 'none';
	try {nd();} catch (ex) {}
}

//Test function for default action function
function actionOneDefault(par1,par2,par3){
	var str = "This is the default function for action 1 test.\nIt just alerts the parameter values.\n"
	if (arguments) {
		if (arguments.length){
			for (var j = 0; j < arguments.length; j++){
				str += "\nPar" + j + ":" + arguments[j];
			}
		}
	}
	alert(str);	
}

/*
Wrapper function for action searching
Post-loading is controlled by "useCustomFunction" :
	useCustomFunction = true --> do a custom (usually grid) postload
	useCustomFunction = false --> do a regular postload
*/
function checkAction(actionName,compID,formName,useCustomFunction,completionFunction,isModalGrid){
	var execFunction = null;
	if (useCustomFunction){

		if (completionFunction) {
			execFunction = completionFunction
		}
		else {
			alert("No function for action check specified.")
			return null;
		}
	}
	else {	
		//With this method the form of the calling page should contain all the required fields.
		execFunction = function (oXML) {
			replaceString = "''";
			evalstr = "executePageAction(" + oXML.responseText.replace("^RelationalID^",replaceString) + ")";
			try {
				eval(evalstr);
			}
			catch (ex) {
				alert("Execution of an action failed.");
			}
			regularCursor();
			oXML = null;
		};
	}
	//This page links to the navigationfunction page and this is situation relative so update!
	var data = "action=getcomponentactions&actionname=" + actionName + "&compid=" + compID;
	if (formName) {
		data += "&formname=" + formName;
	}
	else {
		data += "&formname=null";
	}
	//Pathchange for modal grid
	var pathchange = "";
	if (isModalGrid){
		pathchange = "../../";
	}
	hiddenSubmit(pathchange + "bin/navigationfunctions.asp",data,execFunction,0,null,false);	
}

/*
Function to fetch a full list of relations that this component is involved in
*/
function getComponentRelations(componentid,isModalGrid){
	var returnArray = [];
	if (!(isNaN(componentid))) {
		var completedFullRelationList = function (oXML) {
			returnArray = (oXML.responseText).split("|^^|");
			if (!(returnArray.length)) {
				alert("Invalid relation data.");
			}
			regularCursor();
			oXML = null;
		};
		var pathchange = "";
		if (isModalGrid){
			pathchange = "../../";
		}
		//This page links to the navigationfunction page and this is situation relative so update!
		hiddenSubmit(pathchange + "bin/navigationfunctions.asp","action=getfulllistofcomponentrelations&compid=" + componentid,completedFullRelationList,0,null,false);
	}
	return returnArray;
}

/*
This function executes a page action defined in the DB
It can also attach form data (via a form name) that is sent to all pages loading from the definition
in the DB. Now it can also execute default functions assigned to an action in the DB taking the relation values 
as parameters.
*/
function executePageAction(preload,id,defaultFunction,formToSend,relationValueString){
	//Do Action Preloader
	try {eval(preload);}
	catch (ex) {alert(preload);}
	var relationURLdata = "relations=none"
	//If a relation the process it and pass on
	if (relationValueString) {
		//Manage relationValueString to turn it into URL encoding to send as data
		relationURLdata = relationValueString.replace(stefanregex,"&");
		relationURLdata = relationURLdata.replace(inversestefanregex,"=");
		//Do Default function if it is required
		if (defaultFunction) {
			//Split the relationValueString to extract actual values to pass to function
			var functionstring = "";
			var functionstring_array = relationValueString.split("|^^|");
			var functionstring_component_array;
			if (functionstring_array.length){
				for (i = 0; i < functionstring_array.length; i++) {
					functionstring_component_array = functionstring_array[i].split("^||^")
					///Comma seperate values
					if (functionstring != "") {
						functionstring += ",";
					}
					//Add string delimiters to non-number values
					//if (isNaN(functionstring_component_array[1])){
						functionstring += "'" + functionstring_component_array[1].replace(/'/g,"\\'") + "'";
					/*}
					else {
						functionstring += functionstring_component_array[1];
					}*/
				}
			}
			//Now execute default function
			try {
				var exec = defaultFunction + "(" + functionstring + ");"
				eval(exec);
			}
			catch (ex) {
				alert("Failed action execution");
			}
		}
	}
	if (id) {
		var formURLData = ""
		if (formToSend) {
			formURLData = "&" + fetchInputFormData(formToSend);
		}
		var gqsdata = relationURLdata + formURLData;
		//alert(gqsdata);
		getPage(id,gqsdata);
	}
}

/*
This would be a content selection from menu i.e. DB specified content
*/
function getPage(id,globalquerystring,skipHistoryWrite){
	var page = "template.asp?UniqueID={" + id + "}"
	//Set globalquerystring to "blank" in querystring string if null
	if (!(globalquerystring)){ globalquerystring = "gqs=blank";}
	//else {alert(globalquerystring);}
	//Save history
	if (!(skipHistoryWrite)) {
		addHistory(id,globalquerystring);
	}
	hiddenSubmit(page,globalquerystring,loadContent,2,null,true);
}

/*
Single page component loader function
Accepts multiple loader strings and can be limited to JS-only by the stopProcessingAfterJS flag.
*/
function genericSubmit(page,data,preload,div,whenDoneRunThis,LoaderToUse,stopProcessingAfterJS) {
	//Process preload - accepts a stopProcessing flag from called function if needed;
	//alert(data);
	try {eval(preload);}
	catch (ex) {
		alert("Tried : " + preload + "\nError : " + ex.message);
	}
	//Call page loader
	if (!(stopProcessingAfterJS)) {
		//Check for a valid division to load the page in
		try {
			document.getElementById(div).style.display = '';
			document.getElementById(div).innerHTML = LoaderToUse;
		}
		catch (ex){alert(ex.message); return;}
		hiddenSubmit(page,data,whenDoneRunThis,1,div,true);
	}
}

/*
A page loader function that works in the background.
It creates a new request object for each call, allowing for multiple simultaneous page loads,
and runs a user specified function when page load is completed.
It's different modes (specified by "modeDelimiter") are :
	GENERAL (0)			: Just returns the request object to the handling function.
						  (Used for general functions requiring background page calls.)
	SINGLEPAGELOAD (1)	: Returns the entire request object as well as a page division to
						  display its contents in.
						  (Used for loading and displaying a single page component)
	DATABASELOAD (2)	: Returns the entire request object as well as the queryString data to use
						  again on the individual
						  (Used for loading and displaying a DB defined set of page components simultaneously)
	RUNANDIGNORE (3)	: Runs request and then clears the request object upon load completion, without any
						  further action

Synchronisation is controlled by "syncmode" :
	syncmode = true --> asychronous transfer (meaning: processing continues on another thread until request load is complete.)
	syncmode = false --> sychronous transfer (meaning: processing is paused until request is completed.)
*/
function hiddenSubmit(page,data,whenDoneRunThis,modeDelimiter,div,syncmode) {
	//alert(div);
	try {
		var xmlhttp = createXMLHttp();
		//Check for loaded request component
		if (xmlhttp){
			xmlhttp.open("POST", page , syncmode);
			if (data != "") {
				xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf8;");
				//xmlhttp.setRequestHeader("Content-Type", "charset=utf-8");
				data = data.replace(spaceregex,"%20");
			}
			//This is the case for a call expecting no return whatsoever
			if (modeDelimiter == 3){
				xmlhttp.onreadystatechange = function (){
					if (xmlhttp.readyState == 4){
						regularCursor();
						xmlhttp = null;
					}
				};
			}
			//This is the case for a getPage function with global submission data
			if (modeDelimiter == 2){
				xmlhttp.onreadystatechange = function (){
					if (xmlhttp.readyState == 4){
						whenDoneRunThis(xmlhttp,data);
					}
				};
			}
			//This is the case for a page display submission ie: general case requiring a div to display data in.
			if (modeDelimiter == 1){
				xmlhttp.onreadystatechange = function (){
					if (xmlhttp.readyState == 4){
						whenDoneRunThis(xmlhttp,document.getElementById(div));
					}
				};
			}
			//This is the case for a more general function needing only the return values from a hiddenSubmit to process
			if (modeDelimiter == 0){
				xmlhttp.onreadystatechange = function (){
					if (xmlhttp.readyState == 4){
						whenDoneRunThis(xmlhttp);
					}
				};
			}
			busyCursor();
			xmlhttp.send(data);
		}
		else {
			alert("No XMLHTTP object initialised.");
		}
	}
	catch(e) {
		alert(e.message);
	}
}

/*
Custom HTML error checking function for some specified errors used to check page load status
before displaying the content in the browser.
*/
function pageLoadChecker(xmlObj,divInCaseOfMessage){
	//Check for null load division and set default
	if (!(divInCaseOfMessage)){
		divInCaseOfMessage = document.getElementById("topcontent");
	}
	//Get status
	var status = xmlObj.status;
	//Status - OK
	if (status == 200){
		return xmlObj.responseText;
		//return xmlObj.responseXML;
	}
	//Status - Server error (likely SQL or ASP sourced)
	/*if (status == 500){
		lasterror = xmlObj.responseText;
		getMessageBox("Server Error",servererror,divInCaseOfMessage.id);
		return;
	}*/
	//Status - Page not found
	if (status == 404){
		lasterror = xmlObj.responseText;
		getMessageBox("File Not Found",error404,divInCaseOfMessage.id);
		return;
	}
	//Status - Permission denied (likely local proxy or remote security)
	if (status == 403){
		lasterror = xmlObj.responseText;
		getMessageBox("Permission Denied",error403,divInCaseOfMessage.id);
		return;
	}
	//Status - Requested Method / Resource not allowed
	if (status == 405){
		lasterror = xmlObj.responseText;
		getMessageBox("Resource not allowed",error405,divInCaseOfMessage.id);
		return;
	}
	//Unhandled status but a page has been loaded so just display and see what happens
	divInCaseOfMessage = null;
	return xmlObj.responseText;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//SYSTEM INFORMATION HANDLING
//////////////////////////////////////////////////////////////////////////////////////////////
/*
IE modal window creater
*/
function createModalWin(page,height,width,arguments){
	if (!(arguments)){
		arguments = null;
	}
	var modalresult = window.showModalDialog(page,arguments,'help:no;scroll:no;center:yes;status:no;dialogHeight:' + height + 'px;dialogWidth:' + width + 'px;resizable:no');
	return modalresult;
}

/*
POPUP window
*/
//var newwindow = '';

function openNewWindow(url){
	try {
		window.open(url,"_blank", "width=720,scrollbars=yes,resizable=yes,toolbar=no,menubar=no,location=no");
	}
	catch (ex) {
		alert("An error occured while opening popup window.");
	}
	/*if (newwindow && (!newwindow.closed && newwindow.location)){
		alert("old");
		try {
			newwindow.location.href = url;
		}
		catch (ex) {newwindow = '';}
	}
	else {
		alert("new");
		newwindow = window.open(url,"_blank", "width=720,scrollbars=yes,resizable=yes,toolbar=no,menubar=no,location=no");
		if (!newwindow.opener) newwindow.opener = self;
	}
	try {
		if (window.focus) {
			newwindow.focus();
		}
	catch (ex) {}
	}*/
	return false;
}

/*
A general message box display function

USAGE :
Title			--> Header of Content
Content			--> Content of the messagebox with different bullets seperated by the "|^^|" marker
DivToLoadItIn	--> The page division to show the messagebox in.
*/
function getMessageBox(title,content,divToLoadItIn){
	var page = "bin/messagebox.asp";
	var data = "content=" + content + "&title=" + title;
	genericSubmit(page,data,null,divToLoadItIn,completedSingleLoad,regularloadingstring,false);
}

/*
Standard currency formatting function to emulate the ASP format function in JS
*/
function currencyFormatter(value){
	var dotspot,workspot,output,flag;
	//2 digit rounding simulator
	value = (Math.round(value * 100))/100;
	value = value.toString();
	//Add cents if required
	if (value.indexOf(".") == -1) {
		value = value.concat(".00");
	}
	dotspot = value.indexOf(".");
	workspot = dotspot;
	flag = true;
	//Add comma every 3 digits
	while (flag) {
		workspot = workspot - 3;
		if (workspot > 0) {
			var part1 = value.substring(0,workspot)
			var part2 = value.substring(workspot,value.length)
			value = part1 + "," + part2
			workspot = value.indexOf(",");
		}
		else {
			flag = false;
		}
	}
	dotspot = value.indexOf(".");
	if (value.substring(dotspot,value.length).length < 3){
		value = value.concat("0");
	}
	//Assumes ZAR output
	output = "R " + value
	return output;
}

/*
A function to check if a system event was the pressing of the enter key.
*/
function isEnterKey(evt){
	if (!evt){
		evt = window.event;
	}
	else if (!evt.keyCode){
		evt.keyCode = evt.which;
	}
	return (evt.keyCode == 13)
}

/*
A function to check if a system event was the pressing of the tab key.
*/
function isTabKey(evt){
	if (!evt){
		evt = window.event;
	}
	else if (!evt.keyCode){
		evt.keyCode = evt.which;
	}
	return (evt.keyCode == 9)
}

/*
A function to cancel event propagation
*/
function cancelEvent(event){
	try {
		event.cancelBubble = true;
		event.returnValue = false;
	}
	catch (ex){}
}

//////////////////////////////////////////////////////////////////////////////////////////////
//FORM INPUT HANDLING
//////////////////////////////////////////////////////////////////////////////////////////////

/*
A generalised form submitting function that returns the contents of a form in URL querystring
*/
function fetchInputFormData(formToProcess){
	var theform 
	if (formToProcess){
		theform = eval("document." + formToProcess)
	}
	else {
		theform = null
	}
	var queryString = ""
	var addString = ""
	if (theform) {
		try {
			for (var i = 0; i < theform.elements.length; i++){
				if (queryString == "") {
					addString = ""
				}
				else {
					addString = "&"
				}
				if (theform.elements[i].type == "radio") {
					if (theform.elements[i].checked){
						addString += theform.elements[i].name + "=" + ampEncode(theform.elements[i].value);
					}
				}
				else {
					if (theform.elements[i].type == "checkbox") {
						if (theform.elements[i].checked) {
							addString += theform.elements[i].name + "=" + 1;
						}
						else {
							addString += theform.elements[i].name + "=" + 0;
						}
					}
					else {
						if (theform.elements[i].type == "select-multiple") {
							for (j = 0; j < theform.elements[i].options.length; j++) {
								if (theform.elements[i].options[j].selected){
									if (addString != "" && addString != "&") {
										addString += "&"
									}
									addString += theform.elements[i].name + "=" + ampEncode(theform.elements[i].options[j].value);
								}
							}
						}
						else {
							//Meaning : Hidden, Text or Single-Select : All treated equally without discrimination... :-)
							addString += theform.elements[i].name + "=" + ampEncode(theform.elements[i].value);
						}
					}
				}
				if (addString != "&") {
					queryString += addString
				}
			}
		}
		catch (ex) { alert("Error processing input form.");}
	}
	else {
		//alert("Invalid input form specified.")
	}
	//alert(queryString);
	theform = null;
	return queryString;
}

/*
//Trims the spaces off the beginning and end of a string
function trim(strVal) {
	var re = /^\s*|\s*$/g
	return strVal.replace(re, "")
}
*/

//returns true if val is a valid internet e-mail address
function isValidEmail(val){
   re = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
   r = val.match(re);
   if (r == null) {
	return false;
   }
   else {
	return true
   }
}

//returns true if val is an integer
function isInteger(val){
	re = /^[-]?\d+$/;
	r = val.toString().match(re);
	if (r == null) {
		return false;
	}
	else {
		return true
	}
}

//returns true if val is a valid decimal
function isDecimal(val){
	//re = /([.])/;
	re = /^[-]?\d+([.]{1}\d+)?$/;
	r = val.toString().match(re);
	if (r == null) {
		return false;
	}
	else {
		return true
	}
}

//Used with onkeypress event
//takes the current value as input and cancel the event if the entered key makes the new value an invalid decimal
function maskAmount(val) {
	val = val + String.fromCharCode(window.event.keyCode);
	if (val != "") {
		re = /^\d+([.]?\d*)?$/;
		r = val.toString().match(re);

		if (r == null) {
			//alert("if");
			window.event.returnValue = false;
		}
		else {
			//alert("else");
		}
	}
}

// Added by Pieter Le Roux 22 Aug 2005
//MaskMe will replace 100. with 100.00
function maskMe(myobj){
	rr = /[.]/;
	
	if (myobj.value.match(rr)){
		if (Right(myobj.value,1) == "."){
			myobj.value = myobj.value.replace(rr,'.00');
		}
		var arr = myobj.value.split(".");
		if (arr[1].length == 1) {
			myobj.value = myobj.value.toString() + '0';
		}
	}
	else {
		if (myobj.value == "") {
			myobj.value = "0";
		}
		myobj.value = myobj.value.toString() + '.00';
	}
}

//Added by Pieter Le roux 22 Aug 2005
//Gives Javascript the Left/Right capability we like in VB
function Left(str, n){
	if (n <= 0)
	    return "";
	else if (n > String(str).length)
	    return str;
	else
	    return String(str).substring(0,n);
}
function Right(str, n){
    if (n <= 0)
       return "";
    else if (n > String(str).length)
       return str;
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}

function fetchAndSetTooltip(obj) {
	try {
		obj.title = obj.innerHTML;
	}
	catch (ex) {}
}

function mailMessage(formName, vAction) // To send any email message
{
	if (document.forms(formName).all("txtSubject").value != ""){
		if (document.forms(formName).all("txtMessage").value != ""){
			var page = "bin/mailer.asp"
			var data = "action="+vAction+"&" + fetchInputFormData(formName);
			hiddenSubmit(page,data,alertHiddenResponse,0,null,false);
			document.forms(formName).all("txtSubject").value = "";
			document.forms(formName).all("txtMessage").value = "";
		}
		else{
			alert("Please enter a valid message");
			return;
		}
	}
	else{
		alert("Please enter a valid subject line");
		return;
	}
}



/*
A generalised form submitting function that returns the contents of a form in URL querystring
Added to include ALL the listbox id's aswell - not only selected.
*/

function fetchFormAndListboxData(formToProcess)
{
	var theform 
	
	if (formToProcess)
	{
		theform = eval("document." + formToProcess)
	}
	else 
	{
		theform = null
	}
	var queryString = ""
	var addString = ""
	if (theform) 
	{
		try 
		{
			for (var i = 0; i < theform.elements.length; i++)
			{
				if (queryString == "") 
				{
					addString = ""
				}
				else 
				{
					addString = "&"
				}
				if (theform.elements[i].type == "radio") 
				{
					if (theform.elements[i].checked)
					{
						addString += theform.elements[i].name + "=" + ampEncode(theform.elements[i].value);
					}
				}
				else 
				{
					if (theform.elements[i].type == "checkbox") 
					{
						if (theform.elements[i].checked) 
						{
							addString += theform.elements[i].name + "=" + 1;
						}
						else 
						{
							addString += theform.elements[i].name + "=" + 0;
						}
					}
					else 
					{
						if (theform.elements[i].type == "select-multiple") 
						{
							for (j = 0; j < theform.elements[i].options.length; j++) 
							{	
								if (addString != "" && addString != "&") 
								{
									addString += "&"
								}
								addString += theform.elements[i].name + "=" + ampEncode(theform.elements[i].options[j].value);
							}
						}
						else 
						{
							//Meaning : Hidden, Text or Single-Select : All treated equally without discrimination... :-)
							addString += theform.elements[i].name + "=" + ampEncode(theform.elements[i].value);
						}
					}
				}
				if (addString != "&") 
				{
					queryString += addString
				}
			}
		}
		catch (ex) { alert("Error processing input form.");}
	}
	else 
	{
		//alert("Invalid input form specified.")
	}
	//alert(queryString);
	theform = null;
	return queryString;
}

/*
function isValidCellNumber(val)
{
      //var re = /^[-]?\d+([.]{1}\d+)?$/;
      //var re = /^[-]?\d+([.])?(\d+)?$/;
      var re = /^[0-9]{3,3}\s{0,1}[0-9]{3,3}\s{0,1}[0-9]{4,4}$/;
      return re.test(val.toString());
}
*/

function ShowHideSingleSelect(formName, vcheckbox, vselectBox)
{
	if (document.forms(formName).all(vcheckbox).checked == true) // show single selection box
	{
		document.forms(formName).all(vselectBox).style.display = "block";
	}
	else // hide single selection box
	{
		document.forms(formName).all(vselectBox).options[0].selected = true;
		document.forms(formName).all(vselectBox).style.display = "none";
	}
}

// Function - If a checkbox's state is dependant on a field, check it with this function and set the checked state
function checkboxAndFieldValidation(formName, vcheckbox, vtextField, vMessage, visEmail, vIsNumeric, vIsText)
{
	if (document.forms(formName).all(vcheckbox).checked == true) // check if the corresponding field has a value
	{
		if (vIsText == true) // check for a valid text entry
		{
			if (!document.forms(formName).all(vtextField).value != "")
			{
				document.forms(formName).all(vcheckbox).checked = false;
				alert(vMessage);
				return;
			}
		}
		
		if (visEmail == true) // check for a valid email entry
		{
			if (!isValidEmail(document.forms(formName).all(vtextField).value))
			{
				document.forms(formName).all(vcheckbox).checked = false;
				alert(vMessage);
				return;
			}
		}
		if (vIsNumeric == true)
		{
			if (!IsNumeric(document.forms(formName).all(vtextField).value))
			{
				document.forms(formName).all(vcheckbox).checked = false;
				alert(vMessage);
				return;
			}
		}
	}
}

function newWindowResize(vurl)
{ 
	window.open(vurl, "_blank", "status=yes,scrollbars=yes,resizable=yes,toolbar=yes,menubar=yes,location=yes"); //,top=0,left=0,width="+screen.availWidth+",height="+screen.availHeight
	//window.resizeTo(screen.availWidth, screen.availHeight); 
//	newWindow.moveTo(0, 0);
//	newWindow = null;
}

function IsNumeric(strString)
//  check for valid numeric strings	
{
   var strValidChars = "0123456789)-(+ ";
   var strChar;
   var blnResult = true;

   if (strString.length == 0) return false;

   //  test strString consists of valid characters listed above
   for (i = 0; i < strString.length && blnResult == true; i++)
      {
      strChar = strString.charAt(i);
      if (strValidChars.indexOf(strChar) == -1)
         {
         blnResult = false;
         }
      }
   return blnResult;
  }
  
function IsValidIDNumber(strString)
//  check for valid numeric strings	
{
	var strValidChars = "0123456789";
	var strChar;
	var blnResult = true;

	if (strString.length == 0 || strString.length != 13) return false;

	//  test strString consists of valid characters listed above
	for (i = 0; i < strString.length && blnResult == true; i++)
		{
		strChar = strString.charAt(i);
		if (strValidChars.indexOf(strChar) == -1)
			{
			blnResult = false;
			}
		}
	return blnResult;
}
