/*
 * ajax.js
 * author: joel stevick
 * Copyright (c) 2007, CorData, Inc
 * Program Name: C.H.I.P. - CorData Hierarchical Inference Program
 */
/*
 * Call one of our web applications
 */
var ajax_sessionid = 0;
var ajax_sessionkey = '';
var Http_Request = null;
var Http_Request_async = null;

/*
 * Synchronous AJAX call
 */
function Ajax_Call_Web_Method(method, parameters)
{
	/*
	 * Add the session information to the ajax parameters
	 */
	parameters['ajax_sessionid'] = ajax_sessionid;
	parameters['ajax_sessionkey'] = ajax_sessionkey;
		
	/*
	 * Create the request object
	 */
	if (Http_Request == null)
		Http_Request = zXmlHttp.createRequest();
	else if (Http_Request.readyState != 0)
		Http_Request.abort();

	/*
	 * Serialize the calling parameters
	 */
	var serializedParameters = '';
	for (name in parameters) {
		serializedParameters += '&' + name + '=' + encodeURIComponent(parameters[name]);
	}
	
	var ok = true;
	do
	{
		ok = true;
		try
		{
			/*
			 * Do this synchronously
			 */
			Http_Request.open('POST', 'ajax.php?method=' + method, false);
			
			/*
			 * Create the HTTP request header so that we can submit form data
			 */
			Http_Request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		
			/*
			 * Execute the request now
			 */
			Http_Request.send(serializedParameters);
			
			if (Http_Request.status != 200) 
				throw Http_Request.statusText;
				
		} 
		catch (oException)
		{
			Http_Request.abort();

			if (confirm("Error connecting to CHIP.\r\nKeep trying?"))
				ok = false;	
			else
				return "";
				
		}
	} while (ok == false);

	/*
	 * Get the results XML
	 */
	var content = Http_Request.responseText.replace(/&lt;/g, '<');

	/*
	 * Decode special characters
	 */
	content = content.replace(/&gt;/g, '>');
	content = content.replace(/###gt###/g, '&gt;');
	content = content.replace(/###lt###/g, '&lt;');
	content = content.replace(/###amp###/g, '&amp;');
		
	/* 
	 * Extract script that should be executed
	 */
	if (content.indexOf('###EVAL=') >= 0) {
		var script = content.substr(content.indexOf('###EVAL=')+8);
		content = content.substr(0, content.indexOf('###EVAL='));
		script = script.replace(/\n/g, ' ');
		script = script.replace(/\r/g, ' ');
		eval(script);
	}
	return content;
}

/*
 * Hide/Display a please-wait DIV
 */
var Please_Wait_DIV = null;

var connectionTimer = null;

var saved_method = null;
var	saved_parameters = null;
var	saved_callerObject = null;
var alternateDisplayText = null;

function Display_Please_Wait_DIV(show)
{
	try
	{
		if (show) {
			/*
			 * Create the DIV if it does not already exist
			 */
			if (Please_Wait_DIV == null) {
				Please_Wait_DIV = document.createElement("div");
				Please_Wait_DIV.setAttribute('id', 'ajaxpleasewaitdiv');
	
				Please_Wait_DIV.innerHTML = alternateDisplayText == null ? "<nobr>Contacting CHIP...</nobr>" : alternateDisplayText;;
				
				Please_Wait_DIV.style.position='absolute';
				Please_Wait_DIV.style.top='300px';
				Please_Wait_DIV.style.left='300px';
				Please_Wait_DIV.style.zIndex = 10000;			
				Please_Wait_DIV.style.fontSize='8pt';
				Please_Wait_DIV.style.fontWeight= alternateDisplayText == null ? 'bold' : 'normal';
				Please_Wait_DIV.style.backgroundColor = alternateDisplayText == null ? 'white' : 'black';
				Please_Wait_DIV.style.color = alternateDisplayText == null ? 'black' : 'yellow';
				Please_Wait_DIV.style.borderColor = alternateDisplayText == null ? 'black' : 'red';
				Please_Wait_DIV.style.borderWidth = '1px';
				Please_Wait_DIV.style.borderStyle = 'solid';
				Please_Wait_DIV.style.padding='5px';

				var container = document.getElementById('ajaxcontainer');
				if (container)
					container.appendChild(Please_Wait_DIV);								
				
				/*
				 * If alternate display text provided, then show right away
				 */
				if (alternateDisplayText != null)
					Please_Wait_DIV.style.display='block';
			} else {
				Please_Wait_DIV.style.fontWeight= alternateDisplayText == null ? 'bold' : 'normal';
				Please_Wait_DIV.style.backgroundColor = alternateDisplayText == null ? 'white' : 'black';
				Please_Wait_DIV.style.color = alternateDisplayText == null ? 'black' : 'yellow';
				Please_Wait_DIV.style.borderColor = alternateDisplayText == null ? 'black' : 'red';

				if (retryInProgress) {
					/*
					 * Retry
					 */
					numberOfAttempts++;
					
					Please_Wait_DIV.innerHTML = '<nobr><font color=red>Connection timed out. Retrying CHIP [' + numberOfAttempts + ']</font></nobr>';
				} else {
					/*
					 * 1st attempt
					 */
					Please_Wait_DIV.innerHTML = alternateDisplayText == null ? "<nobr>Contacting CHIP...</nobr>" : alternateDisplayText;;
					
					numberOfAttempts = 0;
				}
				
				Please_Wait_DIV.style.display='block';
			}
			
			/*
			 * Create a connection timer
			 */
			var waitSeconds = retriesAllowed  ? 10 : 300;
			connectionTimer = setTimeout('Connection_Timer()', waitSeconds*1000);
			
		} else {
			/*
			 * Hide it
			 */
			Please_Wait_DIV.style.display='none';
			
			/*
			 * Clear the connection timer
			 */
			clearTimeout(connectionTimer);
			connectionTimer = null;
			
		}
	} 
	catch (ex)
	{
	}
}

/*
 * Connection timeout
 */
var tempHttp_Request_async;
var numberOfAttempts = 0;

var retriesAllowed = true;

function Connection_Timer()
{
	/*
	 * Schedule an abort for this connection
	 */
	tempHttp_Request_async = Http_Request_async;
	activeHttpRequest = null;

	setTimeout('tempHttp_Request_async.abort();', 500);	
	
	/*
	 * Clear the current connection object so that a new one will be allocated
	 */
	Http_Request_async = null;
	
	/*
	 * We are now in retry mode
	 */
	retryInProgress = true;
	
	/*
	 * Are retries permitted?
	 */
	if (retriesAllowed) {
		/*
		 * Re-execute the last request
		 */
		Ajax_Call_Web_Method_async(saved_method, saved_parameters, saved_callerObject, true);
	} else {
		/*
		 * Retries not allowed, abort this request
		 */
		retriesAllowed = true; // always reset this
		alternateDisplayText = null;
		
		saved_callerObject.results = ""; 
		saved_callerObject.timeoutAbort = true;
		saved_callerObject.AjaxCompletion(saved_callerObject);
		
		
	}
}

/*
 * Asynchronous AJAX call
 */
var Ajax_In_Use = false;
var retryInProgress = false;
var activeHttpRequest = null;
function Ajax_Call_Web_Method_async(method, parameters, callerObject, retry)
{
	/*
	 * If this is not a retry, then make sure the framework is not already in use
	 */
	if (retry != true) {
		/*
		 * Check for Ajax already in use (should never happen)
		 */
		if (Ajax_In_Use) {
			alert("Application is busy.  Please try again.");
			return;
		}
	}
	
	/*
	 * Save the parameters in case retry
	 */
	saved_method = method;
	saved_parameters = parameters;
	saved_callerObject = callerObject;
	
	/*
	 * Display the please-wait DIV
	 */
	Display_Please_Wait_DIV(true);

	/*
	 * Mark Ajax in use
	 */
	Ajax_In_Use = true;
	
	/*
	 * Clear the retry flag
	 */
	retryInProgress = false;
	
	/*
	 * Add the session information to the ajax parameters
	 */
	parameters['ajax_sessionid'] = ajax_sessionid;
	parameters['ajax_sessionkey'] = ajax_sessionkey;
		
	/*
	 * Create the request object
	 */
	if (Http_Request_async == null)
		Http_Request_async = zXmlHttp.createRequest();
	else if (Http_Request_async.readyState != 0)
		Http_Request_async.abort();

	activeHttpRequest = Http_Request_async;
	
	/*
	 * Serialize the calling parameters
	 */
	var serializedParameters = '';
	for (name in parameters) {
		serializedParameters += '&' + name + '=' + encodeURIComponent(parameters[name]);
	}
	
	try
	{
		/*
		 * Do this asynchronously
		 */
		Http_Request_async.open('POST', 'ajax.php?method=' + method, true);
		
		/*
		 * Create the HTTP request header so that we can submit form data
		 */
		Http_Request_async.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				
		/*
		 * Set up the completion handler
		 */
		Http_Request_async.onreadystatechange = function() {
			
			try {
				/*
				 * Request completed ?
				 */
				if (Http_Request_async.readyState == 4) {

					/*
					 * Yes, only process it if succeeded (connection timer will handle failures)
					 */
					if (Http_Request_async.status == 200 && Ajax_In_Use && activeHttpRequest == Http_Request_async) {
						/*
						 * Get the results (w/ decoding of LT characters)
						 */
						var content = Http_Request_async.responseText.replace(/&lt;/g, '<');
					
						/*
						 * Decode GT characters as well
						 */
						content = content.replace(/&gt;/g, '>');
						
						/*
						 * Decode other special characters
						 */
						content = content.replace(/###gt###/g, '&gt;');
						content = content.replace(/###lt###/g, '&lt;');
						content = content.replace(/###amp###/g, '&amp;');
							
						/* 
						 * Extract script that should be executed
						 */
						if (content.indexOf('###EVAL=') >= 0) {
							var script = content.substr(content.indexOf('###EVAL=')+8);
							content = content.substr(0, content.indexOf('###EVAL='));
							script = script.replace(/\n/g, ' ');
							script = script.replace(/\r/g, ' ');
							eval(script);
						}
										
						/*
						 * Mark Ajax available
						 */
						Ajax_In_Use = false;
						
						/*
						 * Close the please-wait DIV
						 */
						Display_Please_Wait_DIV(false);

						/*
						 * Always require the caller to explicitly disable retries
						 */
						retriesAllowed = true; 
						alternateDisplayText = null;

						/*
						 * Invoke the caller's completion function
						 */
						callerObject.results = content; 
						callerObject.AjaxCompletion(callerObject);
						
					} // End if not aborted 
					
				} // End if the communication to the server is completed
			}
			catch (ex)
			{
				/*
				 * Exception - don't do anything handled by timer
				 */
			}
		} // End ajax completion handler
		
		/*
		 * Execute the request now
		 */
		Http_Request_async.send(serializedParameters);

	} 
	catch (oException)
	{
		/*
		 * Exception, abort
		 */
		Http_Request_async.abort();

		/*
		 * Close the please-wait DIV
		 */
		Display_Please_Wait_DIV(false);
			
		/*
		 * Notify the user
		 */
		alert("Error connecting to CHIP.\r\nPlease try again");
		
		/*
		 * Mark Ajax available
		 */
		Ajax_In_Use = false;
		
		/*
		 * Always require the caller to explicitly disable retries
		 */
		retriesAllowed = true; 
		alternateDisplayText = null;

		/*
		 * Invoke the caller's completion function
		 */
		callerObject.results = '';
		callerObject.AjaxCompletion(callerObject);
			
	}

}
