/*
'Author					: Stefan Kruger
'Date Created			: 07-Dec-2005
'Last Changed by		: Stefan Kruger
'Date Last Changed		: 18-Jan-2006
'Version				: 1.0.18012006
'Comments/Changes:
'Date:			Person:					Desc:
'------------------------------------------------------------------------------------------------------
'07-Dec-2005	Stefan Kruger			Created file
'20-Dec-2005	Stefan Kruger			Applied "Loading" to all hidden page loads.
'21-Dec-2005	Stefan Kruger			Added the component template loading.
'04-Jan-2006	Stefan Kruger			Used a "contentUpdater" workaround for IE not updating the
										division contents correctly on change of page layout.
										IF POSSIBLE THIS SHOULD BE REMOVED.

'ToDo List:
'Date:			Person:					Desc:
'------------------------------------------------------------------------------------------------------
'03-Jan-2006	Stefan Kruger			Make component printing globally functioning and accommodate
										for advanced search mode
'03-Jan-2006	Stefan Kruger			Make component help globally functioning
'05-Jan-2005	Stefan Kruger			Possibly move grid postload into createGrid Function????
*/

//////////////////////////////////////////////////////////////////////////////////////////////
//CONSTANTS
//////////////////////////////////////////////////////////////////////////////////////////////
/*
Define 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,'')");

/*
Definitions of contant values
*/
var defaultoutputdiv = null;
var divisionarray = new Array();
var modalpathchange = "../../";

/*
Definitions of contant common regular expressions
*/
var splitterregex = /\|\^\^\|/g;
var alternatesplitterregex = /\^\|\|\^/g;
var singlequoteregex = /'/g;

/*
Defines different page loaders that can be used in the genericSubmit function
*/
var regularloadingstring = "<div class=\"loader_indent_1 margin_1 margin_5\"><img src=\"images/loader_1.gif\" border=\"0\"></div>";
var tabloadingstring = "<div class=\"loader_indent_1 margin_1 margin_5\"><img src=\"images/loader_1.gif\" border=\"0\"></div>";


/*
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.|^^|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 lasterror = "";

/*Browser detection*/
var ieregex = /MSIE/i;
var mozregex = /FIREFOX/i;
var isie;

if (ieregex.test((navigator.userAgent).toUpperCase())) {
	isie = true;
}
else if (mozregex.test((navigator.userAgent).toUpperCase())){
	isie = false;
}
else {
	//Unknown browser
	//alert("Unsupported browser detected with User Agent:\n" + navigator.userAgent + "\nDefaulting to Mozilla(Gecko) mode.");
	isie = false;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//STARTUP EXECUTION
//////////////////////////////////////////////////////////////////////////////////////////////
/*
This function executes at the end on a page load just before login/tabload is displayed
*/
function staticPageLoadExecutions(divisionlist){
	//Make array of content hidable divisions
	divisionarray = divisionlist.split(splitterregex);
}

//////////////////////////////////////////////////////////////////////////////////////////////
//LOADING DISPLAY HANDLING
//////////////////////////////////////////////////////////////////////////////////////////////
/*
Loading division management functions.
*/
function showLoading(){
	busyCursor();
	var loaddiv = document.getElementById("loadingDiv");
	if (loaddiv){
		loaddiv.style.display = "block";
	}
	else {
		alert("Loading division not found.");
	}
	loaddiv = null;
}

function hideLoading(){
	regularCursor();
	var loaddiv = document.getElementById("loadingDiv");
	if (loaddiv){
		loaddiv.style.display = "none";
	}
	else {
		alert("Loading division not found.");
	}
	loaddiv = null;
}

/*
Mouse cursor handling functions.
*/
function busyCursor(){
	try { document.body.style.cursor = "wait";}
	catch(ex){ alert(ex.message);}
}

function regularCursor(){
	try { document.body.style.cursor = "auto";}
	catch(ex){ alert(ex.message);}
}

//////////////////////////////////////////////////////////////////////////////////////////////
//OBJECT CREATION 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 content load  (ie : from getPage function)
*/
var loadContent = function (oXML,gqs){
	//Check for expiry of content before loading
	if (checkForExpiry(oXML.responseText)){
		expireSession();
	}
	else {
		var retar = new Array();
		retar = (oXML.responseText).split("|^^|");
		//alert(retar.length + "\n" + ((retar.length - 1) % 12) + "\n" + retar);
		if ((retar.length >= 17) && ((retar.length - 3) % 14 == 0)){
			//Process Page Preload
			var pageguid = retar[0];
			try {
				eval(retar[1]);
			}
			catch (ex){
				alert("Error in page preload.\nTried : " + retar[1] + "\nError : " + ex.message);
			}
			var pagetitle = retar[2]
			//Load each component of page
			for (k = 3; k < retar.length; k++){
				//Extract data
				var componentid = parseInt(retar[k++]);
				var displaymode = parseInt(retar[k++]);
				var preload = retar[k++];
				var postload = retar[k++];
				var url = retar[k++];
				var maindiv = retar[k++];
				var displaywindowmanagement = eval(retar[k++].toLowerCase());
				var contentdiv = maindiv + "-contents";
				var titlediv = maindiv + "-title";
				var title = retar[k++];
				var subtitle = retar[k++];
				var componentname = retar[k++];
				var isprintable = eval(retar[k++]);
				var ismodal = eval(retar[k++]);
				var loaddata = retar[k++];
				var usesecurity = retar[k];
				
				//Set up page data
				var pagedata = gqs;
				if (pagedata){
					pagedata += "&";
				}
				pagedata += "pageguid=" + encodeURIComponent(pageguid) + "&cid=" + componentid + "&maindiv=" + maindiv + "&contentdiv=" + contentdiv + "&displaymode=" + displaymode;
				
				//Make load position hospitible
				var usethisdiv = contentdiv;
				if (displaywindowmanagement){
					setUpPosition(maindiv,componentid,title,isprintable);
				}
				else {
					usethisdiv = maindiv;
					manageDisplayWindow(usethisdiv,"show");
				}
				
				//Set current location
				setCurrentLocation(pagetitle);
				
				//Standard load
				if (displaymode == 1){
					genericSubmit(url,pagedata,preload,postload,usethisdiv,completedSingleLoad,regularloadingstring);
				}
				//Grid load
				else if (displaymode == 2){
					//Component preload
					try {
						eval(preload);
					}
					catch (ex){
						alert("Error in component '" + title + "'  preload.\nTried : " + preload + "\nError : " + ex.message);
					}
					//Load grid
					document.getElementById(usethisdiv).innerHTML = regularloadingstring;
					//Simulated Set Up Division
					createGrid(componentid,usethisdiv,displaymode,pagedata,componentname,loaddata,ismodal,usesecurity,title,subtitle);
					//Component preload
					try {
						eval(postload);
					}
					catch (ex){
						alert("Error in component '" + title + "' postload.\nTried : " + postload + "\nError : " + ex.message);
					}
				}
				//Form load
				else if (displaymode == 3){
					var loadURL = "",pathchange = "";
					if (ismodal){
						pathchange = modalpathchange;
					}
					//Old method
					//loadURL = pathchange + "bin/getformdata.asp";
					//genericSubmit(loadURL,pagedata,preload,postload,usethisdiv,completedSingleLoad,regularloadingstring);
					
					//New method
					loadURL = pathchange + "bin/getformdataaw.asp";
					var drawForm = function (oXML) {
						//alert(oXML.responseText);
						var objectSource = eval(oXML.responseText);
						for (var i = 0; i < objectSource.length;i++){
							//alert(objectSource[i]);
							//usethisdiv.appendChild(columnDiv);
							addFormElement(usethisdiv,objectSource[i][0],objectSource[i][1],objectSource[i][2],objectSource[i][3],null);
						}
						hideLoading();
						oXML = null;
					}
					hiddenSubmit(loadURL,pagedata,drawForm,0,null,postload,true);
				}
				//Invalid load
				else {
					alert("Error in page loader :\nInvalid display mode was requested.");
				}
			}
		}
		else {
			alert("Error in page loader :\nInvalid array received from page template loader.");
			//getMessageBox("Page Load Error","Page not loaded.|^^|Reason: Invalid array received from the page template loader.",defaultoutputdiv);
		}
	}
	hideLoading();
	oXML = null;
};

/*
This function is used when displaying a single page load
*/
var completedSingleLoad = function (oXML,outputDiv,postload){
	var display = pageLoadChecker(oXML,outputDiv);
	//Debug
	//debugMe(display);
	if (display){
		outputDiv.innerHTML = display;
	}
	if (postload) {
		try {
			eval(postload);
		}
		catch (ex){
			alert("Error occured in postload.\nTried : " + postload + "\nError : " + ex.message);
		}
	}
	hideLoading();
	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);
	//Debug
	//debugMe(oXML.responseText);
	hideLoading();
	oXML = null;
};

//////////////////////////////////////////////////////////////////////////////////////////////
//WINDOW MANAGEMENT
//////////////////////////////////////////////////////////////////////////////////////////////
/*
Function to fetch the default output division
*/
function getDefaultOutputDiv(){
	var loadDefaultDiv = function(oXML){
		if (oXML.status == 200){
			var defaultdiv = oXML.responseText;
			if (defaultdiv.length > 0){
				defaultoutputdiv = defaultdiv;
			}
			else {
				alert("Warning : No default loading division was found. HTML error messages may not display correctly.");
			}
		}
		else {
			alert("Error occured while fetching default division.\nError code returned was : " + oXML.status);
		}
		oXML = null;
	}
	hiddenSubmit("bin/actionfunctionmanager.asp","action=getdefaultoutputdiv",loadDefaultDiv,0,null,null,true);
}

/*
General display management function
*/
function manageDisplayWindow(divToProcess,manageModifier){
	var thediv = document.getElementById(divToProcess);
	if (thediv){
		if (manageModifier == "show"){
			thediv.style.display = "block";
			/*Workaround for IE not updating division content on page content change*/
			if (isie){
				//contentUpdater();
			}
		}
		if (manageModifier == "hide"){
			thediv.style.display = "none";
			/*Workaround for IE not updating division content on page content change*/
			if (isie){
				//contentUpdater();
			}
		}
		if (manageModifier == "close"){
			thediv.innerText = "";
			manageDisplayWindow(divToProcess,"hide");
		}
		if (manageModifier == "toggle"){
			if (thediv.style.display == "none"){
				thediv.style.display = "block";
			}
			else {
				thediv.style.display = "none";
			}
		}
	}
	else {
		//alert("Division '" + divToProcess + "' was not found in the document.");
	}
	thediv = null;
}

/*
A function to pepare a division for component to load in.
*/
function setUpPosition(division,componentid,title,isprintable){
	manageDisplayWindow(division,"show");
	var url = "componenttemplate.asp";
	var data = "loadin=" + division + "&componentid=" + componentid + "&title=" + encodeURIComponent(title) + "&isprintable=" + isprintable;
	hiddenSubmit(url,data,completedSingleLoad,1,division,null,false);
}

/*
Printing function per component
*/
function printComponent(componentid){
	alert("Printing component # : " + componentid);
	/*
	var page = "bin/navigationfunctions.asp"
	var data = "action=buildprintstring&componentid=" + componentid + "&searchValue=" + encodeURIComponent(search);
	var url;
	var fetchPrintString = function (oXML){
		if (oXML.status == 200){
			url = oXML.responseText;
			openNewWindow(url);
		}
		else {
			alert("Error : Cannot open the print page due an internal error.");
		}
		hideLoading();
		oXML = null;
	}
	hiddenSubmit(page,data,fetchPrintString,0,null,true);
	*/
}

/*
A function that will display context sensitive help per component.
*/
function showHelp(componentid){
	alert("Showing help for component # : " + componentid);
}

//////////////////////////////////////////////////////////////////////////////////////////////
//SYSTEM INFORMATION HANDLING FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////
/*
A function to hide and clear the regular content display.
*/
function contentHider(){
	//Clear content divisions
	try {
		for (var i=0;i<divisionarray.length;i++){
			manageDisplayWindow(divisionarray[i],"close");
		}
	}
	catch (ex){alert("Error while hiding content :\n" + ex.message);}
	//Clear possible tooltip residue
	tooltipHider();
}

function contentUpdater(){
	try {
		//Update each division
		for (var j=0;j<divisionarray.length;j++){
			if (document.getElementById(divisionarray[j] + "-contents")){
				if (document.getElementById(divisionarray[j] + "-contents").style.display != "none"){
					document.getElementById(divisionarray[j] + "-contents").style.display = "none";
					document.getElementById(divisionarray[j] + "-contents").style.display = "block";
				}
			}
		}
	}
	catch (ex){alert("Error while updating content :\n" + ex.message);}
}

/*
A function to hide and clear the tooltip display.
*/
function tooltipHider(){
	try {
		//nd();
	} catch (ex){
		alert("Error while unloading mouseover :\n" + ex.message);
	}
}

/*
A function to check if the context expiry messagebox is present in output.
*/
function checkForExpiry(textcheck){
	if (textcheck.substr(2,35) == "<!-- Message box start delimiter-->"){return true;}
	else {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=" + encodeURIComponent(content) + "&title=" + encodeURIComponent(title);
	genericSubmit(page,data,null,null,divToLoadItIn,completedSingleLoad,regularloadingstring,false);
}

/*
Auto tooltip function
*/
function fetchAndSetTooltip(obj){
	try {
		obj.title = obj.innerHTML;
	}
	catch (ex){}
}

/*
Standard debugging function
*/
function debugMe(text){
	alert(text);
	manageDisplayWindow(defaultoutputdiv,"show");
	document.getElementById(defaultoutputdiv).innerHTML = text;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//CONTENT LOADING FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////
/*
This would be a content selection from menu i.e. DB specified content
*/
function getPage(id,globalquerystring,skipHistoryWrite){
	var guidcheck = /{(.)+}/
	if (!(guidcheck.test(id))){
		id = "{" + id + "}";
	}
	var page = "pageloader.asp?uniqueid=" + id;
	//Set globalquerystring to "blank" in querystring string if null
	if (!(globalquerystring)){globalquerystring = "";}
	//Save history
	if (!(skipHistoryWrite)){
		try {
			addHistory(id,globalquerystring);
		}
		catch (ex){alert("Error occured adding history");}
	}
	hiddenSubmit(page,globalquerystring,loadContent,3,null,null,true);
}

/*
Single page component loader function
*/		 
function genericSubmit(page,data,preload,postload,div,whenDoneRunThis,LoaderToUse){
	//Process preload;
	try {eval(preload);}
	catch (ex){
		/*alert(preload)*/
		alert("Error occured in preload.\nTried : " + preload + "\nError : " + ex.message);
	}
	//If  page is specified call page loader, else just process postload.
	if (page){
		var loadMode;
		//If postload is specified
		if (postload){
			loadMode = 2;
		}
		//Else set default loading mode
		else {
			loadMode = 1;
		}
		//Check for a valid division to load the page in
		try {
			document.getElementById(div).style.display = "block";
			document.getElementById(div).innerHTML = LoaderToUse;
		}
		catch (ex){
			alert("Error in genericSubmit division validator for '" + div + "':\n" + ex.message);
			return;
		}
		hiddenSubmit(page,data,whenDoneRunThis,loadMode,div,postload,true);
	}
	else {
		//Process postload;
		try {eval(postload);}
		catch (ex){
			/*alert(postload)*/
			alert("Error occured in postload.\nTried : " + postload + "\nError : " + ex.message);
		}
	}
}

/*
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)
	SINGLEPAGEPOSTLOAD (2)	: Returns the entire request object as well as a page division to
							  display its contents in and a postload javascript to execute .
							  (Used for loading and displaying a single page component);
	CONTENTLOAD (3)			: Returns the entire request object as well as the queryString data
							  (Used for loading and displaying a DB defined set of page components simultaneously)
	RUNANDIGNORE (4)		: 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,postload,syncmode){
	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=UTF-8");
			}
			//If asynchronous set up postload function
			if (syncmode){
				xmlhttp.onreadystatechange = function (){
					if (xmlhttp.readyState == 4){
						execPostLoad(xmlhttp,modeDelimiter,whenDoneRunThis,div,postload,data);
					}
				};
			}
			if (!data) {
				data = "";
			}
			showLoading();
			xmlhttp.send(data);			
			//If synchronous execute postload function
			if (!(syncmode)){
				execPostLoad(xmlhttp,modeDelimiter,whenDoneRunThis,div,postload,data);
			}
		}
		else {
			alert("No XMLHTTP object initialised.");
		}
	}
	catch(ex){
		alert(ex.message);
	}
}

function execPostLoad(xmlhttp,modeDelimiter,whenDoneRunThis,div,postload,data){
	var continueclear = /http\/1\.1 100 cont[i]nue/ig;
	if ((xmlhttp.responseText).match(continueclear)) {alert("Caught HTTP/1.1 Continue 100")};
	hideLoading();
	//This is the case for a call expecting no return whatsoever
	if (modeDelimiter == 4){
		xmlhttp = null;
	}
	//This is the case for a getPage function with global submission data
	if (modeDelimiter == 3){
		whenDoneRunThis(xmlhttp,data);
	}
	//This is the case for a page display submission ie: general case requiring a div to display data in as well as postload execution.
	if (modeDelimiter == 2){
		whenDoneRunThis(xmlhttp,document.getElementById(div),postload);
	}
	//This is the case for a page display submission ie: general case requiring a div to display data in.
	if (modeDelimiter == 1){
		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){
		whenDoneRunThis(xmlhttp);
	}
}
				
/*
Custom HTML error checking function for some specified errors used to check page load status
before displaying the content in the browser.
*/
function pageLoadChecker(oXML,divInCaseOfMessage){
	//Check for null load division and set default
	if (!(divInCaseOfMessage)){
		divInCaseOfMessage = document.getElementById(defaultoutputdiv);
	}
	//Get status
	var status = oXML.status;
	//Status - OK
	if (status == 200){
		return oXML.responseText;
	}
	//Status - Server error (likely SQL or ASP sourced)
	/*if (status == 500){
		lasterror = oXML.responseText;
		getMessageBox("Server Error",servererror,divInCaseOfMessage.id);
		return;
	}*/
	//Status - Page not found
	if (status == 404){
		lasterror = oXML.responseText;
		getMessageBox("File Not Found",error404,divInCaseOfMessage.id);
		return;
	}
	//Status - Permission denied (likely local proxy or remote security)
	if (status == 403){
		lasterror = oXML.responseText;
		getMessageBox("Permission Denied",error403,divInCaseOfMessage.id);
		return;
	}
	//Status - Requested Method / Resource not allowed
	if (status == 405){
		lasterror = oXML.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 oXML.responseText;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//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 = document.getElementById(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 + "=" + encodeURIComponent(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 + "=" + encodeURIComponent(theform.elements[i].options[j].value);
								}
							}
						}
						else {
							//Meaning : Hidden, Text or Single-Select : All treated equally without discrimination... :-)
							addString += theform.elements[i].name + "=" + encodeURIComponent(theform.elements[i].value);
						}
					}
				}
				if (addString != "&"){
					queryString += addString;
				}
			}
		}
		catch (ex){ alert("Error processing input form :\n" + ex.message);}
	}
	else {
		//alert("Invalid input form specified.")
	}
	//alert(queryString);
	theform = null;
	return queryString;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//ACTION HANDLING FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////
/*
Test function for default action function
*/
function actionDefault(){
	var str = "This is the default action function 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);
	str = null;
}

/*
Function to fetch a full list of relations that this component is involved in
*/
function getComponentRelations(componentid,isModal){
	var returnArray = [];
	if (isNumber(componentid)){
		var completedFullRelationList = function (oXML){
			if (oXML.status == 200){
				returnArray = (oXML.responseText).split("|^^|");
			}
			else {
				alert("Error occured while fetching relation list.\nError code returned was : " + oXML.status);
			}
			hideLoading();
			oXML = null;
		};
		var pathchange = "";
		if (isModal){
			pathchange = modalpathchange;
		}
		hiddenSubmit(pathchange + "bin/componentfunctionmanager.asp","action=getoutboundrelationlist&componentid=" + componentid,completedFullRelationList,0,null,null,false);
	}
	return returnArray;
}

/*
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(actionID,compID,displayMode,formName,useCustomFunction,completionFunction,isModal){
	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.\nTried : " + evalstr + "\nError : " + ex.message);
			}
			hideLoading();
			oXML = null;
		};
	}
	//This page links to the navigationfunction page and this is situation relative so update!
	var data = "action=getcomponentactiondetail&actionID=" + actionID + "&compid=" + compID + "&displaymode=" + displayMode;
	if (formName){
		data += "&formname=" + formName;
	}
	else {
		data += "&formname=null";
	}
	//Pathchange for modal grid
	var pathchange = "";
	if (isModal){
		pathchange = modalpathchange;
	}
	hiddenSubmit(pathchange + "bin/componentfunctionmanager.asp",data,execFunction,0,null,null,false);	
}

/*
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,actionFunction,id,formToSend,relationValueString){
	//Do action preload
	try {eval(preload);}
	catch (ex){alert("Error occured in action preload.\nTried : " + preload + "\nError : " + ex.message);}
	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(splitterregex,"&");
		relationURLdata = relationURLdata.replace(alternatesplitterregex,"=");
		//Do default function if it is required
		if (actionFunction){
			//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 += ",";
					}
					/*
					NOTE : 
					All values are passed to handling function as strings for universality.
					The handling function should know what to expect where and parse accordingly.
					*/
					functionstring += "'" + functionstring_component_array[1].replace(singlequoteregex,"\\'") + "'";
				}
			}
			//Now execute default function
			var exec = actionFunction + "(" + functionstring + ");"
			try {
				eval(exec);
			}
			catch (ex){
				alert("Failed action function execution.\nTried : " + exec +"\nError : " + ex.message);
			}
		}
	}
	if (id){
		var formURLData = "";
		if (formToSend){
			formURLData = fetchInputFormData(formToSend);
		}
		var gqsdata = (relationURLdata == "") ? formURLData : (formURLData == "") ? relationURLdata : relationURLdata + "&" + formURLData;
		//alert(gqsdata);
		getPage(id,gqsdata);
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////
//POPUP HANDLING
//////////////////////////////////////////////////////////////////////////////////////////////
/*
IE modal window creater
*/
function openModalWindow(page,width,height,arguments){
	if (window.showModalDialog){
		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;
	}
	else {
		alert("Note : Your web browser does not support modal dialogue boxes. Pop up window was not displayed.");
	}
}

/*
Pop up window creater
*/
function openNewWindow(page,width,height){
	try {
		window.open(page,"_blank", "width=" + width + ",height=" + height +",scrollbars=yes,resizable=yes,toolbar=no,menubar=no,location=no");
	}
	catch (ex){
		alert("An error occured while opening popup window.");
	}
	return false;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//AUXILARY FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////
/*
These functions give Javascript left/right capability
*/
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);
    }
}

/*
Standard currency formatting function to emulate the ASP format function in JS
*/
function currencyFormatter(value){
	if (isNumber(value)){
		var dotspot,workspot,output,flag;
		//2 digit rounding simulator
		value = (Math.round(value * 100))/100;
		value = value.toString();
		//Add cents
		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;
	}
	else {
		alert("Error : The value that was supplier to the currency formatter was not a valid number.");
	}
}

/*
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){}
}

/*
Validation functions
*/
//Returns true if the value supplied is a valid e-mail address
function isValidEmail(val){
   var re = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
   return re.test(val.toString());
}

//Returns true if the value supplied is a valid integer
function isInteger(val){
	var re = /^[-]?\d+$/;
	return re.test(val.toString());
}

//Returns true if the value supplied is a valid decimal
function isDecimal(val){
	var re = /^[-]?\d+([.]{1})\d+$/;
	return re.test(val.toString());
}

//Returns true if the value supplied is a valid number
function isNumber(val){
	var re = /^[-]?\d+([.]{1}\d+)?$/;
	return re.test(val.toString());
}

//Returns true if the value supplied is a valid number
function isDate(val){
	var re = /^[0-9]{1,2}[-]{1}[a-zA-Z]{3}[-]{1}[0-9]{4,}$/;
	return re.test(val.toString());
}

// *************************************************** KOBUS ADDED ***********************************************
/*
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;
}

function IsValidTelephone(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 IsANumber(strString)
//  check for valid number 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 IsPerc(strString)
//  check for valid percentage strings	
{
   var strValidChars = "0123456789.";
   var strChar;
   var blnResult = true;

   if (strString.length == 0) return true;

   //  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 DuplicateTextbox(SourceBox, DestinationBox)
{
	var txtVal = document.getElementById(SourceBox).value
	if (txtVal.length != 0)
	{
		document.getElementById(DestinationBox).value = txtVal
	}
}

// *************************************************** KOBUS ADDED ***********************************************

function openLinkInCurrentWindow(url){
	try {
		window.location = url;
	}
	catch (ex){
		alert("Error : The URL '" + url + "' could not be loaded in this window. Reason :\n" + ex.message);
	}
}