/*

Progress window overlay based on local or remote input
js progress cycle object
Test upload and download of files (jpg, etc...)
get class instance name automatically for manage_Cache()

connect to other ports

//application helpers
Form send method (to only send data, not change page)
Window handler, moveable
Message window
Error window
Strip string class (with regex???) for js
field by field sender like flash
login and perm handler
Help window
Timer queue (like in flash) to check for actions to do
Data binding (data provider) for elements
Other gui and data functions
Iframe content handler

Apps:
graffiti wall
chat client
*/

/**
	phAtJAX - Robust and independent AJAX client
	
	@author	Brian Grayless
			Copyright 2000-2005 (c) Sunergize Inc.
			Visit http://www.sunergize.com
 	 				
 	@license	This library is free software; you can redistribute it and/or
			modify it under the terms of the GNU Lesser General Public
			License as published by the Free Software Foundation; either
			version 2.1 of the License, or (at your option) any later version.
			
			This library is distributed in the hope that it will be useful,
			but WITHOUT ANY WARRANTY; without even the implied warranty of
			MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
			Lesser General Public License for more details.
			
			If you did not receive a copy of the GNU Lesser General Public
			License along with this library, write to the Free Software
			Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
function Phatjax(service_url, request_type, response_type, debug, js_debug_inst)
{
	// check for debug mode and setup debug class
	switch(true)
	{
		case (!debug || (debug == false) || (debug === 0) || (debug === 'undefined')):
			this.debug = true;
			this.debug_mode = 1;
			break;
		case ((debug == true) || (debug === 0)):
			this.debug_mode = 1;
			this.debug = true;
			break;
		case (debug > 1):
			this.debug_mode = debug;
			this.debug = true;
			break;
		default:
			this.debug = false;
			this.debug_mode = 0;
			break;
	}
	// set debug console
	if(js_debug_inst && this.debug)
	{
		this.js_debug = js_debug_inst;
	}
	else
	{
		if (this.debug) {
			try
			{
				//this.js_debug = new Js_Debug(this.debug);
				this.js_debug = new Js_Debug(this.debug_mode);
			}
			catch(e)
			{
				this.debug = false;
				alert('Debug is turned on, but Js_Debug class is not available.\n\nTurning debug off.');
			}
		}
	}
	
	// get browser info
	try
	{
		this.browser_info = new Browser_Info();
	}
	catch(e)
	{
		alert('Unable to load Browser Info class.');
	}
	
	// url regex parts for easy changes, use debug to see full string
	var protocol_check = '(http(s)?://)?';
	var domain_check = '[a-zA-Z0-9.-]+';
	var ip_check = '([0-9]{1,3}\.){3}[0-9]{1,3}';
	var port_check = '(:[0-9]+)?';
	var filepath_check = '([-/a-zA-Z0-9.?_=&+~]+)?';
	
	var url_regex_string = "^" + protocol_check + "((" + domain_check + "|" + ip_check + ")" + port_check + ")?" + filepath_check + "$";
	this._debug_out('url regex: ' + url_regex_string);
	this.url_regex = new RegExp(url_regex_string, "i");
	try
	{
		this.url_regex.compile(url_regex_string, "i");
	}
	catch(e)
	{
		this._debug_out('url regex did not compile: ' + e, 'warning');	
	}
	this.service_url = this._url_Check(service_url);
	
	this.request_type = this._request_Type_Check(request_type);
	
	this.response_type = this._response_Type_Check(response_type);
	
	// prefix used with sent vars
	this.var_prefix = '';
	
	// set server calls to array
	this.registered_calls = new Array();
	// class that contains responder methods, if set to class
	this.responder_class = '';
	// calls in queue
	this.call_queue = new Array();
	// calls to cache data for
	this.cache_queue = new Array();
	// set clear cache timer
	this.clear_cache_timer = null;
	// minute interval to clear cache
	this.clear_cache_minutes = null;
	
	return true;
};

Phatjax.prototype.register_Call = function(function_name, response_type, cache_minutes, stream)
{
	this._debug_out('register_Call(' + function_name + ', ' + response_type + ', ' + cache_minutes + ', ' + stream + ') calling register_Call_To()');
	
	this.register_Call_To(this.service_url, this.request_type, function_name, response_type, cache_minutes, stream);
	
	return true;
};

Phatjax.prototype.register_Call_To = function(serv_url, r_type, function_name, response_type, cache_minutes, stream)
{
	this._debug_out('register_Call_To(' + serv_url +', ' + r_type + ', ' + function_name + ', ' + response_type + ', ' + cache_minutes + ', ' + stream + ')');
	
	if(!this.call_Registered(function_name))
	{
		var resp_type = this._response_Type_Check(response_type);
		var pj_inst = this;
		// build function dynamically that calls server function
		var eval_string = function_name + ' = function(){var unique_id = "' + function_name + '" + new Date().getTime(); pj_inst._call("' + serv_url + '", "' + r_type + '", "' + function_name + '", "' + resp_type + '", ' + stream + ', unique_id, ' + function_name + '.arguments); return unique_id;}; ';
		try
		{
			eval(eval_string);
			this.registered_calls[this.registered_calls.length] = function_name;
			
			// if cache time is set, add to cache queue
			if(cache_minutes && (cache_minutes > 0))
			{
				this._add_To_Cache_Queue(function_name, cache_minutes);	
			}
		}
		catch(e)
		{
			this._debug_out('unable to register call: ' + e, 'error');	
		}	
	}
	else
	{
		this._debug_out('function by this name already registered: ' + function_name, 'error');
	}
	
	return true;
};

Phatjax.prototype.registered_Calls = function()
{
	this._debug_out('registered_Calls()');
	
	return this.registered_calls;
};

Phatjax.prototype.call_Registered = function(function_name)
{	
	this._debug_out('call_Registered(' + function_name + ')');
	
	var call_found = false;
	
	var reg_calls_length = this.registered_calls.length;
	for(var i = 0; i < reg_calls_length; i++)
	{
		if(function_name == this.registered_calls[i])
		{
			call_found = true;
		
			continue;
		}
	}
	
	return call_found;
};

Phatjax.prototype.set_Responder_Class = function(responder_class_name)
{
	this._debug_out('set_Responder_Class(' + responder_class_name + ')');
	
	this.responder_class = responder_class_name + '.';
	
	return true;
};

Phatjax.prototype.abort_Call = function(unique_call_id, iteration)
{
	this._debug_out('abort_Call(' + unique_call_id + ', ' + iteration + ')');
	
	var aborted = false;
	
	if(!iteration)
	{
		iteration = 1;	
	}
	else
	{
		iteration++;	
	}
	
	for(var i = 0; i < this.call_queue.length; i++)
	{
		// if found call
		if(this.call_queue[i].unique_call_id == unique_call_id)
		{
			// if running, kill it
			if(this.call_queue[i].call_instance.readyState < 4)
			{
				try
				{
					this.call_queue[i].call_instance.abort();
					
					aborted = true;
					this._debug_out('aborted call: ' + e, 'warning');
				}
				catch(e)
				{
					this._debug_out('unable to abort call: ' + e, 'warning');	
				}
			}
			
			// delete obj instance
			try
			{
				this.call_queue.splice(i, 1);
				aborted = true;
				this._debug_out('removed call from queue: ' + unique_call_id);
			}
			catch(e)
			{
				aborted = false;
				this._debug_out('unable to delete call instance from queue. ' + e, 'warning');
				
				// attempt recursive delete until sucessful or until 10th try (because indexes may shift during asynchronous splicing)
				if(iteration < 11)
				{
					aborted = this.abort_Call(unique_call_id, iteration);
				}
			}
			break;	
		}		
	}
	
	return aborted;
};

Phatjax.prototype.call_Queue = function()
{
	this._debug_out('call_Queue()');
	
	var r_calls = new Array();
	
	for(var i = 0; i < this.call_queue.length; i++)
	{
		r_calls[i] = this.call_queue[i].unique_call_id;		
	}
	
	return r_calls;
};

Phatjax.prototype.call_In_Queue = function(unique_call_id)
{
	this._debug_out('call_In_Queue(' + unique_call_id + ')');
	
	var is_running = false;
	
	for(var i = 0; i < this.call_queue.length; i++)
	{
		if((this.call_queue[i].unique_call_id == unique_call_id) && (this.call_queue[i].call_instance.readyState < 4))
		{
			is_running = true;
			break;	
		}		
	}
	
	return is_running;
};

Phatjax.prototype.manage_Cache = function(minutes, pj_inst_name)
{
	this._debug_out('manage_Cache(' + minutes + ', ' + pj_inst_name + ')');
	if(!minutes)
	{
		minutes = 60;	
	}
	this.clear_cache_minutes = minutes;

	var clear_int = (this.clear_cache_minutes * 60) * 1000;
	this.clear_cache_timer = setInterval(pj_inst_name + "._clear_Unused_Cache()", clear_int);
};

Phatjax.prototype.unmanage_Cache = function()
{
	this._debug_out('unmanage_Cache()');
	
	if(this.clear_cache_timer != null)
	{
		clearInterval(this.clear_cache_timer);
		this.clear_cache_timer = null;
	}
};

Phatjax.prototype.pairs_To_Vars = function(name_value_pair_string)
{
	var vars = new Object();
	
	// if found &
	if(name_value_pair_string.indexOf('&') > -1)
	{
		// split by &
		var pair_array = name_value_pair_string.split('&');
		
		
		// loop over the tag pairs
		var pair_array_length = pair_array.length;
		for(var i = 0; i < pair_array_length; i++)
		{
			if(pair_array[i].indexOf('=') > -1)
			{
				var name_value_pair = pair_array[i].split('=');
				eval('vars.' + name_value_pair[0] + ' = unescape(name_value_pair[1]); ');
			}
		}
	}
	
	return vars;
};

Phatjax.prototype.xml_To_Object = function(xml_string)
{
	var xml_obj = null;
	
	try
	{
		var xml_trans = new Xml_Object_Transform(this.debug, this.js_debug);
		
		try
		{
			xml_obj = xml_trans.xml_To_Object(xml_string);
		}
		catch(e)
		{
			this._debug_out('possible malformed xml: ' + e, 'error');
		}
	}
	catch(e)
	{
		this._debug_out('unable to instantiate XML to object transformer: ' + e, 'error');	
	}
		
	return xml_obj;
};

Phatjax.prototype.set_Var_Prefix = function(prefix)
{
	this._debug_out('set_Var_Prefix(' + prefix + ')');
	
	if(prefix.length > 0)
	{
		prefix += '_';	
	}
	
	this.var_prefix = prefix;
	
	return true;
};

Phatjax.prototype._init = function()
{
	this._debug_out('_init()');
	
	var conn_handle;
	try
	{
		conn_handle = new ActiveXObject('Msxml2.XMLHTTP');
	}
	catch(e)
	{
		this._debug_out('Unable to connect to given XMLHttp object. ' + e + ': trying another...', 'warning');
		
		try
		{
			conn_handle = new ActiveXObject('Microsoft.XMLHTTP');
		}
		catch(ec)
		{
			conn_handle = null;
			this._debug_out('Unable to connect to given XMLHttp object. ' + ec + ': trying another...', 'warning');
		}
	}
	if(!conn_handle && typeof XMLHttpRequest != 'undefined')
	{
		try
		{
			conn_handle = new XMLHttpRequest();
		}
		catch(e)
		{
			conn_handle = null;
			this._debug_out('Unable to connect to given XMLHttp object. ' + e, 'warning');
		}
	}
	if(!conn_handle)
	{
		this._debug_out('Unable to connect.', 'error');
	}
	
	return conn_handle;
};

Phatjax.prototype._call = function(serv_url, r_type, function_name, response_type, stream, unique_call_id, args)
{
	this._debug_out('_call(' + serv_url + ', ' + r_type + ', ' + function_name + ', ' + response_type + ', ' + stream + ', ' + unique_call_id + ', [args])');
	
	// call is not cached, continue
	if(!this._call_Cached(function_name))
	{
		var service_url = null;
		var request_type = null;
		var request_data;
		
		if(serv_url != this.service_url)
		{
			service_url = this._url_Check(serv_url);
		}
		else
		{
			service_url = this.service_url;	
		}
		request_type = this._request_Type_Check(r_type);
		
		// verify service and request type before trying service
		if(service_url && (service_url == 'null') || request_type && (request_type == 'null'))
		{
			request_type = (request_type != null) ? request_type : 'none';
			service_url = (service_url != null) ? service_url : 'none';
			
			this._debug_out('Service: METHOD: "' + request_type + '" URL: "' + service_url + '" is not properly defined.', 'error');
		}
		else
		{
			// build data strings
			if(request_type == 'GET')
			{
				if(service_url.indexOf('?') == -1)
				{ 
					service_url += '?' + this.var_prefix + 'call=' + escape(function_name);
				}
				else
				{
					service_url += '&' + this.var_prefix + 'call=' + escape(function_name);
				}
				for(var i = 0; i < args.length; i++)
				{
					service_url += '&' + this.var_prefix + 'call_args[]=' + escape(args[i]);
				}
				service_url += '&' + this.var_prefix + 'resp_type=' + response_type;
				if(this.debug)
				{
					service_url += '&' + this.var_prefix + 'debug=1';
				}
				if(stream && (stream == true))
				{
					service_url += '&' + this.var_prefix + 'stream=1';
				}
				service_url += '&' + this.var_prefix + 'rnd=' + new Date().getTime();
				request_data = null;
			}
			else
			{
				request_data = this.var_prefix + 'call=' + escape(function_name);
				for(var i = 0; i < args.length; i++)
				{
					request_data += '&' + this.var_prefix + 'call_args[]=' + escape(args[i]);
				}
				request_data += '&' + this.var_prefix + 'resp_type=' + response_type;
				if(this.debug)
				{
					request_data += '&' + this.var_prefix + 'debug=1';
				}
				if(stream && (stream == true))
				{
					request_data += '&' + this.var_prefix + 'stream=1';
				}
				request_data += '&' + this.var_prefix + 'rnd=' + new Date().getTime();
			}
			
			var a = this._init();
			
			// add call to queue
			var call_queue_length = this.call_queue.length;
			this.call_queue[call_queue_length] = new Object();
			this.call_queue[call_queue_length].unique_call_id = unique_call_id;
			this.call_queue[call_queue_length].call_instance = a;
					
			try
			{
				a.open(request_type, service_url, true);
				if(request_type == 'POST')
				{
					a.setRequestHeader('Method', 'POST ' + service_url + ' HTTP/1.1');
					a.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
				}
				
				if(stream && (stream == true))
				{
					var ready_state = 3;	
				}
				else
				{
					var ready_state = 4;	
				}
				
				// safari doesn't support streaming
				if((this.browser_info.get_Name() == 'Safari') || (this.browser_info.get_Name() == 'Internet Explorer'))
				{
					ready_state = 4;
				}
				
				// set instance of self to be used by external functions
				var pj_inst = this;
				a.onreadystatechange = function()
				{
					var keep_processing = true;
					
					pj_inst._debug_out('ready state: ' + a.readyState);
	
					// if in wrong state or page load is not successful, end processing
					if(a.readyState != ready_state) 
					{
						keep_processing = false;
					}
					else if(a.status && (a.status != 200))
					{
						switch(a.status)
						{
							case 404:
								pj_inst._debug_out('page status: 404 - page not found', 'error');
								break;
						}
	
						return;
					}
					
					// no reason to return, keep going
					if(keep_processing)
					{
						var status;
						var data;
						var debug;
						var stream_in_parts = false;
						
						var status_start = 0;
						var data_start = 2;
						// streaming part delimiter
						var stream_break = '::BREAK::';
						// string that marks server debug to end
						var debug_marker = '::DEBUG::';
						var debug_marker_pos = a.responseText.lastIndexOf(debug_marker);
						debug_marker_pos = (debug_marker_pos < 0) ? a.responseText.length : debug_marker_pos;
						
						status = a.responseText.charAt(status_start);
	
						// safari doesn't support streaming
						if((pj_inst.browser_info.get_Name() != 'Safari') && (pj_inst.browser_info.get_Name() != 'Internet Explorer'))
						{
							// if found break, process only latest data
							if(a.responseText.lastIndexOf(stream_break) > -1)
							{
								// start data after last break
								stream_in_parts = true;
								data_start = a.responseText.lastIndexOf(stream_break) + stream_break.length;
							}
						}
	
						// if not stream, or stream but not at end yet, set data
						if(!stream_in_parts || (stream_in_parts && (a.responseText.indexOf(debug_marker) < 0)))
						{
							data = a.responseText.substring(data_start, debug_marker_pos);
						}
	
						// strip stream breaks for Safari
						if((pj_inst.browser_info.get_Name() == 'Safari') || (pj_inst.browser_info.get_Name() == 'Internet Explorer'))
						{
							data = data.split(stream_break).join('');
						}
	
						// get debug after marker
						debug = a.responseText.substring(debug_marker_pos + debug_marker.length);
						
						pj_inst._debug_out('received:<br />STATUS: ' + status +  '<br />DATA: ' + pj_inst._show_Html(data));
	
						// output debug
						if(debug.length > 0)
						{
							pj_inst._debug_out('<div style="margin-top: 5px; text-align: center; color: #ff0000; border: dotted 1px #ff0000;">SERVER DEBUG INFO</div><div style="margin-bottom: 5px; border: dotted 1px #ff0000; padding: 5px;">' + debug + '</div>');
						}
		
						if(status == '0')
						{
							pj_inst._debug_out(data, 'error');
						}
						else if(status == '1')
						{
							switch(response_type)
							{
								case 'xml':
									if((data.indexOf('<') == 0) && (data.indexOf('</') > 0))
									{
										data = pj_inst.xml_To_Object(data);
									}
									else
									{
										pj_inst._debug_out('data cannot be determined to be xml.', 'error');		
									}
									break;
								case 'pairs':
									if(data.indexOf('=') > 0)
									{
										data = pj_inst.pairs_To_Vars(data);
									}
									else
									{
										pj_inst._debug_out('data cannot be determined to be name-value pairs.', 'error');		
									}
									break;
								case 'b64':
									try
									{
										data = atob(data);
									}
									catch(e)
									{
										pj_inst._debug_out('data cannot be determined to be bas64-encoded. Returning as string.', 'error');	
									}
									break;
								case 'string':
								default:
									break;
							}
	
							if(data)
							{
								try
								{
									// call response function
									var response_function = pj_inst.responder_class + function_name + '_Response';
									pj_inst._debug_out('calling responder function: ' + response_function);
									var eval_func = response_function + '(data); ';
									eval(eval_func);
									
									// send data to cache
									try
									{
										pj_inst._cache_Data(function_name, data);
									}
									catch(e)
									{
										pj_inst._debug_out('unable to cache data for call: ' + function_name);
									}
	
									// if NOT in stream mode, abort here
									if(a.readyState == 4)
									{
										try
										{
											pj_inst.abort_Call(unique_call_id);
										}
										catch(e)
										{
											pj_inst._debug_out('unable to remove call from queue "' + unique_call_id + '" from array: ' + e, 'warning');	
										}	
									}
								}
								catch(e)
								{
									pj_inst._debug_out('please verify <b>' + response_function + '</b> exists: ' + e, 'error');	
								}
							}
						}
						else
						{
							pj_inst._debug_out('data received does not contain proper status and is unexpected.', 'warning');	
						}
					}
					else
					{
						// if in stream mode, abort here
						// call is done, abort
						if(a.readyState == 4)
						{
							try
							{
								pj_inst.abort_Call(unique_call_id);
							}
							catch(e)
							{
								pj_inst._debug_out('unable to remove call from queue "' + unique_call_id + '" from array: ' + e, 'warning');	
							}	
						}
					}
				};
				
				try
				{	
					a.send(request_data);
					
					this._debug_out(function_name + ' uri = ' + service_url + '/post = ' + request_data);
					this._debug_out(function_name + ' response pending...');
				}
				catch(e)
				{
					this._debug_out(e, 'error');
				}
			}
			catch(e)
			{
				this._debug_out(e, 'error');
			}
		}
	}
	else
	{
		this._debug_out('Call ' + function_name + ' is already cached. Getting local data.');
		
		var data = this._get_Cached_Data(function_name);
		
		// if data contains something, run local responder
		if(data != null)
		{
			// call response function
			var response_function = this.responder_class + function_name + '_Response';
			this._debug_out('calling responder function: ' + response_function + ' with cached data.');
			var eval_func = response_function + '(data); ';
			try
			{
				eval(eval_func);
			}
			catch(e)
			{
				this._debug_out('unable to call responder function: ' + response_function + ' with cached data.');
			}
		}
	}
};

Phatjax.prototype._add_To_Cache_Queue = function(call_name, cache_minutes)
{	
	this._debug_out('_add_To_Cache_Queue(' + call_name + ', ' + cache_minutes + ')');

	if(cache_minutes > 0)
	{
		// check for call in cache queue
		var call_cached = false;
		for(var i = 0; i < this.cache_queue.length; i++)
		{
			if(this.cache_queue[i].call == call_name)
			{
				call_cached = true;
				break;	
			}		
		}
		// if not found, add to queue
		if(!call_cached)
		{
			var cq_len = this.cache_queue.length;
			this.cache_queue[cq_len] = new Object();
			this.cache_queue[cq_len].call = call_name;
			this.cache_queue[cq_len].cache_span = Math.round(cache_minutes);
			this.cache_queue[cq_len].last_return = null;
			this.cache_queue[cq_len].data = null;
		}
	}
};

Phatjax.prototype._call_Cached = function(call_name)
{
	this._debug_out('_call_Cached(' + call_name + ')');
	
	var call_cached = false;
	// find call
	var found_call = false;
	var call_id = null;
	for(var i = 0; i < this.cache_queue.length; i++)
	{
		if(this.cache_queue[i].call == call_name)
		{
			found_call = true;
			call_id = i;
			break;	
		}		
	}
	
	// check call span expiration
	if(found_call && (call_id != null))
	{
		// if cache is not expired, do not continue call
		var last_return = this.cache_queue[call_id].last_return;
		// turn into milliseconds
		var cache_span_secs = (this.cache_queue[call_id].cache_span * 60) * 1000;
		
		if(last_return != null)
		{
			// if cache time has not passed
			if(new Date().getTime() < (last_return + cache_span_secs))
			{
				call_cached = true;
			}
		}
	}
	
	return call_cached;
};

Phatjax.prototype._get_Cached_Data = function(call_name)
{
	this._debug_out('_get_Cached_Data(' + call_name + ')');
	
	var data = null;
	
	for(var i = 0; i < this.cache_queue.length; i++)
	{
		if(this.cache_queue[i].call == call_name)
		{
			data = this.cache_queue[i].data;
			break;	
		}		
	}
	
	return data;
};

Phatjax.prototype._cache_Data = function(call_name, data)
{
	this._debug_out('_cache_Data(' + call_name + ', [data])');
	
	for(var i = 0; i < this.cache_queue.length; i++)
	{
		if(this.cache_queue[i].call == call_name)
		{
			this.cache_queue[i].data = data;
			this.cache_queue[i].last_return = new Date().getTime();
			break;	
		}		
	}
};

Phatjax.prototype._clear_Unused_Cache = function()
{
	var clear_int = (this.clear_cache_minutes * 60) * 1000;
	for(var i = 0; i < this.cache_queue.length; i++)
	{
		var last_return = this.cache_queue[i].last_return;
		// turn into milliseconds
		var cache_span_secs = (this.cache_queue[i].cache_span * 60) * 1000;
		
		if((last_return != null) && (this.cache_queue[i].data != null))
		{
			// if cache time has not passed
			if(new Date().getTime() > (last_return + cache_span_secs + clear_int))
			{
				this.cache_queue[i].data = null;
			}
		}		
	}
};

Phatjax.prototype._url_Check = function(url)
{
	this._debug_out('_url_Check(' + url + ')');
	
	var url_pass;

	if(url && this.url_regex.test(url))
	{
		url_pass = url;	
	}
	else
	{
		url_pass = null;
		this._debug_out('service URL does not pass Regex test.', 'error');
	}
	
	return url_pass;
};

Phatjax.prototype._request_Type_Check = function(request_type)
{
	this._debug_out('_request_Type_Check(' + request_type + ')');
	
	var r_type = null;
	if(request_type && (request_type.length > 2))
	{
		r_type = request_type.toUpperCase();
		
		if((r_type != 'POST') && (r_type != 'GET'))
		{
			r_type = null;
		}
	}
	else
	{
		this._debug_out('incorrect service argument', 'error');	
	}
	
	// invalid, set default
	if(r_type == null)
	{
		r_type = 'POST';
		this._debug_out('request type invalid, defaulting to POST', 'warning');
	}
	
	return r_type;
};

Phatjax.prototype._response_Type_Check = function(response_type)
{
	this._debug_out('_response_Type_Check(' + response_type + ')');
	
	var resp_type = null;
	
	// if sent value is null, set to class value, else string
	if(!response_type || (response_type === 'undefined'))
	{
		resp_type = (this.response_type) ? this.response_type : 'string';	
	}
	else
	{
		switch(response_type)
		{
			case 'xml':
			case 'pairs':
			case 'b64':
			case 'string':
				resp_type = response_type;
				break;	
			default:
				resp_type = (this.response_type) ? this.response_type : 'string';
				break;
		}
	}
	
	return resp_type;
};

Phatjax.prototype._show_Html = function(str)
{
	if(this.debug)
	{
		// replace <
		str = str.split('<');
		str = str.join('&lt;');
		// replace >
		str = str.split('>');
		str = str.join('&gt;');
	}
	
	return str;
};

Phatjax.prototype._debug_out = function(msg, type)
{
	if(this.debug)
	{
		var output = 'phAtJAX: ' + msg;
		
		switch(type)
		{
			case 'error':
				this.js_debug.error(output);
				break;
			case 'warning':
				this.js_debug.warning(output);
				break;
			case 'boolean':
				this.js_debug.boolean_Test(output);
				break;
			default:
				this.js_debug.message(output);
				break;
		}
	}
};