var gHttpError = false;
var gIsCharsOK = new Array();
 
// Character Validation global arrays
var gCVObj;
var gCVMsk;
var gCVIdx;


//this is the original http get request that does not allow for caching
function httpRequest(responseFunction, encodedAction, lockPage, parmString) {
	httpGetRequest(responseFunction, encodedAction, lockPage, parmString, true);
}

//this is a http get request that will allow for caching
function httpRequestCache(responseFunction, encodedAction, lockPage, parmString) {
	httpGetRequest(responseFunction, encodedAction, lockPage, parmString, false);	
}

function httpGetRequest(responseFunction, encodedAction, lockPage, parmString, timeStamp) {
	try {
		xmlDoc= getXmlObj(responseFunction);
		if (xmlDoc==null) throw "";
		// Set URL
		var url = encodedAction + "?httpRequest=true";
		//if time is set each time then the request cannot be cached reliably
		if (timeStamp) {
			url = url + "&x=" + new Date().getTime();
		}
		if (parmString!=null) url = url + "&" + parmString;

		// Check if to lock the page
		if (lockPage==null) lockPage = false;
		if(lockPage)document.body.style.cursor = 'progress';
        xmlDoc.open("GET", url, !lockPage);
        xmlDoc.setRequestHeader("Content-type", "text/html;charset=UTF-8");
		xmlDoc.send(null);
	 } catch (e) {	
	 	if (typeof parent.gErrorActiveX != 'undefined')
		 	alert(parent.gErrorActiveX); 
	 }	
}

function httpResponded(response) {
	if (typeof window.ActiveXObject != 'undefined')
		if (xmlDoc.readyState != 4) return false;

	//	if (xmlDoc.status == 500) return false; // server error
	document.body.style.cursor = 'auto';
	return true;
}

function getHttpResponseString() {
	return xmlDoc.responseText;
}

function getHttpResponseStatus() {
	return xmlDoc.status;
}

function getXmlObj(responseFunction) {
	try {
		var xmlObj=null;
		if (typeof window.ActiveXObject != 'undefined') {
        	try {
	       		xmlObj = new ActiveXObject("Msxml2.XMLHTTP");
        	} catch (e) {
          		xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
         	}
 			if (xmlObj && responseFunction) xmlObj.onreadystatechange = responseFunction;
		} else if (window.XMLHttpRequest) { // Mozilla, Safari,...
        		xmlObj = new XMLHttpRequest();
				if (xmlObj && responseFunction) xmlObj.onload = responseFunction;
	   	}
	   	return xmlObj;
	} catch (e) {
		return null;
	}	
}

// ****************************************************************************
// Call an Action class with a parameters string by executing an HTTP POST.
// A string is returned by the Action, this is retrieved by calling 
// the function getHttpPostResponseString().
// Parameters in: 
//   responseFunction		callback function
//   encodedAction			Action class to process HTTP POST request
//   lockPage				true if current web page should be locked
//   parmString				Parameter string passed to the Action class
// Return: -
//   boolean				true if successful
// ****************************************************************************
function httpPostRequest(responseFunction, encodedAction, lockPage, parmString) {

	xmlDoc=getXmlObj(responseFunction);
	if (xmlDoc==null) {
	 	alert(parent.gErrorActiveX);
	 	return false; 
	}	

	try {
		// Set URL
		var url = encodedAction + "?httpRequest=true&x=" + new Date().getTime();

		// Check if to lock the page
		if (lockPage==null) lockPage = false;

		// Execute Request
		xmlDoc.open("POST", url, !lockPage);
	    xmlDoc.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	    xmlDoc.setRequestHeader("Content-length", parmString.length);
      	xmlDoc.setRequestHeader("Connection", "close");
      	// Just in case the MS XMLHTTP object didn't hear us the first time...
      	xmlDoc.setRequestHeader("Connection", "close");
		xmlDoc.send(parmString);
		return true;	
	} catch (e) {
		// Ignore first error only to allow for a single retry
		// NOTE: status 12030 returned occassionally from the server.
		if (gHttpError) {
			gHttpError = false;
		 	if (typeof parent.gErrorActiveX != 'undefined')
		 		alert(parent.gErrorActiveX); 
		} else {
			gHttpError = true;
		}
		// return true if 1st error and retry required 
		return gHttpError;	
	}
}

function httpPostResponded() {
	// IE
	if (typeof window.ActiveXObject != 'undefined') {
		if (xmlDoc.readyState == 4) {
			if (xmlDoc.status==0 || xmlDoc.status == 200) return true;
		}
	} else {
		// Mozilla, Safari,...
		if (xmlDoc.status==0 || xmlDoc.status == 200) return true;
	}
	return false;
}

function getHttpPostResponseString() {
	gHttpError = false;
	return xmlDoc.responseText;
}

// ****************************************************************************
// Clear arrays ready for character validation
// ****************************************************************************
function clearReadyForCharacterValidation() {
	gCVObj = new Array();
	gCVMsk = new Array();
	gCVIdx = 0;
}

// ****************************************************************************
// Load the object into array for character validation
// Parameters in: 
//   obj		web page field
//   mask		optional, mask string (containing restricted special characters)
// ****************************************************************************
function loadForCharacterValidation(obj, mask) {

	// If web field has been entered, load into next array element
	if (obj && !isEmpty(obj.value)) {
		gCVObj[gCVIdx] = obj;
		
		if (mask && !isEmpty(mask)) {
			gCVMsk[gCVIdx] = mask;
		} else {
			gCVMsk[gCVIdx] = null;
		}
		gCVIdx++;
	}

}

// ****************************************************************************
// Validate characters to ensure they are 
// able to be stored in AS400 alphanumeric name fields.
// Return: -
//   boolean		true if validation ok
// ****************************************************************************
function isCharacterValidationOK() {
	var hasActiveX= (getXmlObj()!=null) && (typeof encodeURI!='undefined');
	var maskAND = "/&/";
	var mask, checkAND, pos;

	//setup error message and action
	var action=parent.gValidateCharsAction;
	var vldChrErr;
	if (!action) {
		action = opener.parent.gValidateCharsAction;
		vldChrErr = opener.parent.gValidateCharsMsg;
	} else {
		vldChrErr = parent.gValidateCharsMsg;
	}

	var allInputs = "";

	// No validation required, return ok
	if (gCVObj.length == 0) return true;

	// Loop through each input field...
	for (idx=0; idx<gCVObj.length; idx++){

		if (gCVObj[idx].value!=null) {
			var source = gCVObj[idx].value;
			allInputs += source;

			// If required, ensure invalid characters are not entered
			if (gCVMsk[idx]!=null && gCVMsk[idx].length>0) {
				mask = gCVMsk[idx];
				checkAND = !eval(maskAND).test(mask);
			} else {
				mask = maskAND;
				checkAND = false;
			}
			
			//not to be confused with pattern matching.  
			//Check for invalid characters only, no need to loop through whole string
			pos = source.search(eval(mask));
			if (pos>-1) {
				alert(vldChrErr + " " + source.substring(pos,pos+1));
				gCVObj[idx].focus();
				return false;
			}

			//do we need to check for ampersand
			if (checkAND) {
				pos = source.search(eval(maskAND));
				if (pos>-1) {
					alert(vldChrErr + " " + source.substring(pos,pos+1));
					gCVObj[idx].focus();
					return false;
				}
			}
			
			// If activeX is off then check basic character validation
			if (!hasActiveX && !validChar(gCVObj[idx])) return false;
		}
		if (idx<gCVObj.length-1) {
			allInputs += " |";
		}
	}

	//if activeX is off return, no point carrying on
	if (!hasActiveX) return true;
	
	// Send concatenated fields to server for validation...
	gIsCharsOK = new Array();
	gHttpError = false; // switch off - report 1st error
	
	var parmString = "fields=" + encodeURI(allInputs);
	if (httpPostRequest(processValidateCharacters, action, true, parmString)) {;
		// If connection problem, retry once again...
		if (gIsCharsOK.length==0) {
			httpPostRequest(processValidateCharacters, action, true, parmString);
		}
	}

	// Error already reported if gIsCharsOK is empty... so return false
	if (gIsCharsOK.length == 0) return false;

	// Check for any web object with invalid characters..
	for (var idx= 0; idx< gIsCharsOK.length; idx++) {
		if (gIsCharsOK[idx]=="false") {
			// .. if invalid, display invalid characters
			var obj = gCVObj[idx];
			if (obj) {
				alert(vldChrErr + " " + obj.value);
				obj.focus();
			} else {
				alert(vldChrErr);
			}
			return false;
		}
	}

	// All characters ok, return true
	return true;
}

// Process HTTP response for character validation
function processValidateCharacters() {
	if (httpPostResponded()) {
		gIsCharsOK = getHttpPostResponseString().split("|");
	}
}

function validChar(obj) { 
var len = obj.value.length;
// char(33) = !, characters before this are control codes, they are not stored correctly on file
// this code is standard ascii including symbols and some accented characters, these can be entered on the green screen
	for (i=0;i<len;i++) {
		if (!isEmpty(obj.value.charAt(i)) && (obj.value.charCodeAt(i) < 33 || obj.value.charCodeAt(i) > 255)) {
			//setup error message
			var vldChrErr;
			if (opener) {
				vldChrErr = opener.parent.gValidateCharsMsg;
			} else {
				vldChrErr = parent.gValidateCharsMsg;
			}
			alert(vldChrErr + " " +obj.value.charAt(i));
			obj.focus();
			return false;
	 	}
	 }
	return true;
}