// get dynamic data and return it. the data returned is passed to a function named after the field to finalize the formatting
// and display. 

//var lookupCallback = '';
var browserName=navigator.appName; 
var browserVer=parseInt(navigator.appVersion); 
var lookupObj = new Object();

//check the url for https, and use the secure version of the _cfscriptLookupLocation app
if (document.URL.substring(0,5) == 'https'){
	var _cfscriptLookupLocation_localRef = _cfscriptLookupLocation_secure;
}else{
	var _cfscriptLookupLocation_localRef = _cfscriptLookupLocation;
}


	///////////////////////////////////////////////////////////////////////////
	
	function getLookupData(fStruct,callback,getExtendedData)
	{
		/*
		params: fStruct 			= the object containing the lookup vars
			    callback 			= reference to the callback handler
				lookupremapArray	= remapfields array. This is a new feature which when it exists and 
									  is an array indicates that the CF template should return WDDX data.
									  Older versions of the form script will not pass this argument.
		*/
		// make sure the queue exists for this fieldname and if it does not create it now. The
		// queue is an array named after this fieldname and store in the global lookupObj var
		if (typeof(lookupObj[fStruct.fieldname]) != 'object'){
			lookupObj[fStruct.fieldname] = new Array();	
		}
		
		
		//show loading div if the lookupQueue is empty (nothing else processing)
		if (lookupObj[fStruct.fieldname].length == 0){
			createloadingDiv(fStruct.fieldname);
		}
		
		//create a unique id for this call (it will get passed to the cf function which will pass it back in the 2nd 
		// position of the returned array
		var uid = new Date().getTime() + '_' + fStruct.fieldname
		//add uid to the array
		//alert('adding task ('+uid+') to the lookupQueue. The lookup queue contains ' + lookupObj[fStruct.fieldname].length + 'items');
		lookupObj[fStruct.fieldname].push(uid);
		
		//showLoading('Requesting Saved Data from the Server','We are searching for previously saved form data.');
		DWREngine._errorHandler =  errorHandler;
		fStruct.fid = getFormName().fID.getValue();
		fStruct.hid = getFormName().Hid.getValue();
		fStruct.eid = getFormName().Eid.getValue();
		fStruct.eid2 = getFormName().Eid2.getValue();
		fStruct.uid = uid;
		// if lookupremapArray is an array, pass true to CF
		fStruct.getwddx = (typeof(getExtendedData) == 'object') ? true : false;
				
		//convert the object into a delimited string since it does not appear we can pass an object as an argument
		var argString = '';
		for (i in fStruct){
			//alert(i + ':' + fStruct[i]);
			if (argString != ''){
				var argString = argString + ',' + i + '|' + fStruct[i]
			}else{
				var argString = i + '|' + fStruct[i]
			}
		}

		DWREngine._execute(_cfscriptLookupLocation_localRef, null, 'getLookupData', argString, getLookupData_result);

	} 
	
	function getLookupData_result(result){
		//the results are an array of data and the first item in the array contains a reference
		// to the current fieldname. This is extracted and used to determin the name of the callback 
		// handler

		
		//convert returned wddx to an object
		if (result[result.length-1]['KEY'].indexOf('wddx') >= 0 && typeof(dpWDDX) == 'function'){
			
			// New: added July 13th 2009, to replace the line break character code <char code='0d'/><char code='0a'/>
			// to correctly format the returned data. For some reason the deserialize function was not doing this correctly
			try{
				var wddxpacket = result[result.length-1]['KEY'];
				var lineBreakRegEx = new RegExp("<char code='0d'/><char code='0a'/>", "g");
				wddxpacket = wddxpacket.replace(lineBreakRegEx,'\n');
				var fullArray  = dpWDDX('deserialize', wddxpacket)
			}catch(er){}
			
			//remove the serialized wddx and replace it with the serialized data 
			result.splice(result.length-1,1)
			result.push({VALUE:fullArray,KEY:'wddx'});
		}

		
		// The early positions of the returned array contain variables specific to the call that we are 
		// keeping track of. These contain the uid and the fieldname
		var fieldname = Trim(result[0]['KEY']);
		var curUid = Trim(result[1]['KEY']);
		var lookUpMode = Trim(result[2]['KEY']); 
		
		//alert('lookUpMode = ' + lookUpMode);
		//set the callback mode based on the current lookUpMode
		if (lookUpMode == 'onLoad'){
			lookUpMode = 'onloadResult';
		}else{
			lookUpMode = 'populate';	
		}
		
		//remove the first three items in the array
		result.splice(0,3);
			
			//alert('The current tasks id is ' + curUid + 'The last task in the array is ' + lookupObj[fStruct.fieldname][lookupObj[fStruct.fieldname].length-1]);
			
			// next, check if the curItem is the last item in the queue. if it is not, then no results
			// will be returned as another operation was initiated and those are the only results we 
			// care about in this release (TODO:review queue handling)

			if (lookupObj[fieldname][lookupObj[fieldname].length-1] != curUid){
				//alert('The current task is not the last task in the array, the array contains ' + lookupObj[fStruct.fieldname].length + ' tasks ');
				// there is another operation added to the queue after this one, so no data is returned.
				// remove item from the array
				for (var u=0; u < lookupObj[fieldname].length; u++){
					if (lookupObj[fieldname][u] == curUid){
						//alert('Task ' + curUid + ' removed');
						lookupObj[fieldname].splice(u,1);	
					}
				}
				
			}
			else
			{
			//alert('The current task is the last task in the array. The array has  ' + lookupObj[fStruct.fieldname].length + ' tasks ');
			//set the callback handler
			//alert('calling the callback in ' + lookUpMode + ' mode');
			var callback = eval('lookup_'+fieldname+'(result,lookUpMode)');
			//hide the loading message and show the hidden field
			lookup_showfield(eval('refto_' + fieldname));
			//destory the div
			//alert('div to remove is named ' + 'lookup_loading_'+fieldname+'_div');
			destroyLookUploader(document.getElementById("lookup_loading_"+fieldname+"_div"));
			
			// remove item from the queue
			for (var u=0; u < lookupObj[fieldname].length; u++){
				if (lookupObj[fieldname][u] == curUid){
					//alert('Task ' + curUid + ' removed');
					lookupObj[fieldname].splice(u,1);	
				}
			}
			
		}
		
	}
	 
	 	
	
	function createloadingDiv(fieldname){
		//create the loading div and return it
		var loadingDiv = createLookUploader(fieldname);
		//find the field element
		fieldmatch = getfieldObject(fieldname);		
		//append the div before the field and hide the field
		fieldmatch.parentNode.appendChild(loadingDiv) 		
		//hide the field			
		lookup_hidefield(fieldmatch);
		
		//store a reference to the fieldobject in a variable based
		//on the field name so the callback script can show the field
		var fieldRefVarName = 'refto_' + fieldname;
		eval(fieldRefVarName + ' = '  + ' fieldmatch');
	}
	 
	 function getfieldObject(fieldname){
		// find the field object. This method returns the correct field
		// regardless of the page it is on. the getElementByID() method
		// does not work since there is a hidden form with the same fieldnames
		var fielddiv = document.getElementById(fieldname+'field_div')
		//var fieldmatch = findChildInNode(fielddiv,fieldname)
		var fieldmatch = document.getElementById(fieldname)
		
		return fieldmatch;
	 }
	
	
	
	function createLookUploader(fieldname){
		
		var loadingdivname = "lookup_loading_"+fieldname+"_div";
		
		var docfrag=document.createDocumentFragment()
		//create the div
		mydiv=document.createElement("DIV")
		mydiv.setAttribute("id", loadingdivname)
		//create table
		tableObj = document.createElement("TABLE");
		tableObj.setAttribute("border", "0")
		tableObj.setAttribute("width", "200")
		tableObj.setAttribute("id", "lookup_loading_table")
		tbodyObj = document.createElement("TBODY");
		tr1Obj = document.createElement("TR");
		tr1td1Obj = document.createElement("TD");
		tr1td2Obj = document.createElement("TD");
		tr1td1Obj.setAttribute("valign", "middle")
		tr1td1Obj.setAttribute("width", "20")
		tr1td2Obj.setAttribute("valign", "middle")
		//create font
		fontObj = document.createElement("FONT");
		fontObj.setAttribute("face", "Arial, Helvetica, sans-serif")
		fontObj.setAttribute("size", "-1")
		//create image
		imgObj = document.createElement("IMG");
		imgObj.setAttribute("border", "0");
		imgObj.setAttribute("src", "/jsimages/loadingcircle.gif");
		//create text
		textObj = document.createTextNode("Loading Data...");
		
		//join the table together
		mydiv.appendChild(tableObj);
		tableObj.appendChild(tbodyObj);
		tbodyObj.appendChild(tr1Obj);
		tr1Obj.appendChild(tr1td1Obj);
		tr1Obj.appendChild(tr1td2Obj);
		tr1td1Obj.appendChild(imgObj);
		tr1td2Obj.appendChild(fontObj);
		fontObj.appendChild(textObj);
		
		// add the div and table to the document fragment
		docfrag.appendChild(mydiv)
	
	return docfrag;
	}


	function findChildInNode(node,childtofind){
		 
		 //alert('Running findChildInNow');	 
		 // loop over the node and check each child, if the child contains	 
		 for (var i = 0; i < node.childNodes.length; i++) {
			
			//alert('loop ' + i);
			// get the next child element
			n = node.childNodes[i];
			//first check if this node is our match
			 if (n.nodeType == 1) {
				  if (n.name) {  // named children
					if (n.name == childtofind){
						//match found, return it
						return n;
					}
				}
			}		
			
			//alert('no match for this node, check its children. It has ' + n.childNodes.length + 'children');
			// check if this node has children
			if (n.childNodes.length > 0){
				// this childnode has its own child node
				//alert('this childnode has its own child nodes, call the function recurivly');
				var recursiveresult = findChildInNode(n,childtofind);
				
				//alert('result returned from recurive function is ' + recursiveresult);
				if (typeof(recursiveresult) == 'object'){
					return recursiveresult;
				}
				
			}
		 }
		
		return '';
	}

	
	function destroyLookUploader(nodetoremove)
	{
	 	nodetoremove.parentNode.removeChild(nodetoremove);
	}

	
	
	
	///////////////////////////////////////////////////////////////////////////
	// HELPER FUNCTIONS
	
	//helper function to return form name (for single or multipage forms)
	function getFormName(){
		return logiform;
		/*
		//alert('running getFormName');
		// for multipage forms we need to update logi_hidden_form as opposed to 'logiform' for single page forms.
		if (typeof(logi_hidden_form) != 'undefined'){
			//alert('returning logi_hidden_form ' + logi_hidden_form)
			return logi_hidden_form;
				}else{
			//alert('returning logiform ' + logiform)
			return logiform;
		}
		*/
	}

	function Trim(STRING){
		STRING = LTrim(STRING);
		return RTrim(STRING);
	}
	
	function RTrim(STRING){
		while(STRING.charAt((STRING.length -1))==" "){
		STRING = STRING.substring(0,STRING.length-1);
		}
		return STRING;
	}
	
	
	function LTrim(STRING){
		while(STRING.charAt(0)==" "){
		STRING = STRING.replace(STRING.charAt(0),"");
		}
		return STRING;
	}

	
	function getInternetExplorerVersion()
		// Returns the version of Internet Explorer or a -1
		// (indicating the use of another browser).
		{
		  var rv = -1; // Return value assumes failure
		  if (navigator.appName == 'Microsoft Internet Explorer')
		  {
			var ua = navigator.userAgent;
			var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
			if (re.exec(ua) != null)
			  rv = parseFloat( RegExp.$1 );
		  }
		  return rv;
		}
	
	function lookup_hidefield(fieldobj)
	{
		//hide the field while loading data
		if (fieldobj.type == "select-one")
		{
			fieldobj.style.display = 'none';
		}
	}


	function  lookup_showfield(fieldobj)
	{
		//hide the field while loading data
		if (fieldobj.type == "select-one")
		{
			fieldobj.style.display = 'inline';
		}
	}