/**
* HostCMS
*
* @author Hostmake LLC, http://www.hostcms.ru/
* @version 5.x
*/

if (typeof HostcmsEscape == 'undefined')
{
	// Сохраняем стандартную функцию escape()
	//var escapeOrig = window.escape;

	// Переопределяем функцию escape()
	//window.escape = function(str)
	function HostcmsEscape(str)
	{
		// Инициализируем таблицу перевода
		var trans = [];

		for (var i = 0x410; i <= 0x44F; i++)
		{
			trans[i] = i - 0x350; // А-Яа-я
		}

		trans[0x401] = 0xA8; // Ё
		trans[0x451] = 0xB8; // ё
		
		var ret = [];
		// Составляем массив кодов символов, попутно переводим кириллицу
		for (var i = 0; i < str.length; i++)
		{
			var n = str.charCodeAt(i);

			if (typeof trans[n] != 'undefined')
			{
				n = trans[n];
			}
			if (n <= 0xFF)
			{
				ret.push(n);
			}
		}

		var res = escape(String.fromCharCode.apply(null, ret)).replace('+','%2B').replace(':','%3A').replace('/','%2F').replace('?','%3F').replace('=','%3D').replace('&','%26').replace('@','%40').replace('#','%23').replace('$','%24').replace(';','%3B');

		return res;
	}
}

// Событие - нажатие клавиши.
document.onkeydown = DoKeyDown;

// Пользовательский обработчик события нажатия клавиш,
// для обработки Ctrl + стрелка.
function DoKeyDown(event)
{
	if (!document.getElementById)
	{
		return;
	}

	if (window.event)
	{
		event = window.event;
	}

	if (event.ctrlKey)
	{
		var Element = null;

		switch (event.keyCode ? event.keyCode : event.which ? event.which : null)
		{
			case 0x25: // Назад
			Element = document.getElementById ('id_prev');
			break;

			case 0x27: // Вперед
			Element = document.getElementById ('id_next');
			break;
		}

		if (Element && Element.href)
		{
			// Редирект на нужную страницу.
			document.location = Element.href;
		}
	}
}

function DisableTinyMCE()
{
	// Работу с визуальным редактором ведём, если пришли данные для form_html
	if (typeof tinyMCE != 'undefined')
	{
		textarea_array = document.getElementsByTagName("textarea");

		for (var i=0; i < textarea_array.length; i++)
		{
			var elementId = textarea_array[i].id;

			if (tinyMCE.getInstanceById(elementId) != null)
			{
				textarea_array[i].disabled = true;
				tinyMCE.execCommand('mceRemoveControl', false, elementId);
			}
		}
	}
}

// выполняет скрипты из полученного ответа от сервера
function runScripts(scripts)
{
	if (!scripts)
	{
		return false;
	}

	for (var i = 0; i < scripts.length; i++)
	{
		var thisScript = scripts[i];
		var text;

		if (thisScript.src)
		{
			var newScript = document.createElement("script");
			newScript.type = thisScript.type;
			newScript.language = thisScript.language;

			newScript.src = thisScript.src;
			document.getElementsByTagName('head')[0].appendChild(newScript);

			// Получаем объект, к которому применим ребенка
			//var obj = document.getElementsByTagName('body')[0];
			//var obj = document.getElementById('id_form_' + AAdminFromsId);
			//obj.appendChild(newScript);
		}
		else if (text = (thisScript.text || thisScript.innerHTML))
		{
			var text = (""+text).replace(/^\s*<!\-\-/, '').replace(/\-\->\s*$/, '');

			var newScript = document.createElement("script");
			newScript.setAttribute("type", "text/javascript");
			newScript.text = text;

			var script_node = document.getElementsByTagName('head')[0].appendChild(newScript);

			// Не работает в IE, в нем работает newScript.text = text;
			//script_node.appendChild(document.createTextNode(text));
		}
	}
}

// action - адрес страницы для запрос
// method - GET, POST, null - автоматическое определение
// callback_function - функция обратного вызова, которая будет вызвана после получения ответа от backenad-а
function sendRequest(action, method, callback_function)
{
	var req = new JsHttpRequest();

	// Отображаем экран загрузки
	ShowLoadingScreen();

	// Этот код вызовется автоматически, когда загрузка данных завершится.
	req.onreadystatechange = function()
	{
		if (req.readyState == 4)
		{
			// Возвращаем обычный курсор
			document.body.style.cursor = '';

			// Убираем затемнение.
			HideLoadingScreen();

			if (typeof callback_function != 'undefined')
			{
				callback_function(req.responseJS);
			}

			return true;
		}
	}

	req.open(method, action, true);

	// Отсылаем данные в обработчик.
	req.send(null);

	// Курсор ставим на часики.
	document.body.style.cursor = "wait";
}

//Загрузка формы
//AAction - относительный адрес файла, который будет запрошен
//AAdditionalParams - внешние переметры, передаваемые в строку запроса. Должны начинаться с &
//AAdminFromsId - идентификатор формы центра администрирования
//AOperation - имя события
//ALimit - текущая страница, false - не отправлять страницу
//AOnPage - число элементов на страницу
//AOrderFieldId - ID поля, по которому идет сортировка
//AOrderDirection - направление сортировки, 1 - по возрастанию, 2 - по убыванию
function DoLoadAjax(AAction, AAdditionalParams, AAdminFromsId, AOperation, ALimit, AOnPage, AOrderFieldId, AOrderDirection)
{
	// Отключаем связь с редакторами
	DisableTinyMCE();

	if (AOperation == '')
	{
		return false;
	}

	// Если поле сортировки было указано - передадим поле и направление сортировки
	if (AOrderFieldId != 0)
	{
		sOrder = '&order_field_id=' + AOrderFieldId +
		'&order_field_direction=' + AOrderDirection;
	}
	else
	{
		sOrder = '';
	}

	// Чисто элеменов на страницу.
	cbOnPage = document.getElementById('id_on_page');

	if (AOnPage)
	{
		sOnPage = '&admin_forms_on_page=' + AOnPage;
	}
	else
	{
		if (cbOnPage)
		{
			sOnPage = '&admin_forms_on_page=' + cbOnPage.options[cbOnPage.selectedIndex].value;
		}
		else
		{
			sOnPage = '';
		}
	}

	// Строка запроса с выбранными элементами и их значениями.
	sElements = '';
	sFilter = '';

	// Для определния принадлежности поля фильтру
	reg_filter = /admin_form_filter_.+/;

	element_array = document.getElementsByTagName("input");
	if (element_array.length > 0)
	{
		for (var i = 0; i < element_array.length; i++)
		{

			element_name = element_array[i].getAttribute('name');

			if (element_name == undefined)
			{
				continue;
			}

			// Определяем выбрана ли запись для редактирования.
			if (element_name.search("check_") != -1 &&
			element_name.search("_fv_") == -1)
			//element_name.search("field_value") == -1)
			{
				if (element_array[i].checked)
				{
					sElements = sElements + '&' + element_name + '=1';

					// Ищем значения записей.
					value_element_array = document.getElementsByTagName("input");
					if (value_element_array.length > 0)
					{
						for (var j = 0; j < value_element_array.length; j++)
						{
							value_element_name = value_element_array[j].name;

							if (typeof value_element_name == 'undefined')
							{
								continue;
							}

							// Проверяем, содержит ли в себе имя чекбокса для записи.
							//if (value_element_name.search("field_value") != -1 &&
							if (value_element_name.search("_fv_") != -1 &&
							value_element_name.search(element_name) != -1)
							{
								if (value_element_array[j].getAttribute('type') == 'text')
								{
									sElements = sElements + '&' + value_element_name +
									'=' + value_element_array[j].value;
								}
								else if (value_element_array[j].getAttribute('type') == 'checkbox')
								{

									if (value_element_array[j].checked)
									{

										sElements = sElements + '&' + value_element_name + '=1';
									}
									else
									{

										sElements = sElements + '&' + value_element_name + '=0';
									}
								}
							}
						}
					}

					// Ищем значения записей для select-ов
					value_element_array = document.getElementsByTagName("select");
					if (value_element_array.length > 0)
					{
						for (var j = 0; j < value_element_array.length; j++)
						{
							value_element_name = value_element_array[j].name;

							if (typeof value_element_name == 'undefined')
							{
								continue;
							}

							// Проверяем, содержит ли в себе имя чекбокса для записи.
							//if (value_element_name.search("field_value") != -1 &&
							if (value_element_name.search("_fv_") != -1 &&
							value_element_name.search(element_name) != -1)
							{
								sElements = sElements + '&' + value_element_name +
								'=' + HostcmsEscape(value_element_array[j].options[value_element_array[j].selectedIndex].value);
							}
						}
					}
				}
			}

			// Может быть это элемент фильтра?
			if (reg_filter.test(element_name))
			{
				// Дописываем к передаваемым данным, только если значение фильтра до 255 символов
				if (element_array[i].value.length < 256)
				{
					sFilter = sFilter + '&' + element_name + '=' + HostcmsEscape(element_array[i].value);
				}
			}
		}
	}

	// Select-ы из фильтра
	element_array = document.getElementsByTagName("select");
	if (element_array.length > 0)
	{
		for (var i = 0; i < element_array.length; i++)
		{
			element_name = element_array[i].getAttribute('name');

			// Может быть это элемент фильтра?
			if (reg_filter.test(element_name))
			{
				// Дописываем к передаваемым данным
				sFilter = sFilter + '&' + element_name + '=' + HostcmsEscape(element_array[i].value);
			}
		}
	}

	// Данные которые всегда нужно передавать в запрос.
	sParams = AAdditionalParams;

	// Текущая страница.
	//ALimit = '&limit=' + ALimit;

	//if (ALimit == 0)
	if (ALimit === false)
	{
		ALimit = '';
	}
	else
	{
		ALimit = '&limit=' + ALimit;
	}

	cmsrequest = AAction + '?admin_forms_id=' + AAdminFromsId +
	'&hostcmsAAction=' + HostcmsEscape(AAction) +
	'&hostcmsAAdditionalParams=' + HostcmsEscape(AAdditionalParams) +
	'&operation=' + AOperation + ALimit + sOnPage + sFilter +
	sElements + sOrder + sParams;

	if (cmsrequest.length < 2000)
	{
		method = 'get';
	}
	else
	{
		method = 'post';
	}

	// Отправляем запрос backend-у
	sendRequest(cmsrequest, method, callbackfunction_DoLoadAjax);
}

// Функция обратного вызова для DoLoadAjax
function callbackfunction_DoLoadAjax(responseJS)
{
	// Результат принят
	sended_request = false;

	//if (typeof responseJS != 'undefined')
	if (responseJS != null)
	{
		if (typeof responseJS.error != 'undefined')
		{
			var div_id_message = document.getElementById('id_message');

			if (div_id_message)
			{
				div_id_message.innerHTML = responseJS.error;
			}
		}

		// Данные.
		if (typeof responseJS.form_html != 'undefined')
		{
			// Указываем текущий путь
			// Меняем Location только при DoLoadAjax, если вернулись назад - не меняем
			if (cmsrequest != ''
			&& function_exists('getCmsUrl')
			&& getCmsUrl() != cmsrequest)
			{
				setLocation(cmsrequest);
			}

			if (function_exists('saveLocation'))
			{
				// Сохраняем текущий путь всегда
				saveLocation(getCmsUrl());
			}

			// Отключаем связь с редакторами
			DisableTinyMCE();

			html = responseJS.form_html;

			document.getElementById('id_content').innerHTML = html;

			// Выполняем скрипты из полученного с сервера HTML-а
			runScripts(document.getElementById('id_content').getElementsByTagName('SCRIPT'));

			// Сбрасываем cmsrequest
			cmsrequest = '';
		}

		// Title.
		if (typeof responseJS.title != 'undefined' && responseJS.title != '')
		{
			document.title = responseJS.title;
		}

		// Редирект.
		if (typeof responseJS.redirect != 'undefined')
		{
			if (responseJS.redirect != '')
			{
				ShowLoadingScreen();
				location = responseJS.redirect;
			}
		}
	}
}

//Отправка формы методом Get или Post
//AAction - относительный адрес файла, который будет запрошен
//AAdditionalParams - внешние переметры, передаваемые в строку запроса. Должны начинаться с &
//ButtonObject - Объект нажатой кнопки
//AAdminFromsId - идентификатор формы центра администрирования
function doSendForm(AAction, AAdditionalParams, ButtonObject, AAdminFromsId, AOperation, ALimit, AOnPage)
{
	// Объект родительской формы по умолчанию
	var FormNode = ButtonObject.parentNode;

	// Пока родительская форма не является формой
	while (FormNode.nodeName.toLowerCase() != 'form')
	{
		var FormNode = FormNode.parentNode;
	}

	// Получим ID формы (не путать с ID формы центра администрирования)
	FormID = FormNode.id;

	// Пытаемся получить скрытый объект для input-а
	var HiddenInput = document.getElementById(ButtonObject.name);

	// Элемента нет, добавим его
	if (null == HiddenInput && undefined == HiddenInput || HiddenInput.type != 'hidden')
	{
		// Создадим скрытй input, т.к. нажатый не передается в форму
		var ElementInput = document.createElement("input");
		ElementInput.setAttribute("type", "hidden");
		ElementInput.setAttribute("id", ButtonObject.name);
		ElementInput.setAttribute("name", ButtonObject.name);

		// Добавим скрытый Input к форме
		var InputNode = FormNode.appendChild(ElementInput);
	}

	// Сохраним из визуальных редакторов данные
	if (typeof tinyMCE != 'undefined')
	{
		tinyMCE.triggerSave();
	}

	var JsHttpRequestSendForm = new JsHttpRequest();

	// Код вызывается, когда загрузка завершена
	JsHttpRequestSendForm.onreadystatechange = function ()
	{
		if (JsHttpRequestSendForm.readyState == 4)
		{
			// Возвращаем обычный курсор
			document.body.style.cursor = '';

			// Убираем затемнение.
			HideLoadingScreen();

			if (typeof JsHttpRequestSendForm.responseJS != 'undefined')
			{
				// Выводим результат ошибки в переменную.
				if (typeof JsHttpRequestSendForm.responseJS.error != 'undefined')
				{
					var div_id_message = document.getElementById('id_message');

					if (div_id_message)
					{
						// Создадим скрытый SPAN для IE, в который поместим текст + скрипт.
						// Если перед <script> не будет текста, нехороший IE не увидит SCRIPT
						var span = document.createElement("span");
						span.style.display = 'none';
						span.innerHTML = "Stupid IE. " + JsHttpRequestSendForm.responseJS.error;

						runScripts(span.getElementsByTagName('SCRIPT'));

						// Занесем текст сообщения только после выполнения скрипта
						div_id_message.innerHTML = JsHttpRequestSendForm.responseJS.error;
					}
				}

				// Данные записываем только тогда, если они есть и не пустые.
				if (typeof JsHttpRequestSendForm.responseJS.form_html != 'undefined' && JsHttpRequestSendForm.responseJS.form_html != '')
				{
					// Отключаем связь с редакторами
					DisableTinyMCE();

					// В клиентском разделе нам не нужно показывать результат отправки формы,
					// поэтому если такой результат пришел - закрываем окно.
					HideWindow(prev_window);

					/*html = JsHttpRequestSendForm.responseJS.form_html;

					document.getElementById('id_content').innerHTML = html;

					// Выполняем скрипты из полученного с сервера HTML-а
					runScripts(document.getElementById('id_content').getElementsByTagName('SCRIPT'));*/

				}
			}
			return true;
		}
	}

	// Определим action у формы
	//var FormAction = FormNode.getAttribute('action');
	// fix bug with IE 6 and getAttribute('') return [object]
	var FormAction = FormNode.attributes['action'].value;

	// Определим метод формы
	var FormMethod = FormNode.getAttribute('method');

	if (AOnPage)
	{
		sOnPage = '&admin_forms_on_page=' + AOnPage;
	}
	else
	{
		sOnPage = '';
	}

	// Текущая страница.
	if (ALimit == 0)
	{
		ALimit = '';
	}
	else
	{
		ALimit = '&limit=' + ALimit;
	}

	// передача параметров AAdditionalParams сделана явно, а не через hostcmsAAdditionalParams
	FormAction += (FormAction.indexOf('?') >= 0 ? '&' : '?') + 'hostcmsAAction=' + HostcmsEscape(AAction) +
	'&hostcmsAAdditionalParams=' + HostcmsEscape(AAdditionalParams) + AAdditionalParams +
	'&operation=' + AOperation + ALimit + sOnPage;

	// Prepare request object (automatically choose GET or POST).
	JsHttpRequestSendForm.open(FormMethod, FormAction, true);

	JsHttpRequestSendForm.send( { query: FormNode } );

	// Очистим поле для сообщений
	var div_id_message = document.getElementById('id_message');

	if (div_id_message)
	{
		div_id_message.innerHTML = '';
	}

	// Курсор ставим на часики.
	document.body.style.cursor = "wait";

	// Отображаем экран загрузки
	ShowLoadingScreen();

	return false;
}


//Функция выполняет событие, убирает выделение всех checkbox'ов кроме нужного.
//AAction - относительный адрес файла, который будет запрошен
//AAdditionalParams - внешние переметры, передаваемые в строку запроса. Должны начинаться с &
//AOperation - название события
//AItemName - кодовое имя элемента, над которым производится действие
//AAdminFromsId - идентификатор формы
//ALimit - текущая страница
//AOnPage - число элементов на страницу
//AOrderFieldId - ID поля, по которому идет сортировка
//AOrderDirection - направление сортировки, 1 - по возрастанию, 2 - по убыванию
function TrigerSingleAction(AAction, AAdditionalParams, AOperation, AItemName, AAdminFromsId, ALimit, AOnPage, AOrderFieldId, AOrderDirection)
{
	var ElementID = 'id_' + AItemName;

	cbItem = document.getElementById(ElementID);

	if (cbItem)
	{
		// Получаем все input-ы
		element_array = document.getElementsByTagName("input");

		// Если получили хотя бы один
		if (element_array.length > 0)
		{
			// Проходимся по списку
			for (var i = 0; i < element_array.length; i++)
			{
				if (element_array[i].getAttribute('name') == null)
				{
					continue;
				}

				if (element_array[i].getAttribute('name').search("check_") != -1
				&& element_array[i].getAttribute('name').search("_fv_") == -1)
				//&& element_array[i].getAttribute('name').search("field_value") == -1)
				{
					element_array[i].checked = false;
				}
			}
		}
		cbItem.checked = true;
	}
	else
	{
		// Получим ID источника и ID элемента
		var reg = /id_check_(\d+)_(\S+)/;
		var arr = reg.exec(ElementID);

		// arr[1] - ID источника
		// arr[2] - ID элемента

		// Для элемена с ID = 0 создадим чекбокс "на лету"
		//if (arr[2] == 0)
		//{
		// Создадим скрытый див
		var ElementDiv = document.createElement("div");
		ElementDiv.setAttribute("style", "display: none");

		// Добавим скрытый div к div-у с загружаемыми данными
		//var DivNode = document.getElementById('id_form_' + AAdminFromsId).appendChild(ElementDiv);
		var DivNode = document.getElementById('id_content').appendChild(ElementDiv);

		// Создадим чекбокс
		var ElementCheckbox = null;

		// Попытка создать элемент в стиле "$%&*@#" IE 6-7.
		try {
			ElementCheckbox = document.createElement('<input name="'+AItemName+'" type="checkbox" checked="">');
		} catch (e) {
		}

		if (!ElementCheckbox)
		{
			ElementCheckbox = document.createElement("input");
			ElementCheckbox.setAttribute("type", "checkbox");
			ElementCheckbox.setAttribute("name", AItemName);
			ElementCheckbox.setAttribute("checked", true);
			ElementCheckbox.setAttribute("value", "1");  //
		}

		// Добавим чекбокс к скрытому div-у
		var ElementNode = DivNode.appendChild(ElementCheckbox);
		//}
	}

	var admin_forms_all_check = document.getElementById('id_admin_forms_all_check');

	// Если элемент выбора всех чекбоксов существует
	if (admin_forms_all_check != undefined)
	{
		admin_forms_all_check.checked = false;
	}

	// Если для действия был указан 0, то устанавливаем в false, чтобы не передавать явно limit в DoLoadAjax()
	if (ALimit == 0)
	{
		ALimit = false;
	}

	DoLoadAjax(AAction, AAdditionalParams, AAdminFromsId, AOperation, ALimit, AOnPage, AOrderFieldId, AOrderDirection);
}

//Отправка формы методом Get или Post
//callback_function функция обратного вызова
//AAdditionalParams - внешние переметры, передаваемые в строку запроса. Должны начинаться с &
//ButtonObject - Объект нажатой кнопки
function AjaxSendForm(callback_function, AAdditionalParams, ButtonObject)
{
	// Объект родительской формы по умолчанию
	var FormNode = ButtonObject.parentNode;

	// Пока родительская форма не является формой
	while (FormNode.nodeName.toLowerCase() != 'form')
	{
		var FormNode = FormNode.parentNode;
	}

	// Получим ID формы (не путать с ID формы центра администрирования)
	FormID = FormNode.id;

	// Пытаемся получить скрытый объект для input-а
	var HiddenInput = document.getElementById(ButtonObject.name);

	// Элемента нет, добавим его
	if (null == HiddenInput && undefined == HiddenInput || HiddenInput.type != 'hidden')
	{
		// Создадим скрытй input, т.к. нажатый не передается в форму
		var ElementInput = document.createElement("input");
		ElementInput.setAttribute("type", "hidden");
		ElementInput.setAttribute("id", ButtonObject.name);
		ElementInput.setAttribute("name", ButtonObject.name);

		// Добавим скрытый Input к форме
		var InputNode = FormNode.appendChild(ElementInput);
	}

	// Сохраним из визуальных редакторов данные
	if (typeof tinyMCE != 'undefined')
	{
		tinyMCE.triggerSave();
	}

	var JsHttpRequestSendForm = new JsHttpRequest();

	// Код вызывается, когда загрузка завершена
	JsHttpRequestSendForm.onreadystatechange = function ()
	{
		if (JsHttpRequestSendForm.readyState == 4)
		{
			// Возвращаем обычный курсор
			document.body.style.cursor = '';

			// Убираем затемнение.
			HideLoadingScreen();

			if (typeof callback_function != 'undefined')
			{
				callback_function(JsHttpRequestSendForm.responseJS);
			}
			
			return true;
		}
	}

	// Определим action у формы
	// fix bug with IE 6 and getAttribute('') return [object]
	var FormAction = FormNode.attributes['action'].value;

	// Определим метод формы
	var FormMethod = FormNode.getAttribute('method');

	// передача параметров AAdditionalParams сделана явно, а не через hostcmsAAdditionalParams
	FormAction += (FormAction.indexOf('?') >= 0 ? '&' : '?') + AAdditionalParams;

	// Prepare request object (automatically choose GET or POST).
	JsHttpRequestSendForm.open(FormMethod, FormAction, true);

	JsHttpRequestSendForm.send( { query: FormNode } );

	// Курсор ставим на часики.
	document.body.style.cursor = "wait";

	// Отображаем экран загрузки
	ShowLoadingScreen();

	return false;
}

// Отображение экрана загрузки AJAX.
function ShowLoadingScreen()
{
	var fade_div = document.getElementById('id_admin_forms_fade');

	if (fade_div == null)
	{
		// Создаем div
		var fade_div = document.createElement("div");
		var body = document.getElementsByTagName("body")[0];
		body.appendChild(fade_div);

		fade_div.id = "id_admin_forms_fade";

		fade_div.style.zIndex = 999;

		fade_div.className = "shadowed";

		fade_div.style.position = 'absolute';
		fade_div.style.left = '50%';
		fade_div.style.top = '50%';

		var fade_div_img = document.createElement("img");
		fade_div_img.id = 'id_fade_div_img';
		fade_div_img.src = '/hostcmsfiles/images/ajax_loader.gif';
		fade_div.appendChild(fade_div_img);

		var shadowed_tl = document .createElement("div");
		shadowed_tl.className = "tl";
		fade_div.appendChild(shadowed_tl);

		var shadowed_t = document.createElement("div");
		shadowed_t.className = "t";
		fade_div.appendChild(shadowed_t);

		var shadowed_tr = document.createElement("div");
		shadowed_tr.className = "tr";
		fade_div.appendChild(shadowed_tr);

		var shadowed_l = document.createElement("div");
		shadowed_l.className = "l";
		fade_div.appendChild(shadowed_l);

		var shadowed_r = document.createElement("div");
		shadowed_r.className = "r";
		fade_div.appendChild(shadowed_r);

		var shadowed_bl = document.createElement("div");
		shadowed_bl.className = "bl";
		fade_div.appendChild(shadowed_bl);

		var shadowed_b = document.createElement("div");
		shadowed_b.className = "b";
		fade_div.appendChild(shadowed_b);

		var shadowed_br = document.createElement("div");
		shadowed_br.className = "br";
		fade_div.appendChild(shadowed_br);

		// получаем ширину выпадающего блока и устанавливаем её для верхней и нижней границы
		groupChildElements = fade_div.children;

		if (groupChildElements != undefined)
		{
			for (i = 0; i < groupChildElements.length; i++)
			{
				if(groupChildElements[i].className == 'b' | groupChildElements[i].className == 't')
				{
					groupChildElements[i].style.width = fade_div.clientWidth + 'px';
				}

				if(groupChildElements[i].className == 'r' | groupChildElements[i].className == 'l')
				{
					groupChildElements[i].style.height = fade_div.clientHeight + 'px';
				}
			}
		}

		fade_div.style.display = 'none';
	}

	// Отображаем div
	fade_div.style.display = 'block';

	var arrayPageSize = getPageSize();

	// 0 - pageWidth, 1 - pageHeight, 2 - windowWidth, 3 - windowHeight
	var arrayPageSize = getPageSize();

	// 0 - scrOfX, 1 - scrOfY
	var arrayScrollXY = getScrollXY();

	// Отображаем до определения размеров div-а
	var clientHeight = fade_div.clientHeight;
	fade_div.style.top = ((arrayPageSize[3] - clientHeight) / 2 + arrayScrollXY[1]) + 'px';

	var clientWidth = fade_div.clientWidth;
	fade_div.style.left = ((arrayPageSize[2] - clientWidth) / 2 + arrayScrollXY[0]) + 'px';
}

// Скрытие экрана загрузки AJAX.
function HideLoadingScreen()
{
	// Убераем затемнение.
	fade_div = document.getElementById('id_admin_forms_fade');

	if (typeof fade_div != 'undefined')
	{
		fade_div.style.display = "none";
	}
}

function AddLoadFileField(container_id, inpit_prefix)
{
	cbItem = document.getElementById(container_id);

	if (cbItem)
	{
		// Получаем все input-ы
		element_array = cbItem.getElementsByTagName("input");

		count_input = element_array.length;

		// <br/>
		var ElementBr = document.createElement("br");
		cbItem.appendChild(ElementBr);

		//<input
		var ElementInput = document.createElement("input");
		ElementInput.setAttribute("size", "30");
		ElementInput.setAttribute("name", inpit_prefix + (count_input + 1));
		ElementInput.setAttribute("type", "file");
		ElementInput.setAttribute("title", "Прикрепить файл");
		//ElementInput.setAttribute("style", "margin-bottom: 20px");
		cbItem.appendChild(ElementInput);
	}
}

// action - адрес страницы для запрос
// method - GET, POST, null - автоматическое определение
// callback_function - функция обратного вызова, которая будет вызвана после получения ответа от backenad-а
function sendBackgroundRequest(action, method, callback_function)
{
	var req = new JsHttpRequest();

	// Этот код вызовется автоматически, когда загрузка данных завершится.
	req.onreadystatechange = function()
	{
		if (req.readyState == 4)
		{
			// Возвращаем обычный курсор
			document.body.style.cursor = '';

			if (typeof callback_function != 'undefined')
			{
				callback_function(req.responseJS);
			}

			return true;
		}
	}

	req.open(method, action, true);

	// Отсылаем данные в обработчик.
	req.send(null);

	// Курсор ставим на часики.
	document.body.style.cursor = "wait";
	
	ShowLoadingScreen();
}

var prev_comment = 0;

// Ответ на комментарий
function cr(comment_id)
{
	if (prev_comment && prev_comment != comment_id)
	{
		document.getElementById(prev_comment).style.display = 'none';
	}

	var div = document.getElementById(comment_id);
	
	if (div.style.display != 'block')
	{
		div.style.display = 'block';
	}
	else
	{
		div.style.display = 'none';
	}

	prev_comment = comment_id;
}

var temp_ChildId = '';
var temp_CurrenElementId = '';
var menu_timeout_id = 0;
var filter_timeout_id = 0;

// обработчик наведения мыши на меню
function TopMenuOver(CurrenElementId, ChildId)
{
	clearTimeout(menu_timeout_id);

	if (temp_CurrenElementId != ''
	&& temp_CurrenElementId != CurrenElementId)
	{
		var oTemp_ChildId = document.getElementById(temp_ChildId);

		if (oTemp_ChildId)
		{
			oTemp_ChildId.style.display = "none";
		}
	}

	temp_ChildId = ChildId;
	temp_CurrenElementId = CurrenElementId;

	if (CurrenElementId == undefined)
	{
		return false;
	}

	if (ChildId != '')
	{
		var oChildId = document.getElementById(ChildId);

		if (oChildId)
		{
			oChildId.style.display = "block";
			//oChildId.style.opacity = 0.4;
			//	oChildId.style.filter = 'alpha(opacity=100, style=1, finishopacity=60)';
			//oChildId.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=0, style=0)";
		}
	}
}

// обработчик уведения мыши с меню
function TopMenuOut(CurrenElementId, ChildId)
{
	if (CurrenElementId == undefined)
	{
		return false;
	}

	if (ChildId != '')
	{
		var oChildId = document.getElementById(ChildId);
		if (oChildId)
		{
			menu_timeout_id = setTimeout(function (){oChildId.style.display = "none"}, 300);
		}
	}
}

// Функция обратного вызова для AddIntoCart
function callbackfunction_AddIntoCart(responseJS)
{
	// Результат принят
	sended_request = false;
	
	if (typeof responseJS != 'undefined')
	{
		// Данные.
		if (typeof responseJS.cart != 'undefined')
		{
			html = responseJS.cart;

			var little_cart = document.getElementById('little_cart');
			
			if (little_cart)
			{
				little_cart.innerHTML = html;
			}
			else
			{
				alert('Ошибка! Краткая корзина не найдена');
			}
		}
	}
}

function AddIntoCart(shop_path, item_id, item_count)
{
	//location.href = shop_path + 'cart/?ajax_add_item_id=' + item_id + '&count=' + item_count;
	cmsrequest = shop_path + 'cart/?ajax_add_item_id=' + item_id + '&count=' + item_count;
	
	// Отправляем запрос backend-у
	sendRequest(cmsrequest, 'get', callbackfunction_AddIntoCart);
	
	return false;
}

// Установка или снятие всех флажков для checkbox'ов элементов.
function SelectAllItems(ASelect, prefix)
{
	element_array = document.getElementsByTagName("input");
	if (element_array.length > 0)
	{
		for (var i = 0; i < element_array.length; i++)
		{
			if (element_array[i].name.search(prefix) != -1)
			{
				// Устанавливаем checked
				element_array[i].checked = ASelect;
			}
		}

	}
}

if (document.images)
{	
    var img = new Object();

    img["tl_angle_pull_down"] = new Image();	
    img["tl_angle_pull_down"].src = '/images/tl_angle_pull_down.png';

    img["tr_angle_pull_down"] = new Image();	
    img["tr_angle_pull_down"].src = '/images/tr_angle_pull_down.png';

    img["bl_angle_pull_down"] = new Image();	
    img["bl_angle_pull_down"].src = '/images/bl_angle_pull_down.png';

    img["br_angle_pull_down"] = new Image();	
    img["br_angle_pull_down"].src = '/images/br_angle_pull_down.png';
}

/**
* JsHttpRequest: JavaScript "AJAX" data loader
*
* @license LGPL
* @author Dmitry Koterov, http://en.dklab.ru/lib/JsHttpRequest/
* @version 5.x $Id$
*/

// {{{
function JsHttpRequest() {
	// Standard properties.
	var t = this;
	t.onreadystatechange = null;
	t.readyState         = 0;
	t.responseText       = null;
	t.responseXML        = null;
	t.status             = 200;
	t.statusText         = "OK";
	// JavaScript response array/hash
	t.responseJS         = null;

	// Additional properties.
	t.caching            = false;        // need to use caching?
	t.loader             = null;         // loader to use ('form', 'script', 'xml'; null - autodetect)
	t.session_name       = "PHPSESSID";  // set to SID cookie or GET parameter name

	// Internals.
	t._ldObj              = null;  // used loader object
	t._reqHeaders        = [];    // collected request headers
	t._openArgs          = null;  // parameters from open()
	t._errors = {
		inv_form_el:        'Invalid FORM element detected: name=%, tag=%',
		must_be_single_el:  'If used, <form> must be a single HTML element in the list.',
		js_invalid:         'JavaScript code generated by backend is invalid!\n%',
		url_too_long:       'Cannot use so long query with GET request (URL is larger than % bytes)',
		unk_loader:         'Unknown loader: %',
		no_loaders:         'No loaders registered at all, please check JsHttpRequest.LOADERS array',
		no_loader_matched:  'Cannot find a loader which may process the request. Notices are:\n%'
	}

	/**
	* Aborts the request. Behaviour of this function for onreadystatechange()
	* is identical to IE (most universal and common case). E.g., readyState -> 4
	* on abort() after send().
	*/
	t.abort = function() { with (this) {
		if (_ldObj && _ldObj.abort) _ldObj.abort();
		_cleanup();
		if (readyState == 0) {
			// start->abort: no change of readyState (IE behaviour)
			return;
		}
		if (readyState == 1 && !_ldObj) {
			// open->abort: no onreadystatechange call, but change readyState to 0 (IE).
			// send->abort: change state to 4 (_ldObj is not null when send() is called)
			readyState = 0;
			return;
		}
		_changeReadyState(4, true); // 4 in IE & FF on abort() call; Opera does not change to 4.
	}}

	/**
	* Prepares the object for data loading.
	* You may also pass URLs like "GET url" or "script.GET url".
	*/
	t.open = function(method, url, asyncFlag, username, password) { with (this) {
		
		// Extract methor and loader from the URL (if present).
		if (url.match(/^((\w+)\.)?(GET|POST)\s+(.*)/i)) {
			this.loader = RegExp.$2? RegExp.$2 : null;
			method = RegExp.$3;
			url = RegExp.$4;
		}
		// Append SID to original URL. Use try...catch for security problems.
		try {
			if (
			document.location.search.match(new RegExp('[&?]' + session_name + '=([^&?]*)'))
			|| document.cookie.match(new RegExp('(?:;|^)\\s*' + session_name + '=([^;]*)'))
			) {
				url += (url.indexOf('?') >= 0? '&' : '?') + session_name + "=" + this.escape(RegExp.$1);
			}
		} catch (e) {}
		// Store open arguments to hash.
		_openArgs = {
			method:     (method || '').toUpperCase(),
			url:        url,
			asyncFlag:  asyncFlag,
			username:   username != null? username : '',
			password:   password != null? password : ''
		}
		_ldObj = null;
		_changeReadyState(1, true); // compatibility with XMLHttpRequest
		return true;
	}}

	/**
	* Sends a request to a server.
	*/
	t.send = function(content) {
		if (!this.readyState) {
			// send without open or after abort: no action (IE behaviour).
			return;
		}
		this._changeReadyState(1, true); // compatibility with XMLHttpRequest
		this._ldObj = null;

		// Prepare to build QUERY_STRING from query hash.
		var queryText = [];
		var queryElem = [];


		if (!this._hash2query(content, null, queryText, queryElem)) return;

		// Solve the query hashcode & return on cache hit.
		var hash = null;
		if (this.caching && !queryElem.length) {
			hash = this._openArgs.username + ':' + this._openArgs.password + '@' + this._openArgs.url + '|' + queryText + "#" + this._openArgs.method;
			var cache = JsHttpRequest.CACHE[hash];
			if (cache) {
				this._dataReady(cache[0], cache[1]);
				return false;
			}
		}

		// Try all the loaders.
		var loader = (this.loader || '').toLowerCase();
		if (loader && !JsHttpRequest.LOADERS[loader]) return this._error('unk_loader', loader);
		var errors = [];
		var lds = JsHttpRequest.LOADERS;
		for (var tryLoader in lds) {
			var ldr = lds[tryLoader].loader;
			if (!ldr) continue; // exclude possibly derived prototype properties from "for .. in".
			if (loader && tryLoader != loader) continue;
			// Create sending context.
			var ldObj = new ldr(this);
			JsHttpRequest.extend(ldObj, this._openArgs);
			JsHttpRequest.extend(ldObj, {
				queryText:  queryText.join('&'),
				queryElem:  queryElem,
				id:         (new Date().getTime()) + "" + JsHttpRequest.COUNT++,
				hash:       hash,
				span:       null
			});
			var error = ldObj.load();
			if (!error) {
				// Save loading script.
				this._ldObj = ldObj;
				JsHttpRequest.PENDING[ldObj.id] = this;
				return true;
			}
			if (!loader) {
				errors[errors.length] = '- ' + tryLoader.toUpperCase() + ': ' + this._l(error);
			} else {
				return this._error(error);
			}
		}

		// If no loader matched, generate error message.
		return tryLoader? this._error('no_loader_matched', errors.join('\n')) : this._error('no_loaders');
	}

	/**
	* Returns all response headers (if supported).
	*/
	t.getAllResponseHeaders = function() { with (this) {
		return _ldObj && _ldObj.getAllResponseHeaders? _ldObj.getAllResponseHeaders() : [];
	}}

	/**
	* Returns one response header (if supported).
	*/
	t.getResponseHeader = function(label) { with (this) {
		return _ldObj && _ldObj.getResponseHeader? _ldObj.getResponseHeader(label) : null;
	}}

	/**
	* Adds a request header to a future query.
	*/
	t.setRequestHeader = function(label, value) { with (this) {
		_reqHeaders[_reqHeaders.length] = [label, value];
	}}

	//
	// Internal functions.
	//

	/**
	* Do all the work when a data is ready.
	*/
	t._dataReady = function(text, js) { with (this) {
		if (caching && _ldObj) JsHttpRequest.CACHE[_ldObj.hash] = [text, js];
		responseText = responseXML = text;
		responseJS = js;
		if (js !== null) {
			status = 200;
			statusText = "OK";
		} else {
			status = 500;
			statusText = "Internal Server Error";
		}
		_changeReadyState(2);
		_changeReadyState(3);
		_changeReadyState(4);
		_cleanup();
	}}

	/**
	* Analog of sprintf(), but translates the first parameter by _errors.
	*/
	t._l = function(args) {
		var i = 0, p = 0, msg = this._errors[args[0]];
		// Cannot use replace() with a callback, because it is incompatible with IE5.
		while ((p = msg.indexOf('%', p)) >= 0) {
			var a = args[++i] + "";
			msg = msg.substring(0, p) + a + msg.substring(p + 1, msg.length);
			p += 1 + a.length;
		}
		return msg;
	}

	/**
	* Called on error.
	*/
	t._error = function(msg) {
		msg = this._l(typeof(msg) == 'string'? arguments : msg)
		msg = "JsHttpRequest: " + msg;
		if (!window.Error) {
			// Very old browser...
			throw msg;
		} else if ((new Error(1, 'test')).description == "test") {
			// We MUST (!!!) pass 2 parameters to the Error() constructor for IE5.
			throw new Error(1, msg);
		} else {
			// Mozilla does not support two-parameter call style.
			throw new Error(msg);
		}
	}

	/**
	* Convert hash to QUERY_STRING.
	* If next value is scalar or hash, push it to queryText.
	* If next value is form element, push [name, element] to queryElem.
	*/
	t._hash2query = function(content, prefix, queryText, queryElem) {
		if (prefix == null) prefix = "";
		if((''+typeof(content)).toLowerCase() == 'object') {
			var formAdded = false;
			if (content && content.parentNode && content.parentNode.appendChild && content.tagName && content.tagName.toUpperCase() == 'FORM') {
				content = { form: content };
			}
			for (var k in content) {
				var v = content[k];
				if (v instanceof Function) continue;
				var curPrefix = prefix? prefix + '[' + this.escape(k) + ']' : this.escape(k);
				var isFormElement = v && v.parentNode && v.parentNode.appendChild && v.tagName;

				if (isFormElement) {
					var tn = v.tagName.toUpperCase();

					if (tn == 'FORM') {
						// FORM itself is passed.
						formAdded = true;
					} else if (tn == 'INPUT' || tn == 'TEXTAREA' || tn == 'SELECT') {
						// This is a single form elemenent.
					} else {
						return this._error('inv_form_el', (v.name||''), v.tagName);
					}

					queryElem[queryElem.length] = { name: curPrefix, e: v };
				} else if (v instanceof Object) {
					this._hash2query(v, curPrefix, queryText, queryElem);
				} else {
					// We MUST skip NULL values, because there is no method
					// to pass NULL's via GET or POST request in PHP.
					if (v === null) continue;
					// Convert JS boolean true and false to corresponding PHP values.
					if (v === true) v = 1;
					if (v === false) v = '';
					queryText[queryText.length] = curPrefix + "=" + this.escape('' + v);
				}
				if (formAdded && queryElem.length > 1) {
					return this._error('must_be_single_el');
				}
			}
		} else {
			queryText[queryText.length] = content;
		}
		return true;
	}

	/**
	* Remove last used script element (clean memory).
	*/
	t._cleanup = function() {
		var ldObj = this._ldObj;
		if (!ldObj) return;
		// Mark this loading as aborted.
		JsHttpRequest.PENDING[ldObj.id] = false;
		var span = ldObj.span;
		if (!span) return;
		ldObj.span = null;
		var closure = function() {
			span.parentNode.removeChild(span);
		}
		// IE5 crashes on setTimeout(function() {...}, ...) construction! Use tmp variable.
		JsHttpRequest.setTimeout(closure, 50);
	}

	/**
	* Change current readyState and call trigger method.
	*/
	t._changeReadyState = function(s, reset) { with (this) {
		if (reset) {
			status = statusText = responseJS = null;
			responseText = '';
		}
		readyState = s;
		if (onreadystatechange) onreadystatechange();
	}}

	/**
	* JS escape() does not quote '+'.
	*/
	t.escape = function(s) {
		return escape(s).replace(new RegExp('\\+','g'), '%2B');
	}
}


// Global library variables.
JsHttpRequest.COUNT = 0;              // unique ID; used while loading IDs generation
JsHttpRequest.MAX_URL_LEN = 2000;     // maximum URL length
JsHttpRequest.CACHE = {};             // cached data
JsHttpRequest.PENDING = {};           // pending loadings
JsHttpRequest.LOADERS = {};           // list of supported data loaders (filled at the bottom of the file)
JsHttpRequest._dummy = function() {}; // avoid memory leaks


/**
* These functions are dirty hacks for IE 5.0 which does not increment a
* reference counter for an object passed via setTimeout(). So, if this
* object (closure function) is out of scope at the moment of timeout
* applying, IE 5.0 crashes.
*/

/**
* Timeout wrappers storage. Used to avoid zeroing of referece counts in IE 5.0.
* Please note that you MUST write "window.setTimeout", not "setTimeout", else
* IE 5.0 crashes again. Strange, very strange...
*/
JsHttpRequest.TIMEOUTS = { s: window.setTimeout, c: window.clearTimeout };

/**
* Wrapper for IE5 buggy setTimeout.
* Use this function instead of a usual setTimeout().
*/
JsHttpRequest.setTimeout = function(func, dt) {
	// Always save inside the window object before a call (for FF)!
	window.JsHttpRequest_tmp = JsHttpRequest.TIMEOUTS.s;
	if (typeof(func) == "string") {
		id = window.JsHttpRequest_tmp(func, dt);
	} else {
		var id = null;
		var mediator = function() {
			func();
			delete JsHttpRequest.TIMEOUTS[id]; // remove circular reference
		}
		id = window.JsHttpRequest_tmp(mediator, dt);
		// Store a reference to the mediator function to the global array
		// (reference count >= 1); use timeout ID as an array key;
		JsHttpRequest.TIMEOUTS[id] = mediator;
	}
	window.JsHttpRequest_tmp = null; // no delete() in IE5 for window
	return id;
}

/**
* Complimental wrapper for clearTimeout.
* Use this function instead of usual clearTimeout().
*/
JsHttpRequest.clearTimeout = function(id) {
	window.JsHttpRequest_tmp = JsHttpRequest.TIMEOUTS.c;
	delete JsHttpRequest.TIMEOUTS[id]; // remove circular reference
	var r = window.JsHttpRequest_tmp(id);
	window.JsHttpRequest_tmp = null; // no delete() in IE5 for window
	return r;
}


/**
* Global static function.
* Simple interface for most popular use-cases.
* You may also pass URLs like "GET url" or "script.GET url".
*/
JsHttpRequest.query = function(url, content, onready, nocache) {
	var req = new this();
	req.caching = !nocache;
	req.onreadystatechange = function() {
		if (req.readyState == 4) {
			onready(req.responseJS, req.responseText);
		}
	}
	req.open(null, url, true);
	req.send(content);
}


/**
* Global static function.
* Called by server backend script on data load.
*/
JsHttpRequest.dataReady = function(d) {
	var th = this.PENDING[d.id];
	delete this.PENDING[d.id];
	if (th) {
		th._dataReady(d.text, d.js);
	} else if (th !== false) {
		throw "dataReady(): unknown pending id: " + d.id;
	}
}


// Adds all the properties of src to dest.
JsHttpRequest.extend = function(dest, src) {
	for (var k in src) dest[k] = src[k];
}

/**
* Each loader has the following properties which must be initialized:
* - method
* - url
* - asyncFlag (ignored)
* - username
* - password
* - queryText (string)
* - queryElem (array)
* - id
* - hash
* - span
*/

// }}}

// {{{ xml
// Loader: XMLHttpRequest or ActiveX.
// [+] GET and POST methods are supported.
// [+] Most native and memory-cheap method.
// [+] Backend data can be browser-cached.
// [-] Cannot work in IE without ActiveX.
// [-] No support for loading from different domains.
// [-] No uploading support.
//
JsHttpRequest.LOADERS.xml = { loader: function(req) {
	JsHttpRequest.extend(req._errors, {
		xml_no:          'Cannot use XMLHttpRequest or ActiveX loader: not supported',
		xml_no_diffdom:  'Cannot use XMLHttpRequest to load data from different domain %',
		xml_no_headers:  'Cannot use XMLHttpRequest loader or ActiveX loader, POST method: headers setting is not supported, needed to work with encodings correctly',
		xml_no_form_upl: 'Cannot use XMLHttpRequest loader: direct form elements using and uploading are not implemented'
	});

	this.load = function() {
		if (this.queryElem.length) return ['xml_no_form_upl'];

		// XMLHttpRequest (and MS ActiveX'es) cannot work with different domains.
		if (this.url.match(new RegExp('^([a-z]+://[^\\/]+)(.*)', 'i'))) {
			// We MUST also check if protocols matched: cannot send from HTTP
			// to HTTPS and vice versa.
			if (RegExp.$1.toLowerCase() != document.location.protocol + '//' + document.location.hostname.toLowerCase()) {
				return ['xml_no_diffdom', RegExp.$1];
			}
		}

		// Try to obtain a loader.
		var xr = null;
		if (window.XMLHttpRequest) {
			try { xr = new XMLHttpRequest() } catch(e) {}
		} else if (window.ActiveXObject) {
			try { xr = new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {}
			if (!xr) try { xr = new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
		}
		if (!xr) return ['xml_no'];

		// Loading method detection. We cannot POST if we cannot set "octet-stream"
		// header, because we need to process the encoded data in the backend manually.
		var canSetHeaders = window.ActiveXObject || xr.setRequestHeader;
		if (!this.method) this.method = canSetHeaders && this.queryText.length? 'POST' : 'GET';

		// Build & validate the full URL.
		if (this.method == 'GET') {
			if (this.queryText) this.url += (this.url.indexOf('?') >= 0? '&' : '?') + this.queryText;
			this.queryText = '';
			if (this.url.length > JsHttpRequest.MAX_URL_LEN) return ['url_too_long', JsHttpRequest.MAX_URL_LEN];
		} else if (this.method == 'POST' && !canSetHeaders) {
			return ['xml_no_headers'];
		}

		// Add ID to the url if we need to disable the cache.
		this.url += (this.url.indexOf('?') >= 0? '&' : '?') + 'JsHttpRequest=' + (req.caching? '0' : this.id) + '-xml';

		// Assign the result handler.
		var id = this.id;
		xr.onreadystatechange = function() {
			if (xr.readyState != 4) return;
			// Avoid memory leak by removing the closure.
			xr.onreadystatechange = JsHttpRequest._dummy;
			req.status = null;
			try {
				// In case of abort() call, xr.status is unavailable and generates exception.
				// But xr.readyState equals to 4 in this case. Stupid behaviour. :-(
				req.status = xr.status;
				req.responseText = xr.responseText;
			} catch (e) {}
			if (!req.status) return;
			try {
				// Prepare generator function & catch syntax errors on this stage.
				eval('JsHttpRequest._tmp = function(id) { var d = ' + req.responseText + '; d.id = id; JsHttpRequest.dataReady(d); }');
			} catch (e) {
				// Note that FF 2.0 does not throw any error from onreadystatechange handler.
				return req._error('js_invalid', req.responseText)
			}
			// Call associated dataReady() outside the try-catch block
			// to pass exceptions in onreadystatechange in usual manner.
			JsHttpRequest._tmp(id);
			JsHttpRequest._tmp = null;
		};

		// Open & send the request.
		xr.open(this.method, this.url, true, this.username, this.password);
		if (canSetHeaders) {
			// Pass pending headers.
			for (var i = 0; i < req._reqHeaders.length; i++) {
				xr.setRequestHeader(req._reqHeaders[i][0], req._reqHeaders[i][1]);
			}
			// Set non-default Content-type. We cannot use
			// "application/x-www-form-urlencoded" here, because
			// in PHP variable HTTP_RAW_POST_DATA is accessible only when
			// enctype is not default (e.g., "application/octet-stream"
			// is a good start). We parse POST data manually in backend
			// library code. Note that Safari sets by default "x-www-form-urlencoded"
			// header, but FF sets "text/xml" by default.
			xr.setRequestHeader('Content-Type', 'application/octet-stream');
		}
		xr.send(this.queryText);

		// No SPAN is used for this loader.
		this.span = null;
		this.xr = xr; // save for later usage on abort()

		// Success.
		return null;
	}

	// Override req.getAllResponseHeaders method.
	this.getAllResponseHeaders = function() {
		return this.xr.getAllResponseHeaders();
	}

	// Override req.getResponseHeader method.
	this.getResponseHeader = function(label) {
		return this.xr.getResponseHeader(label);
	}

	this.abort = function() {
		this.xr.abort();
		this.xr = null;
	}
}}
// }}}


// {{{ script
// Loader: SCRIPT tag.
// [+] Most cross-browser.
// [+] Supports loading from different domains.
// [-] Only GET method is supported.
// [-] No uploading support.
// [-] Backend data cannot be browser-cached.
//
JsHttpRequest.LOADERS.script = { loader: function(req) {
	JsHttpRequest.extend(req._errors, {
		script_only_get:   'Cannot use SCRIPT loader: it supports only GET method',
		script_no_form:    'Cannot use SCRIPT loader: direct form elements using and uploading are not implemented'
	})

	this.load = function() {
		// Move GET parameters to the URL itself.
		if (this.queryText) this.url += (this.url.indexOf('?') >= 0? '&' : '?') + this.queryText;
		this.url += (this.url.indexOf('?') >= 0? '&' : '?') + 'JsHttpRequest=' + this.id + '-' + 'script';
		this.queryText = '';

		if (!this.method) this.method = 'GET';
		if (this.method !== 'GET') return ['script_only_get'];
		if (this.queryElem.length) return ['script_no_form'];
		if (this.url.length > JsHttpRequest.MAX_URL_LEN) return ['url_too_long', JsHttpRequest.MAX_URL_LEN];

		var th = this, d = document, s = null, b = d.body;
		if (!window.opera) {
			// Safari, IE, FF, Opera 7.20.
			this.span = s = d.createElement('SCRIPT');
			var closure = function() {
				s.language = 'JavaScript';
				if (s.setAttribute) s.setAttribute('src', th.url); else s.src = th.url;
				b.insertBefore(s, b.lastChild);
			}
		} else {
			// Oh shit! Damned stupid Opera 7.23 does not allow to create SCRIPT
			// element over createElement (in HEAD or BODY section or in nested SPAN -
			// no matter): it is created deadly, and does not response the href assignment.
			// So - always create SPAN.
			this.span = s = d.createElement('SPAN');
			s.style.display = 'none';
			b.insertBefore(s, b.lastChild);
			s.innerHTML = 'Workaround for IE.<s'+'cript></' + 'script>';
			var closure = function() {
				s = s.getElementsByTagName('SCRIPT')[0]; // get with timeout!
				s.language = 'JavaScript';
				if (s.setAttribute) s.setAttribute('src', th.url); else s.src = th.url;
			}
		}
		JsHttpRequest.setTimeout(closure, 10);

		// Success.
		return null;
	}
}}
// }}}


// {{{ form
// Loader: FORM & IFRAME.
// [+] Supports file uploading.
// [+] GET and POST methods are supported.
// [+] Supports loading from different domains.
// [-] Uses a lot of system resources.
// [-] Backend data cannot be browser-cached.
// [-] Pollutes browser history on some old browsers.
//
JsHttpRequest.LOADERS.form = { loader: function(req) {
	JsHttpRequest.extend(req._errors, {
		form_el_not_belong:  'Element "%" does not belong to any form!',
		form_el_belong_diff: 'Element "%" belongs to a different form. All elements must belong to the same form!',
		form_el_inv_enctype: 'Attribute "enctype" of the form must be "%" (for IE), "%" given.'
	})

	this.load = function() {
		var th = this;

		if (!th.method) th.method = 'POST';
		th.url += (th.url.indexOf('?') >= 0? '&' : '?') + 'JsHttpRequest=' + th.id + '-' + 'form';

		// If GET, build full URL. Then copy QUERY_STRING to queryText.
		if (th.method == 'GET') {
			if (th.queryText) th.url += (th.url.indexOf('?') >= 0? '&' : '?') + th.queryText;
			if (th.url.length > JsHttpRequest.MAX_URL_LEN) return ['url_too_long', JsHttpRequest.MAX_URL_LEN];
			var p = th.url.split('?', 2);
			th.url = p[0];
			th.queryText = p[1] || '';
		}

		// Check if all form elements belong to same form.
		var form = null;
		var wholeFormSending = false;
		if (th.queryElem.length) {
			if (th.queryElem[0].e.tagName.toUpperCase() == 'FORM') {
				// Whole FORM sending.
				form = th.queryElem[0].e;
				wholeFormSending = true;
				th.queryElem = [];
			} else {
				// If we have at least one form element, we use its FORM as a POST container.
				form = th.queryElem[0].e.form;
				// Validate all the elements.
				for (var i = 0; i < th.queryElem.length; i++) {
					var e = th.queryElem[i].e;
					if (!e.form) {
						return ['form_el_not_belong', e.name];
					}
					if (e.form != form) {
						return ['form_el_belong_diff', e.name];
					}
				}
			}

			// Check enctype of the form.
			if (th.method == 'POST') {
				var need = "multipart/form-data";
				var given = (form.attributes.encType && form.attributes.encType.nodeValue) || (form.attributes.enctype && form.attributes.enctype.value) || form.enctype;
				if (given != need) {
					return ['form_el_inv_enctype', need, given];
				}
			}
		}

		// Create invisible IFRAME with temporary form (form is used on empty queryElem).
		// We ALWAYS create th IFRAME in the document of the form - for Opera 7.20.
		var d = form && (form.ownerDocument || form.document) || document;
		var ifname = 'jshr_i_' + th.id;
		var s = th.span = d.createElement('DIV');
		s.style.position = 'absolute';
		s.style.display = 'none';
		s.style.visibility = 'hidden';
		s.innerHTML =
		(form? '' : '<form' + (th.method == 'POST'? ' enctype="multipart/form-data" method="post"' : '') + '></form>') + // stupid IE, MUST use innerHTML assignment :-(
		'<iframe name="' + ifname + '" id="' + ifname + '" style="width:0px; height:0px; overflow:hidden; border:none"></iframe>'
		if (!form) {
			form = th.span.firstChild;
		}

		// Insert generated form inside the document.
		// Be careful: don't forget to close FORM container in document body!
		d.body.insertBefore(s, d.body.lastChild);

		// Function to safely set the form attributes. Parameter attr is NOT a hash
		// but an array, because "for ... in" may badly iterate over derived attributes.
		var setAttributes = function(e, attr) {
			var sv = [];
			var form = e;
			// This strange algorythm is needed, because form may  contain element
			// with name like 'action'. In IE for such attribute will be returned
			// form element node, not form action. Workaround: copy all attributes
			// to new empty form and work with it, then copy them back. This is
			// THE ONLY working algorythm since a lot of bugs in IE5.0 (e.g.
			// with e.attributes property: causes IE crash).
			if (e.mergeAttributes) {
				var form = d.createElement('form');
				form.mergeAttributes(e, false);
			}
			for (var i = 0; i < attr.length; i++) {
				var k = attr[i][0], v = attr[i][1];
				// TODO: http://forum.dklab.ru/viewtopic.php?p=129059#129059
				sv[sv.length] = [k, form.getAttribute(k)];
				form.setAttribute(k, v);
			}
			if (e.mergeAttributes) {
				e.mergeAttributes(form, false);
			}
			return sv;
		}

		// Run submit with delay - for old Opera: it needs some time to create IFRAME.
		var closure = function() {
			// Save JsHttpRequest object to new IFRAME.
			top.JsHttpRequestGlobal = JsHttpRequest;

			// Disable ALL the form elements.
			var savedNames = [];
			if (!wholeFormSending) {
				for (var i = 0, n = form.elements.length; i < n; i++) {
					savedNames[i] = form.elements[i].name;
					form.elements[i].name = '';
				}
			}

			// Insert hidden fields to the form.
			var qt = th.queryText.split('&');
			for (var i = qt.length - 1; i >= 0; i--) {
				var pair = qt[i].split('=', 2);
				var e = d.createElement('INPUT');
				e.type = 'hidden';
				e.name = unescape(pair[0]);
				e.value = pair[1] != null? unescape(pair[1]) : '';
				form.appendChild(e);
			}


			// Change names of along user-passed form elements.
			for (var i = 0; i < th.queryElem.length; i++) {
				th.queryElem[i].e.name = th.queryElem[i].name;
			}

			// Temporary modify form attributes, submit form, restore attributes back.
			var sv = setAttributes(
			form,
			[
			['action',   th.url],
			['method',   th.method],
			['onsubmit', null],
			['target',   ifname]
			]
			);
			form.submit();
			setAttributes(form, sv);

			// Remove generated temporary hidden elements from the top of the form.
			for (var i = 0; i < qt.length; i++) {
				// Use "form.firstChild.parentNode", not "form", or IE5 crashes!
				form.lastChild.parentNode.removeChild(form.lastChild);
			}
			// Enable all disabled elements back.
			if (!wholeFormSending) {
				for (var i = 0, n = form.elements.length; i < n; i++) {
					form.elements[i].name = savedNames[i];
				}
			}
		}
		JsHttpRequest.setTimeout(closure, 100);

		// Success.
		return null;
	}
}}
// }}}


// Кроссбраузерная функция получения размеров экрана,
// используется в функции ShowLoadingScreen.
function getPageSize()
{
	var xScroll, yScroll;

	if (window.innerHeight && window.scrollMaxY)
	{
		xScroll = window.innerWidth + window.scrollMaxX;
		yScroll = window.innerHeight + window.scrollMaxY;
	}
	else if (document.body.scrollHeight > document.body.offsetHeight)
	{ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	}
	else
	{ // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}

	var windowWidth, windowHeight;

	if (self.innerHeight)
	{
		// all except Explorer
		if(document.documentElement.clientWidth)
		{
			windowWidth = document.documentElement.clientWidth;
		}
		else
		{
			windowWidth = self.innerWidth;
		}
		windowHeight = self.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientHeight)
	{ // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	}
	else if (document.body)
	{ // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}

	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight)
	{
		pageHeight = windowHeight;
	}
	else
	{
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth)
	{
		pageWidth = xScroll;
	}
	else
	{
		pageWidth = windowWidth;
	}

	arrayPageSize = new Array(pageWidth, pageHeight, windowWidth, windowHeight);
	return arrayPageSize;
}

// Получение информации о позиции скрола
function getScrollXY()
{
	var scrOfX = 0, scrOfY = 0;

	if (typeof(window.pageYOffset ) == 'number' )
	{
		//Netscape
		scrOfY = window.pageYOffset;
		scrOfX = window.pageXOffset;
	}
	else if (document.body && (document.body.scrollLeft || document.body.scrollTop))
	{
		//DOM
		scrOfY = document.body.scrollTop;
		scrOfX = document.body.scrollLeft;
	}
	else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop))
	{
		//IE6
		scrOfY = document.documentElement.scrollTop;
		scrOfX = document.documentElement.scrollLeft;
	}

	return [ scrOfX, scrOfY ];
}

function CreateWindow(windowId, windowTitle, windowWidth, windowHeight)
{
	var windowDiv = document.getElementById(windowId);

	if (windowDiv == undefined)
	{
		// Создаем div для окна
		var fade_div = document.createElement("div");
		fade_div.setAttribute("id", windowId);
		var body = document.getElementsByTagName("body")[0];
		windowDiv = body.appendChild(fade_div);
	}

	// Тень
	windowDiv.className = "shadowed";

	if (windowWidth == '')
	{
		windowWidth = '300px';
	}

	windowDiv.style.width = windowWidth;

	if (windowHeight != '')
	{
		windowDiv.style.height = windowHeight;
	}

	var shadowed_tl = document.createElement("div");
	shadowed_tl.className = "tl";
	windowDiv.appendChild(shadowed_tl);

	var shadowed_t = document.createElement("div");
	shadowed_t.className = "t";
	windowDiv.appendChild(shadowed_t);

	var shadowed_tr = document.createElement("div");
	shadowed_tr.className = "tr";
	windowDiv.appendChild(shadowed_tr);

	var shadowed_l = document.createElement("div");
	shadowed_l.className = "l";
	windowDiv.appendChild(shadowed_l);

	var shadowed_r = document.createElement("div");
	shadowed_r.className = "r";
	windowDiv.appendChild(shadowed_r);

	var shadowed_bl = document.createElement("div");
	shadowed_bl.className = "bl";
	windowDiv.appendChild(shadowed_bl);

	var shadowed_b = document.createElement("div");
	shadowed_b.className = "b";
	windowDiv.appendChild(shadowed_b);

	var shadowed_br = document.createElement("div");
	shadowed_br.className = "br";
	windowDiv.appendChild(shadowed_br);

	// Верхняя полосочка(для отображения пустого заголовка передать ' ' - пробел)
	if(windowTitle != '')
	{
		var topbar = document.createElement("div");
		topbar.className = "topbar";
		windowDiv.insertBefore(topbar, windowDiv.childNodes[0]);
	}

	windowDiv.style.display = "none";

	// Закрыть
	var wclose_img = document.createElement("img");
	wclose_img.src = '/hostcmsfiles/images/wclose.gif';

	wclose_img.onclick = function() {HideWindow(windowId); };

	if(windowTitle != '')
	{
		topbar.appendChild(wclose_img);

		// Заголовок окна
		var textNode = document.createTextNode(windowTitle);
		topbar.appendChild(textNode);
	}
}

// Отображает/скрывает окно
function SlideWindow(windowId)
{
	var windowDiv = document.getElementById(windowId);

	if (windowDiv == undefined)
	{
		return false;
	}

	if (windowDiv.style.display == "block")
	{
		HideWindow(windowId);
	}
	else
	{
		ShowWindow(windowId);
	}
}

var prev_window = 0;

function ShowWindow(windowId)
{
	var windowDiv = document.getElementById(windowId);

	if (windowDiv == undefined)
	{
		return false;
	}

	// Добавлено  && windowId.indexOf('edit_window_') == 0 для того, чтобы при отображении всплывающего окошка с настройками изображения не закрывалось всплывающее окно ЦА
	if (prev_window && prev_window != windowId && (windowId.indexOf('edit_window_') == 0 || prev_window.indexOf('edit_window_') !== 0))
	{
		HideWindow(prev_window);
	}

	prev_window = windowId;

	// 0 - pageWidth, 1 - pageHeight, 2 - windowWidth, 3 - windowHeight
	var arrayPageSize = getPageSize();

	// 0 - scrOfX, 1 - scrOfY
	var arrayScrollXY = getScrollXY();

	// Отображаем до определения размеров div-а
	windowDiv.style.display = 'block';

	var clientHeight = windowDiv.clientHeight;
	var clientWidth = windowDiv.clientWidth;

	// Если высота div-а больше высоты окна
	if (clientHeight > arrayPageSize[3])
	{
		// Положим высоту равной 90% высоты окна
		clientHeight = Math.round(arrayPageSize[3] * 0.9);
	}

	// Если ширина div-а больше ширины окна
	if (clientWidth > arrayPageSize[2])
	{
		// Положим ширину равной 90% высоты окна
		clientWidth = Math.round(arrayPageSize[2] * 0.9);
	}

	windowDiv.style.top = ((arrayPageSize[3] - clientHeight) / 2 + arrayScrollXY[1]) + 'px';

	windowDiv.style.left = ((arrayPageSize[2] - clientWidth) / 2 + arrayScrollXY[0]) + 'px';
}

// Удаляет дочерние элементы элемента с ID, равным node_id
function deleteChildNodes(node_id)
{
	var node = document.getElementById(node_id);

	if (node !== undefined)
	{
		if (node.hasChildNodes())
		{
			while (node.firstChild)
			{
				node.removeChild(node.firstChild);
			}
		}
	}
}

function HideWindow(windowId)
{
	var windowDiv = document.getElementById(windowId);

	if (windowDiv == undefined)
	{
		return false;
	}

	// Окно редактирования элементов ЦА при закрытии - удаляем полностью
	if (windowId.indexOf('edit_window_') == 0)
	{
		// Отключаем связь с редакторами
		DisableTinyMCE();

		// Удаляем дочерние узлы
		deleteChildNodes(windowId);

		// Удаляем окно
		windowDiv.parentNode.removeChild(windowDiv);
	}
	else
	{
		windowDiv.style.display = 'none';
	}
}

// Магазин
function doSetLocation(shop_country_id, path)
{
	var req = new JsHttpRequest();

	// Отображаем экран загрузки
	ShowLoadingScreen();

	req.onreadystatechange = function()
	{
		if (req.readyState == 4)
		{
			// Возвращаем обычный курсор
			document.body.style.cursor = '';

			// Убираем затемнение.
			HideLoadingScreen();

			if (req.responseJS != undefined)
			{
				// Данные.
				if (req.responseJS.result != undefined)
				{
					oSelect = document.getElementById(location_select_id);

					// Очищаем select
					oSelect.options.length = 0;

					// Добавляем значение " ... "
					oSelect.options[oSelect.options.length] = new Option(" ... ", 0);

					for (var key in req.responseJS.result)
					{
						oSelect.options[oSelect.options.length] = new Option(req.responseJS.result[key], key);
					}

					// Устанавливаем города
					//doSetCity(oSelect.options[oSelect.selectedIndex].value);
					oCity = document.getElementById(city_select_id);
					oCity.options.length = 0;
					oCity.options[oCity.options.length] = new Option(" ... ", 0);

					oCityarea = document.getElementById(cityarea_select_id);
					oCityarea.options.length = 0;
					oCityarea.options[oCityarea.options.length] = new Option(" ... ", 0);
				}
			}
			return true;
		}
	}

	req.open('get', path + "?action=get_location&shop_country_id="+shop_country_id, true);

	// Отсылаем данные в обработчик.
	req.send(null);

	// Курсор ставим на часики.
	document.body.style.cursor = "wait";
}

function doSetCity(shop_location_id, path)
{
	var req = new JsHttpRequest();

	// Отображаем экран загрузки
	ShowLoadingScreen();

	req.onreadystatechange = function()
	{
		if (req.readyState == 4)
		{
			// Возвращаем обычный курсор
			document.body.style.cursor = '';

			// Убираем затемнение.
			HideLoadingScreen();

			if (req.responseJS != undefined)
			{
				// Данные.
				if (req.responseJS.result != undefined)
				{
					oSelect = document.getElementById(city_select_id);

					// Очищаем select
					oSelect.options.length = 0;

					// Добавляем значение " ... "
					oSelect.options[oSelect.options.length] = new Option(" ... ", 0);

					for (var key in req.responseJS.result)
					{
						oSelect.options[oSelect.options.length] = new Option(req.responseJS.result[key], key);
					}

					// Устанавливаем районы
					//doSetCityArea(oSelect.options[oSelect.selectedIndex].value);

					oCityarea = document.getElementById(cityarea_select_id);
					oCityarea.options.length = 0;
					oCityarea.options[oCityarea.options.length] = new Option(" ... ", 0);
				}
			}
			return true;
		}
	}

	req.open('get', path + "?action=get_city&shop_location_id="+shop_location_id, true);

	// Отсылаем данные в обработчик.
	req.send(null);

	// Курсор ставим на часики.
	document.body.style.cursor = "wait";
}

function doSetCityArea(shop_city_id, path)
{
	var req = new JsHttpRequest();

	// Отображаем экран загрузки
	ShowLoadingScreen();

	req.onreadystatechange = function()
	{
		if (req.readyState == 4)
		{
			// Возвращаем обычный курсор
			document.body.style.cursor = '';

			// Убираем затемнение.
			HideLoadingScreen();

			if (req.responseJS != undefined)
			{
				// Данные.
				if (req.responseJS.result != undefined)
				{
					oSelect = document.getElementById(cityarea_select_id);

					// Очищаем select
					oSelect.options.length = 0;

					// Добавляем значение " ... "
					oSelect.options[oSelect.options.length] = new Option(" ... ", 0);

					for (var key in req.responseJS.result)
					{
						oSelect.options[oSelect.options.length] = new Option(req.responseJS.result[key], key);
					}
				}
			}
			return true;
		}
	}

	req.open('get', path + "?action=get_cityarea&shop_city_id="+shop_city_id, true);

	// Отсылаем данные в обработчик.
	req.send(null);

	// Курсор ставим на часики.
	document.body.style.cursor = "wait";
}

// Плавающие блоки
// получаем исходную позицию плавающего блока
function GetStyle(drag_object, axis)
{
	var str_value = "";

	if(document.defaultView && document.defaultView.getComputedStyle)
	{
		var css = document.defaultView.getComputedStyle(drag_object, null);
		str_value = css ? css.getPropertyValue(axis) : null;
	}
	else if(drag_object.currentStyle)
	{
		str_value = drag_object.currentStyle[axis];

		if (str_value == 'auto')
		{
			if (axis == 'top')
			{
				str_value = drag_object.offsetTop;
			}
			else
			{
				str_value = drag_object.offsetLeft;
			}
		}
	}

	return str_value;
}

function Draggable(drag_object)
{
	var xDelta = 0,
	yDelta = 0,
	xStart = 0,
	yStart = 0;

	// остановить событие
	function EndDrag()
	{
		document.onmouseup = null;
		document.onmousemove = null;
	}

	// считаем новую позицию при перетаскивании
	function Drag(drag_event)
	{
		drag_event = drag_event || window.event;

		xDelta = xStart - parseInt(drag_event.clientX);
		yDelta = yStart - parseInt(drag_event.clientY);

		xStart = parseInt(drag_event.clientX);
		yStart = parseInt(drag_event.clientY);

		drag_object.style.top = (parseInt(drag_object.style.top) - yDelta) + 'px';
		drag_object.style.left = (parseInt(drag_object.style.left) - xDelta) + 'px';
	}

	// начать перетаскивание
	function StartDrag(drag_event)
	{
		drag_event = drag_event || window.event;

		xStart = parseInt(drag_event.clientX);
		yStart = parseInt(drag_event.clientY);

		drag_object.style.top = parseInt(GetStyle(drag_object, 'top')) + 'px';
		drag_object.style.left = parseInt(GetStyle(drag_object, 'left')) + 'px';

		document.onmouseup = EndDrag;
		document.onmousemove = Drag;

		return false;
	}

	// связываем объект с событием
	drag_object.onmousedown = StartDrag;
}

// показ окна редактирования
function ShowEditWindow(caption, path, name)
{
	var oWindowId = 'edit_window_'+name;

	var oWindow = document.getElementById(oWindowId);

	if (oWindow == undefined)
	{
		// Создаем окно
		CreateWindow(oWindowId, caption, '90%', '90%');

		var oWindow = document.getElementById(oWindowId);

		// <div id="subdiv">
		var ElementDiv = document.createElement("div");
		ElementDiv.setAttribute("id", "subdiv");
		var SubDiv = oWindow.appendChild(ElementDiv);

		var DivMessage = document.createElement("div");
		DivMessage.setAttribute("id", "id_message");
		var oDivMessage = SubDiv.appendChild(DivMessage);

		var DivContent = document.createElement("div");
		DivContent.setAttribute("id", "id_content");
		var oDivContent = SubDiv.appendChild(DivContent);

		// Запрос backend-у
		var req = new JsHttpRequest();

		// Отображаем экран загрузки
		ShowLoadingScreen();

		req.onreadystatechange = function()
		{
			if (req.readyState == 4)
			{
				// Возвращаем обычный курсор
				document.body.style.cursor = '';

				// Убираем затемнение.
				HideLoadingScreen();

				if (req.responseJS != undefined)
				{
					// Сообщение.
					// Выводим результат ошибки в переменную.
					if (typeof req.responseJS.error != 'undefined')
					{
						if (oDivMessage)
						{
							// Создадим скрытый SPAN для IE, в который поместим текст + скрипт.
							// Если перед <script> не будет текста, нехороший IE не увидит SCRIPT
							var span = document.createElement("span");
							span.style.display = 'none';
							span.innerHTML = "Stupid IE. " + req.responseJS.error;

							runScripts(span.getElementsByTagName('SCRIPT'));

							// Занесем текст сообщения только после выполнения скрипта
							oDivMessage.innerHTML = req.responseJS.error;
						}
					}

					// Данные записываем только тогда, если они есть и не пустые.
					if (typeof req.responseJS.form_html != 'undefined' && req.responseJS.form_html != '')
					{
						cmsrequest = path;
						
						// Указываем текущий путь
						// Меняем Location только при DoLoadAjax, если вернулись назад - не меняем
						if (cmsrequest != ''
						&& function_exists('getCmsUrl')
						&& getCmsUrl() != cmsrequest)
						{
							setLocation(cmsrequest);
						}

						if (function_exists('saveLocation'))
						{
							// Сохраняем текущий путь всегда
							saveLocation(getCmsUrl());
						}
						
						// DisableTinyMCE();

						// Занесем текст сообщения ДО выполнения скрипта
						oDivContent.innerHTML = req.responseJS.form_html;
						
						// Создадим скрытый SPAN для IE, в который поместим текст + скрипт.
						// Если перед <script> не будет текста, нехороший IE не увидит SCRIPT
						var span = document.createElement("span");
						span.style.display = 'none';
						span.innerHTML = "Stupid IE. " + req.responseJS.form_html;

						runScripts(span.getElementsByTagName('SCRIPT'));
					}
				}
				return true;
			}
		}

		req.open('get', path, true);

		// Отсылаем данные в обработчик.
		req.send(null);

		// Курсор ставим на часики.
		document.body.style.cursor = "wait";
	}
	else
	{
		// Отключаем связь с редакторами
		DisableTinyMCE();
		oDivMessage = document.getElementById("id_message");
		oDivMessage.innerHTML = '';
	}

	SlideWindow(oWindowId);
}

function row_over(object)
{
	if (object.className == 'row_table') object.className = 'row_table_over';
}

function row_out(object)
{
	if (object.className == 'row_table_over') object.className = 'row_table';
}

function row_over_odd(object)
{
	if (object.className == 'row_table_odd') object.className = 'row_table_over_odd';
}

function row_out_odd(object)
{
	if (object.className == 'row_table_over_odd') object.className = 'row_table_odd';
}


function menu_row_over(object)
{
	if (object.className == 'menu_out') object.className = 'menu_over';
}

function menu_row_out(object)
{
	if (object.className == 'menu_over') object.className = 'menu_out';
}

function SlideLayer(Num)
{
	var el = document.getElementById(Num);

	if (el.style.display=="block")
	{
		el.style.display="none";
	}
	else
	{
		el.style.display="block";
	}
}

// =============================================
// Функции работы с меню
// =============================================
changeFontSizeTimer = new Array();

function HostCMSMenuOver(CurrenElementId, LevelMenu, ChildId)
{
	CurrenElement = document.getElementById(CurrenElementId);
	if (CurrenElementId == undefined)
	{
		return false;
	}

	decor(CurrenElementId, LevelMenu);
	if (ChildId != '')
	{
		ChildId = document.getElementById(ChildId);
		showHideMenu(ChildId);
	}
}

function HostCMSMenuOut(CurrenElementId, LevelMenu, ChildId)
{
	CurrenElement = document.getElementById(CurrenElementId);

	if (CurrenElementId == undefined)
	{
		return false;
	}

	unDecor(CurrenElementId, LevelMenu);
	if (ChildId != '')
	{
		ChildId = document.getElementById(ChildId);
		showHideMenu(ChildId);
	}
}

// Функции скрытия-открытия меню
function showHideMenu(ChildId)
{
	if (ChildId == undefined)
	{
		return false;
	}

	if (ChildId.style.display == "block")
	{
		ChildId.style.display = "none";
	}
	else
	{
		ChildId.style.display = "block";

		// получаем ширину выпадающего блока и устанавливаем её для верхней и нижней границы
		groupChildElements = ChildId.children;

		if (groupChildElements != undefined)
		{
			for (i = 0; i < groupChildElements.length; i++)
			{
				if(groupChildElements[i].className == 'b' | groupChildElements[i].className == 't')
				{
					groupChildElements[i].style.width = ChildId.clientWidth + 'px';
				}

				if(groupChildElements[i].className == 'r' | groupChildElements[i].className == 'l')
				{
					groupChildElements[i].style.height = ChildId.clientHeight + 'px';
				}
			}
		}
	}
}

// Функции оформления
function changeFontSize(CurrenElementId, change, limit)
{
	var CurrenElement = document.getElementById(CurrenElementId);

	if (CurrenElement)
	{
		var CurrFontSize = CurrenElement.style.fontSize ? parseInt(CurrenElement.style.fontSize) : 10;
		if (CurrFontSize != limit)
		{
			CurrenElement.style.fontSize = (CurrFontSize + change) + 'pt';
			changeFontSizeTimer[CurrenElementId] = setTimeout('changeFontSize("'+CurrenElementId+'", '+change+', '+limit+')', 1);
		}
	}
}

// Функция визуального оформления элементов меню
function decor(CurrenElementId, LevelMenu)
{
	var CurrenElemen = document.getElementById(CurrenElementId);

	if (LevelMenu == 1) // для первого уровня вложенности
	{
		CurrenElement.style.background = "url('/admin/images/line3.gif') repeat-x 0 100%";
		var child = CurrenElement.children;

		if (changeFontSizeTimer[CurrenElementId] != '')
		{
			clearTimeout(changeFontSizeTimer[CurrenElementId]);
		}
		changeFontSize(CurrenElement.id, 1, 13);

		// приподнемаем li при наведении
		//CurrenElementId.style.top = (navigator.userAgent.indexOf('Firefox') != -1)? '-2px':'-6px';
	}
	else // для второго уровня вложенности
	{

	}
}

// Функция визуального оформления элементов меню
function unDecor(CurrenElementId, LevelMenu)
{
	var CurrenElemen = document.getElementById(CurrenElementId);
	if (LevelMenu==1)
	{
		clearTimeout(changeFontSizeTimer[CurrenElementId]);
		CurrenElement.style.background = "url('/admin/images/line1.gif') repeat-x 0 100%";
		changeFontSize(CurrenElement.id, -1, 10);
	}
	else
	{
		//CurrenElementId.style.background = (navigator.userAgent.indexOf('MSIE') == -1)? 'url(/admin/images/fon_li.png) repeat-y 0 0':'url(/admin/images/fon_li.gif) repeat-y 0 0';
	}
}

function SetGradeMessage(message_id, grade_val)
{
	// Запрос backend-у
	var req = new JsHttpRequest();

	// Отображаем экран загрузки
	ShowLoadingScreen();

	req.onreadystatechange = function()
	{
		if (req.readyState == 4)
		{
			// Возвращаем обычный курсор
			document.body.style.cursor = '';

			// Убираем затемнение.
			HideLoadingScreen();

			return true;
		}
	}

	req.open('get', "./?action=set_message_grade&helpdesk_message_id="+message_id+"&grade="+grade_val, true);

	// Отсылаем данные в обработчик.
	req.send(null);

	// Курсор ставим на часики.
	document.body.style.cursor = "wait";
}

/**
 * Обновление картинки CAPTCHA
 * captchaKey - идентификатор CAPTCHA
 * captchaHeight - высота картинки с CAPTCHA
 */
function ReNewCaptcha(captchaKey, captchaHeight)
{	
	if (document.images['captcha'] != undefined)
	{
		var antiCache = Math.floor(Math.random()*100000);
		document.images['captcha'].src = "/captcha.php?get_captcha=" + captchaKey + "&height=" + captchaHeight + "&anc=" + antiCache;
	}
}

/**
 * Обновление картинки CAPTCHA для картинки по ее ID
 * captchaKey - идентификатор CAPTCHA
 * captchaHeight - высота картинки с CAPTCHA
 */
function ReNewCaptchaById(imageId, captchaKey, captchaHeight)
{	
	// Пытаемся получить скрытый объект для input-а
	var captchaObject = document.getElementById(imageId);

	// Элемента нет, добавим его
	if (null != captchaObject && undefined !== captchaObject)
	{
		var antiCache = Math.floor(Math.random()*100000);
		captchaObject.src = "/captcha.php?get_captcha=" + captchaKey + "&height=" + captchaHeight + "&anc=" + antiCache;
	}
}

// Отображает/скрывает блок
function ShowHide(divId)
{
	var windowDiv = document.getElementById(divId);

	if (windowDiv == undefined)
	{
		return false;
	}

	if (windowDiv.style.display == "block")
	{
		windowDiv.style.display = 'none';
	}
	else
	{
		windowDiv.style.display = 'block';
	}
}

//Функция обратного вызова при загрузке формы добавления на доску объявлений
function callbackfunction_showFormAddItem(responseJS)
{
	if (typeof responseJS != 'undefined')
	{
		HideLoadingScreen();
	
		// Данные.
		if (typeof responseJS.result != 'undefined')
		{
			html = responseJS.result;

			document.getElementById('AddItemForm').innerHTML = html;

			// Выполняем скрипты из полученного с сервера HTML-а
			runScripts(document.getElementById('AddItemForm').getElementsByTagName('SCRIPT'));
			
			// Очищаем поле сообщений
			var div_id_message = document.getElementById('AddItemMessage');

			if (div_id_message)
			{
				div_id_message.innerHTML = '';
			}
			
			//cr('AddItemForm');
		}
	}
}

//Функция обратного вызова при отправке добавления на доску объявлений
function callbackfunction_SendFormItem(responseJS)
{
	if (typeof responseJS != 'undefined')
	{
		if (responseJS.message != 'undefined')
		{
			var div_id_message = document.getElementById('AddItemMessage');

			if (div_id_message)
			{
				div_id_message.innerHTML = responseJS.message;
				
				// Выполняем скрипты из полученного с сервера HTML-а
				runScripts(div_id_message.getElementsByTagName('SCRIPT'));
				
				// Переходим к сообщению
				window.location.href = (window.location.href.indexOf('#') >= 0 ? window.location.href : window.location.href + '#FocusAddItemMessage');
			}
		}
	}
}

function ShowImgWindow(title, src, width, height)
{
	obj = window.open("", "", "scrollbars=0,dialog=0,minimizable=1,modal=1,width="+width+",height="+height+",resizable=0");
	obj.document.write("<html>");
	obj.document.write("<head>");
	obj.document.write("<title>"+title+"</title>");
	obj.document.write("</head>");
	obj.document.write("<body topmargin=0 leftmargin=0 marginwidth=0 marginheight=0>");
	obj.document.write("<img src=\""+src+"\" width=\""+width+"\" height=\""+height+"\" />");
	obj.document.write("</body>");
	obj.document.write("</html>");
	obj.document.close();
}

function getElementsByName_iefix(tag, name) 
{
	var elem = document.getElementsByTagName(tag);
	var arr = new Array();

	var iarr = 0;
	
	for(i = 0; i < elem.length; i++)
	{
		att = elem[i].getAttribute("name");

		if(att == name)
		{
			arr[iarr] = elem[i];
			iarr++;
		}
	}
	return arr;
}

// Изменение высоты блока
function changeHeightFloatBlockBorder (oBorder, iHeightAttribute, iStyleTop)
{
	var iElementHeight = 0;
	
	for (i = 0; i < oBorder.length; i++)
	{
		iElementHeight = oBorder[i].parentNode.offsetHeight + iHeightAttribute;

		if (iElementHeight > 0)
		{
			oBorder[i].style.height = iElementHeight + 'px';
			oBorder[i].style.top = iStyleTop + 'px';
		}
	}
}