
function Ajax(handlerURL, requestType, dataType) {
	this.url      = handlerURL;
	this.type     = requestType;
	this.dataType = dataType;
	this.errors   = { };
}

Ajax.prototype = {
	init      : {},  // init functions (run before submit, after triggering ajax event)
	callback  : {},  // callback functions (response handlers)
	state     : {},  // current action state
	request   : {},  // request data
	params    : {},  // action params, format: ajax.params[ElementID] = { param: "val" ... }

	exec: function(request) {
		this.request[request.action] = request;
		$.ajax({
			url      : this.url,
			type     : this.type,
			dataType : this.dataType,
			data     : request,
			success  : ajax.success,
			error    : ajax.error
		});
	},

	success: function(response) {
		var action = response.action;
		// raw_output normally might contain only error messages (if php.ini.display_errors == 1)
		if (response.raw_output) {
			$('body').prepend(response.raw_output);
		}
		if (response.sql_log) {
			$('#sqlLog').prepend(response.sql_log +'<hr />');
			fixSqlLog();
		}
		if (response.update_ids) {
			for (id in response.update_ids) {
				$('#'+id).html( response.update_ids[id] );
			}
		}
		if (response.prompt_password) {
			var user_password = prompt('Please enter your password (for mod/admin session)', '');
			if (user_password) {
				var req = ajax.request[action];
				req.user_password = user_password;
				ajax.exec(req);
			}
			else {
				ajax.clearActionState(action);
				ajax.showErrorMsg('Wrong password');
			}
		}
		else if (response.error_code) {
			ajax.showErrorMsg(response.error_msg);
		}
		else {
			ajax.callback[action](response);
			ajax.clearActionState(action);
		}
	},

	error: function(xml, desc) {
	},

	clearActionState: function(action){
		ajax.state[action] = ajax.request[action] = '';
	},

	showErrorMsg: function(msg){
		alert(msg);
	},

	callInitFn: function(event) {
		event.stopPropagation();
		var params = ajax.params[$(this).attr('id')];
		var action = params.action;
		if (ajax.state[action] == 'readyToSubmit' || ajax.state[action] == 'error') {
			return false;
		} else {
			ajax.state[action] = 'readyToSubmit';
		}
		ajax.init[action](params);
	},

	setStatusBoxPosition: function($el) {
		var newTop = $(document).scrollTop();
		var rCorner = $(document).scrollLeft() + $(window).innerWidth() - ($.browser.msie ? 10 : 24);
		var newLeft = Math.max(0, rCorner - $el.width());
		$el.css({ top: newTop, left: newLeft });
	},

	makeEditable: function(rootElementId, editableType) {
		var $root = $('#'+rootElementId);
		var $editable = $('.editable', $root);
		var inputsHtml = $('#editable-tpl-'+editableType).html();
		$editable.hide().after(inputsHtml);
		var $inputs = $('.editable-inputs', $root);
		if (editableType == 'input' || editableType == 'textarea') {
			$('.editable-value', $inputs).val( $.trim($editable.text()) );
		}
		$('input.editable-submit', $inputs).click(function(){
			var params = ajax.params[rootElementId];
			var $val = $('.editable-value', '#'+rootElementId);
			params.value = ($val.size() == 1) ? $val.val() : $val.filter('[@checked]').val();
			params.submit = true;
			ajax.init[params.action](params);
		});
		$('input.editable-cancel', $inputs).click(function(){
			ajax.restoreEditable(rootElementId);
		});
		$inputs.show().focus();
		$root.removeClass('editable-container');
	},

	restoreEditable: function(rootElementId, newValue) {
		var $root = $('#'+rootElementId);
		var $editable = $('.editable', $root);
		$('.editable-inputs', $root).remove();
		if (newValue) {
			$editable.text(newValue);
		}
		$editable.show();
		ajax.clearActionState( ajax.params[rootElementId].action );
		ajax.params[rootElementId].submit = false;
		$root.addClass('editable-container');
	}
};

$(document).ready(function(){
	// Setup ajax-loading box
	$("#ajax-loading").ajaxStart(function(){
		$("#ajax-error").hide();
		$(this).show();
		ajax.setStatusBoxPosition($(this));
	});
	$("#ajax-loading").ajaxStop(function(){ $(this).hide(); });

	// Setup ajax-error box
	$("#ajax-error").ajaxError(function(req, xml){
		var status = xml.status;
		var text = xml.statusText;
		if (status == 200) {
			status = '';
			text = 'invalid data format';
		}
		$(this).html(
			"Ajax error in: <i>"+ ajax.url +"</i><br /><b>"+ status +" "+ text +"</b>"
		).show();
		ajax.setStatusBoxPosition($(this));
	});

	// Bind ajax events
	$('var.ajax-params').each(function(){
		var params = $.parseJSON($(this).html());
		params.event = params.event || 'dblclick';
		ajax.params[params.id] = params;
		//alert(params.event);
		$("#"+params.id).bind(params.event, ajax.callInitFn);
		 (params.event == 'click' || params.event == 'dblclick') {
			$("#"+params.id).addClass('editable-container');
		}
	});
});

