
if (!portal) {
	alert('ajax.js requires global.js; sokay');
	throw new Error('ajax.js requires global.js; sokay');
}

// to be replaced by jQuery.noop when we update to 1.4
portal.noop = function(){};

portal.defaultAjaxErrorHandler = function(request, status, error)
{
	portal.hideAjaxInProgress();
	
	var msg = status;
	switch (status)
	{
	case 'parsererror': // jQuery
		msg = 'JSON parse error';
		break;
	}
	handleError("An error occurred: " + msg);
};
portal.defaultAjaxFailureHandler = function(data, status, request)
{
	handleJSONError(data);
};
portal.createAjaxResponseHandler = function(success, failure, finallyDo)
{
	if (!success) success = portal.noop;
	if (!failure) failure = portal.defaultAjaxFailureHandler;
	
	return function(data, status, request) {
		portal.hideAjaxInProgress();
		
		try {
			if (checkForJSONError(data)) {
				if (data.outcome == 'AccessDenied')
					window.location = _PORTAL_HOST_URL;
				else
					failure.apply(this, [data, status, request]);
			} else {
				success.apply(this, [data, status, request]);
			}
			if (finallyDo)
				finallyDo.apply(this, [data, status, request]);
		} catch (e) {
			alert('Unexpected error: ' + e);
			throw e;
		}
	};		
};
portal.createAjaxFinallyWrapper = function(callback, finallyDo)
{
	return function() {
		callback.apply(this, arguments);
		if (finallyDo)
			finallyDo.apply(this, arguments);
	}
}

/**
 * @see http://api.jquery.com/jQuery.ajax/
 * 
 * @args {
 *     url: optional; the url of the request, defaults to _PORTAL_HOST_URL
 *     dataType: optional; the response format, defaults to 'json'
 *     data: optional; the request parameters in object form
 *     success: optional; success callback, defaults to portal.noop
 *     failure: optional; failure callback, defaults to portal.defaultAjexFailureHandler
 *     error: optional; error callback, defaults to portal.defaultAjaxErrorHandler
 *     finallyDo: optional; callback called regardless of outcome (after all other callbacks) 
 * }
 */
portal.ajax = function(args)
{
	if (!args.data) args.data = {};
	if (!args.url) args.url = _PORTAL_CURRENT_URL;
	if (!args.error) args.error = portal.defaultAjaxErrorHandler;
	if (!args.type) args.type = 'POST';
	if (!args.data.mode) args.data.mode = 'json';
	if (!args.dataType) args.dataType = args.data.mode;
	if (args.command) args.data.command = args.command;
	
	args.success = portal.createAjaxResponseHandler(
		args.success || portal.noop,
		args.failure || portal.defaultAjaxFailureHandler,
		args.finallyDo
	);
	args.error = portal.createAjaxFinallyWrapper(args.error, args.finallyDo);
	
	portal.maybeShowAjaxInProgress();
	$.ajax(args);
};

portal.showAjaxTimer = null;

portal.maybeShowAjaxInProgress = function()
{
	if (portal.showAjaxTimer)
		return;
	portal.showAjaxTimer = setTimeout(portal.showAjaxInProgress, 1000);
}

portal.showAjaxInProgress = function()
{
	if (portal.showAjaxTimer)
		clearTimeout(portal.showAjaxTimer);
	portal.showAjaxTimer = null;
	
	var div = $('#ajaxInProgress');
	if ($.browser.msie) {
		div.css('top', '100%');
		div.css('marginTop', -div.height());
	}
	div.stop().fadeIn();
};
portal.hideAjaxInProgress = function()
{
	if (portal.showAjaxTimer)
		clearTimeout(portal.showAjaxTimer);
	portal.showAjaxTimer = null;
	
	var div = $('#ajaxInProgress');
	div.stop().fadeOut();
};


portal.createElementBusyIndicator = function(element)
{
	element = $(element);
	var busyIcon = $('<div style="position: absolute; z-index: 100; width: 16px; height: 16px; display: none"><img src="'+_PORTAL_BASE_URL+'images2/waiting.gif" border="0" /></div>');
	$('body').append(busyIcon);
	var pos = element.position();
	busyIcon.css({
		left: pos.left - busyIcon.width(),
		top: pos.top
	}).fadeIn(200);
	element.attr('disabled', true);
	return busyIcon;
}

