
function majax(id, src, args, func)
{
	addLoadingOverlay(id);
	$.ajax({
		type: "POST",
		url: src,
		data: (args),
		success: function(data){
			try {
				response = $.parseJSON(data);
				//Вывод сообщений
				showMessagesAdmin(response.messages);
				if(response.success && func) {
					func();
				}
				if(id) {
					removeLoadingOverlay(id);
				}
			}
			catch(e) {
				if(id) {
					removeLoadingOverlay(id);
					$("#"+id).html(data);
				}
				if(func){
					func();
				}
			}
		}
    });  
}

/**
 *@description
 *	Функция собирает данные с элементов типа INPUT и отсылает их постом в AJAX.
 *	Используется только в Админке для операций, где использование формы невозможно.
 *@params
 *	string selector - Селектор блока с которого будем собирать информацию для отправки.
 *	string src - Строка вызова AJAX'a.
 *	function() func - Функция, выполняемая после получения ответа на AJAX запрос.
 */
function majaxCustomAction(selector, src, func){
	findAndProcessCodeMirror($(selector));
	findAndProcessCKEditor($(selector));
	var f = simpleSerializeArray(selector);
	doAdminMajax(src,f,func);
}
   
/**
 *@description
 *	Функция собирает данные с формы и отсылает их постом в AJAX.
 *	Используется только в Админке.
 *@params
 *	object obj - Объект элемента формы (например кнопка). Парентом этого объекта должна быть именно форма!
 *	function() func - Функция, выполняемая после получения ответа на AJAX запрос.
 */
function majaxFormAction(obj,func){
	var form = $(obj).parents("form");
	findAndProcessCodeMirror(form);
	findAndProcessCKEditor(form);
	var f = form.serializeArray();
	var src = form.attr("action");
	doAdminMajax(src,f,func);
}
   
/**
 *@description
 *	Функция которая непосредственно подает AJAX запрос на сервер.
 *@params
 *	string action - Строка AJAX запроса.
 *	array[] post - Массив с пост данными.
 *	function() func - Функция, выполняемая после получения ответа на AJAX запрос.
 */
function doAdminMajax(action, post, func){
	if(action.length > 0){
		$.ajax({
			type: "POST",
			url: action,
			data: (post),
			async:true,
			success: function(data){
				try {
					response = $.parseJSON(data);
					//Вывод сообщений
					showMessagesAdmin(response.messages);
					//Выполняем доп функцию. Обычно сюда кидаем обновление некого контента аяксом.
					if(response.success && func){
						func();
					}
				}
				catch(e) {
					showMessagesAdmin('<div class="main_error new_error warning" marked="0" style="display: block;"><p>Ошибка! Обратитесь к администратору!<br/>('+action+')</p></div>');
				}
			}
		}); 
		return true;
	}
	return false;
}
   
/**
 *@description
 *	Функция которая отображает список сообщений в окошке при выполнении запроса.
 *@params
 *	string data - HTML данные, которые вернул запрос.
 */
function showMessagesAdmin(data){
	$("#global_majax_messages_block .admin_visible_block .visible_content").append(data);
	//Помечаем добавленные сообщения для предстаящего переноса.
	$("#global_majax_messages_block .admin_visible_block div[class^=main_error][marked=0]").each(function(){
		$(this).attr("marked","1");
		$(this).mousemove(function(){
			$(this).prependTo("#global_majax_messages_block .majax_messajes_history_block .history_content");
			$(this).unbind("mousemove");
		});
		$(this).dblclick(function(){
			majax("additional_block_for_deleted_ajax_messages", "/ajax/errors/deleteError/", {"id":$(this).attr("error_id")});
			$(this).remove();
		});
		$(this).delay(3000).fadeOut(1000,function() {
			$(this).prependTo("#global_majax_messages_block .majax_messajes_history_block .history_content");
			$(this).unbind("mousemove");
			$(this).show();
		});
	});
}

/**
 *@description
 *	Функция создает оверлей и индикатор загрузки для блока при аякс запосе.
 *@params
 *	int id - Идентификатор блока в который загружались данные.
 */
function addLoadingOverlay(id){
	if(id){
		// Получаем параметры блока который будем хайдить.
		var target_width = $("#"+id).width();
		var target_height = $("#"+id).height();
		if((target_width + target_height) != 0){
			$("#"+id).after("<img src='/images/admin/mloader.gif' id='"+id+"_majax_loading' alt='Загрузка...' title='Загрузка...'/>");
			$("#"+id).after("<div id='"+id+"_majax_overlay' class='majax_overlay'>&nbsp;</div>");
			var load_image = $("#"+id+"_majax_loading");
			var load_overlay = $("#"+id+"_majax_overlay");
			load_image.css("position","absolute");
			load_overlay.css("position","absolute");
			load_overlay.fadeTo(3000,0.6);
			//Если высота элемента куда грузим = 0 то немного её увеличим))
			if(target_height == 0){
				target_height = 40;
				$("#"+id).append("<div style='height:40px'>&nbsp;</div>");
			}
			else if(target_height < 40){
				load_image.height(target_height);
			}
			//Усли у таргета позишн не абсолют - юзаем данные о позишнах, иначе данные о оффсете.
			var target_params = null;
			if($("#"+id).css("position") == "absolute"){
				target_params = $("#"+id).offset();
			}
			else{
				target_params = $("#"+id).position();
			}
			//Устанавливаем оверлей
			var cssObj = {
					'left' : target_params.left,
					'top' : target_params.top,
					'width' : target_width,
					'height' : target_height
				};
			load_overlay.css(cssObj);
			//Устанавливаем картинку
			cssObj = {
				'left' : target_params.left + target_width/2 - 20,
				'top' : target_params.top + target_height/2 - 16
			};
			load_image.css(cssObj);
		}
	}
}

/**
 *@description
 *	Функция убирает оверлей после загрузки
 *@params
 *	int id - Идентификатор блока в который загружались данные.
 */
function removeLoadingOverlay(id){
	$("#"+id+"_majax_loading").remove();
	$("#"+id+"_majax_overlay").remove();
}

/**
 *@description
 *	Функция проверяет наличие в блоке тега textarea и проверяет её принадлежность к CKEDITOR'у
 * В случае принадлежности к CKEDITOR'у, происходит автоматическое сохранение контента.
 *@params
 *	ObjectHTML container - Элемент jQuery для проверки его содержимого.
 */
function findAndProcessCKEditor(container){
	//Проверяем глобальный объект CKEDITOR на странице.
	if(typeof(CKEDITOR) == "undefined") return false;
	//Собираем все textarea в контейнере, пробуем найти их в CKEDITOR.instances 
	container.find("textarea").each(function(){
		var id = $(this).attr("id");
		if(CKEDITOR.instances[id] != undefined){
			CKEDITOR.instances[id].updateElement();
		}
	});
}

function findAndProcessCodeMirror(container){
	container.find(".CodeMirror").each(function(){
		window["editor_"+$(this).prev().attr("id")].save();
	});
}
