function jajax(debug, verbose) {
	this.debug = debug;
	this.verbose = verbose;
	this.res = '';

	this.dynamicallyLoadedJSfiles = [];
	this.dynamicallyLoadedCSSfiles = [];

	// initialize the member function references
	// for the class prototype
	if (typeof(_jajax_prototype_called) == 'undefined'){

		jajax_prototype_called = true;
		jajax.prototype.c = this.c;
		jajax.prototype.s = this.s;
		jajax.prototype.serialize = this.serialize;
	}

	this.addScript = function(scriptURL, allowDuplication) {
		if (typeof allowDuplication == 'undefined') {
			allowDuplication = false;
		}

		if (allowDuplication || ($.inArray(scriptURL, this.dynamicallyLoadedJSfiles) == -1 && $('script[src$="'+scriptURL+'"]').length == 0)) {
			$.getScript(scriptURL, function() {
				if (j.debug && typeof console != 'undefined') {
					console.log("script loaded: "+scriptURL);
				}
				j.dynamicallyLoadedJSfiles.push(scriptURL);
			});
		} else if (this.debug && typeof console != 'undefined') {
			console.log("not loading script: "+scriptURL);
		}
	}

	this.addCSS = function(cssURL, media, allowDuplication) {
		if (typeof allowDuplication == 'undefined') {
			allowDuplication = false;
		}

		if (typeof media == 'undefined') {
			media = 'screen';
		}

		if (allowDuplication || ($.inArray(cssURL, this.dynamicallyLoadedCSSfiles) == -1 && $('link[href$="'+cssURL+'"]').length == 0)) {
			this.dynamicallyLoadedCSSfiles.push(cssURL);
			$('<link />').appendTo('head').attr({
				rel:  "stylesheet",
				type: "text/css",
				media: media,
				href: cssURL
			});

			if (this.debug && typeof console != 'undefined') {
				console.log("adding CSS ("+media+"): "+cssURL);
			}
		} else if (this.debug && typeof console != 'undefined') {
			console.log("not adding CSS ("+media+"): "+cssURL)
		}
	}

	// call asyncron ajax function
	this.c = function() {
		var args = new Array();
		var mthis = this;
		var lp = location.pathname.replace(/\/\//g, '/');
		var url = lp+location.search;
		for (var i = 0; i < arguments.length; i++) {
			args[i] = arguments[i];
		}
		js_ret_data = null;

		$.ajax( {
			type: "POST",
			async: true,
			url: url,
			data: { 'jajaxdata': $.toJSON(args) },
			dataType: 'script',
			success:
				function (t) {
					if(verbose) {
						if(typeof console != 'undefined') {
							console.log('Asyncron JAJAX response: ', t);
						} else {
							alert('Asyncron JAJAX response: '+t);
						}
					}
					if(js_ret_data) {
						try{
							mthis.res = jQuery.parseJSON(js_ret_data);
							js_ret_data = null;
						} catch (e) {
							if(debug) {
								if(typeof console != 'undefined') {
									console.log('Malformed JSON data, unable to parse it. ', e);
								} else {
									alert('Malformed JSON data, unable to parse it. '+e);
								}
							}
						}

					}
				},
			error:
				function (request, textStatus, errorThrown) {
					if (debug) {
						if (typeof console != 'undefined') {
							console.log('Asyncron JAJAX error occured. Response: ', textStatus, errorThrown);
						} else {
							alert('Asyncron JAJAX error occured. Response: ' + textStatus);
						}
					}
				}
		});
	}

	// call syncron ajax function
	this.s = function() {
		var toreturn = "";
		var mthis = this;
		var args = new Array();
		var lp = location.pathname.replace(/\/\//g, '/');
		var url = lp+location.search;
		for (var i = 0; i < arguments.length; i++) {
			args[i] = arguments[i];
		}
		js_ret_data = null;
		js_sync_ret_value = null;
		jQuery.ajax( {
			async: false,
			type: 'POST',
			url: url,
			data: { 'jajaxdata': $.toJSON(args) },
			success:
				function(t) {
					if(verbose) {
						if(typeof console != 'undefined') {
							console.log('Syncron JAJAX response: '+t);
						} else {
							alert('Syncron JAJAX response: '+t);
						}
					}
					if(js_ret_data) {
						try{
							mthis.res = jQuery.parseJSON(js_ret_data);
							js_ret_data = null;
						}
						catch(e) {
							if(debug) {
								if(typeof console != 'undefined') {
									console.log('Malformed JSON data, unable to parse it. '+e);
								} else {
									alert('Malformed JSON data, unable to parse it. '+e);
								}
							}
						}

					}
					mthis.ret = js_sync_ret_value;
					js_sync_ret_value = null;
				},
			error:
				function (request, textStatus, errorThrown) {
					if (debug) {
						if (typeof console != 'undefined') {
							console.log('Syncron Jajax error occured. Response: ', textStatus, errorThrown);
						} else {
							alert('Syncron Jajax error occured. Response: ' + textStatus);
						}
					}
				}
		});
		return this.ret;
	}

	// call x3x ajax function
	this.x = function() {
		var args = new Array();
		var mthis = this;
		var lp = location.pathname.replace(/\/\//g, '/');
		var url = lp+location.search;
		for (var i = 0; i < arguments.length; i++) {
			args[i] = arguments[i];
		}
		js_ret_data = null;

		var separator = '?';
		if (url.indexOf('?') != -1) {
			separator = '&';
		}

		$.ajax( {
			type: "POST",
			async: true,
			url: url+separator+'x3x_base64_encoded=1',
			data: { 'jajaxdata': $.toJSON(args) },
			dataType: 'script',
			success:
				function (t) {
					if(verbose) {
						if(typeof console != 'undefined') {
							console.log('Asyncron JAJAX response: ', t);
						} else {
							alert('Asyncron JAJAX response: '+t);
						}
					}
					if(js_ret_data) {
						try{
							mthis.res = jQuery.parseJSON(js_ret_data);
							js_ret_data = null;
						} catch (e) {
							if(debug) {
								if(typeof console != 'undefined') {
									console.log('Malformed JSON data, unable to parse it. ', e);
								} else {
									alert('Malformed JSON data, unable to parse it. '+e);
								}
							}
						}

					}
				},
			error:
				function (request, textStatus, errorThrown) {
					if (debug) {
						if (typeof console != 'undefined') {
							console.log('Asyncron JAJAX error occured. Response: ', textStatus, errorThrown);
						} else {
							alert('Asyncron JAJAX error occured. Response: ' + textStatus);
						}
					}
				}
		});
	}

	this.serialize = function(formID) {
		if (typeof formID == 'object') {
			var ser = $(formID).serialize();
		} else if (formID.indexOf(' ') > -1) {
			// JQselector
			var ser = $(formID).serialize();
		} else if (typeof formID != 'undefined' && formID) {
			// getElement ID
			var ser = $('#'+formID).serialize();
		} else {
			throw new exception ('Missing formID');
		}
		var jason = { 'jajaxformdata': ser }
		return jason;
	}

}
