/** 
 * Библиотека для работы с модальными окнами.
 *
 * @author     Alexander A. Popov
 * @author     Andrey J. Nazarov
 * @author     Dmitriy V. Ibragimov
 * @version    $Id: modalwindow.js,v 1.2 2010/05/07 22:50:44 mondegor Exp $
 */

/**
 * Идентификатор количества модальных окон.
 * 
 * @var    int
 */
var mrcore_dialog_countModal = 1;

/**
 * Идентификатор элемента.
 * Вставляется значение для отображения пользователю 
 * 
 * @var    string
 */
var mrcore_dialog_fieldId = '';

/**
 * Идентификатор элемента Hidden - переменнной
 * 
 * @var    string
 */
var mrcore_dialog_fieldHiddenId = '';

/**
 * Функция создания контейнера для инициализации нового модального окна.
 *
 * @author    Dmitriy V. Ibragimov
 */
function mrcore_dialog_container_create()
{
    // Увеличиваем количество открытых модальных окон
    mrcore_dialog_countModal += 1;

    // Создаем контейнер модального окна после уже созданного модального окна
    $('#modalDialog' + parseInt(mrcore_dialog_countModal - 1))
    .after('<div id="modalDialog' + parseInt(mrcore_dialog_countModal) + '" class="ui-widget"><div id="modalDialogTips' + parseInt(mrcore_dialog_countModal) + '"></div><div id="modalDialogContent' + parseInt(mrcore_dialog_countModal) + '" style="overflow: auto;"></div></div>');

    // Смотрим zIndex ранее открытого модального окна и устанавливаем на единицу больше
    // для создаваемого
    var zIndexLast = $('#modalDialog' + parseInt(mrcore_dialog_countModal-1)).dialog('option', 'zIndex');

    // Инициализация нового модального окна
    $('#modalDialog' + parseInt(mrcore_dialog_countModal)).dialog
    (
        {
            autoOpen: false,
            bgiframe: true,
            closeOnEscape: true,
            draggable: true,
            resizable: false,
            modal: true,
            stack: true,
            zIndex: zIndexLast,
            close: function(event, ui)
            {
                //$('body').css('overflow', 'auto'); //хак для IE - восстанавливаем на body полосы прокрутки
                $('.ui-datepicker').hide();
            }
        }
    );
}

/**
 * Функция удаления контейнера модального окна.
 *
 * @author    Dmitriy V. Ibragimov
 * @param     object    modalDialog
 */
function mrcore_dialog_container_destroy(modalDialog)
{
    // Закрываем окно
    modalDialog.dialog('close');

    // Удалять контейнер можно только, если
    // он был создан из скрипта
    if (mrcore_dialog_countModal != 1)
    {
        // Удаляем модальное окно
        modalDialog.dialog('destroy');
        // Удаляем контейнер модального окна
        modalDialog.remove();
        // Уменьшаем количество открытых модальных окон
        mrcore_dialog_countModal -= 1;
    }
}

/**
 * Базовая функция инициализации модального окна.
 *
 * @author    Andrey J. Nazarov
 * @param     string             title       заголовок окна
 * @param     string             content     содержимое окна
 * @param     object             buttons     /optional/  коллекция кнопок
 * @param     string             icon        /optional/  иконка (набор иконок см. в ui.theme.css -> ui-icon-...)
 * @param     int                width       /optional/  ширина окна
 * @param     int/string('auto') height      /optional/  высота окна
 * @param     boolean            resizable   /optional/  возможность изменения размеров окна
 */
function mrcore_dialog_initModalWindow(title, content, buttons, icon, width, height, resizable)
{
	var winTitle     = ('undefined' != typeof(title))     ? title : 'Modal window';
	var winContent   = ('undefined' != typeof(content))   ? content : '';
	var winButtons   = ('undefined' != typeof(buttons))   ? buttons : '';
	var winWidth     = ('undefined' != typeof(width))     ? width : 300;
	var winHeight    = ('undefined' != typeof(height))    ? height : 'auto';
	var winResizable = ('undefined' != typeof(resizable)) ? resizable : false;

	// При получения доступа к DOM - элементу модального окна необходимо указывать номер
	// текущего модального окна
	var modalDialog = $('#modalDialog' + parseInt(mrcore_dialog_countModal));
	var modalDialogContent = $('#modalDialogContent' + parseInt(mrcore_dialog_countModal));

	modalDialog.dialog('option', 'title', winTitle);	
	modalDialog.dialog('option', 'buttons', winButtons);
	modalDialog.dialog('option', 'width', winWidth);

	// :WARNING: опция 'resizable' некорректно работает (ведёт себя как переключатель), поэтому введена проверка
	if (winResizable != modalDialog.dialog('option', 'resizable'))
	{
		modalDialog.dialog('option', 'resizable', winResizable);
	}

	if ('auto' != winHeight)
	{
		modalDialogContent.css('height', winHeight - 40);
	}
	else
	{
		modalDialogContent.css('height', 'auto');
	}
    
    modalDialogContent.css('width', '100%');
    
	modalDialogContent.html(winContent);
	modalDialogContent.scrollTop(0);

    $('#modalDialogContent' + parseInt(mrcore_dialog_countModal) + ' a[href*=ajax=1][ajax!=off]').click
    (
        function ()
        {
        	mrcore_dialog_openAjaxModalWindow(this.href);
        	return false;
        }
    );
    $('#modalDialogContent' + parseInt(mrcore_dialog_countModal) + ' a[href*=ajax=2][ajax!=off]').click
    (
        function ()
        {
            // Создание нового контейнера модального окна.
            // Контейнер созадется если в предыдущее окно загрузилось содержимое
            mrcore_dialog_container_create();
            mrcore_dialog_openAjaxModalWindow(this.href);
            return false;
        }
    );
}

/**
 * Базовая функция создания диалогового окна.
 *
 * @author Alexander A. Popov 
 * @param     string             title                               заголовок окна
 * @param     string             content                             содержимое окна
 * @param     object             buttons     /optional/  коллекция кнопок
 * @param     string             icon        /optional/  иконка (набор иконок см. в ui.theme.css -> ui-icon-...)
 * @param     int                width       /optional/  ширина окна
 * @param     int/string('auto') height      /optional/  высота окна
 * @param     boolean            resizable   /optional/  возможность изменения размеров окна
 */
function mrcore_dialog_openModalWindow(title, content, buttons, icon, width, height, resizable)
{
    var winIcon = ('undefined' != typeof(icon)) ? icon : '';
    var winContent = ('undefined' != typeof(content)) ? content : '';
 
	if ('' != winIcon)
	{
		winContent = '<table><tr><td><div class="ui-icon ui-icon-' + winIcon + ' dialogMessageIcon"></div></td><td>' + winContent + '</td></tr></table>';
	}

    mrcore_dialog_initModalWindow(title, winContent, buttons, winIcon, width, height, resizable);

	$('#modalDialog' + parseInt(mrcore_dialog_countModal)).dialog('open');
	// $('body').css('overflow', 'hidden'); //хак для IE - убираем на body полосы прокрутки
}

/**
 * Установка заголовка диалоговому окну.
 *
 * @author     Andrey J. Nazarov
 * @param      string title
 */
function mrcore_dialog_setTitle(title)
{
    $('#modalDialog' + parseInt(mrcore_dialog_countModal)).dialog('option', 'title', title);
}

/**
 * Базовая функция для загрузки контента в окно.
 * При ошибке выдает сообщение об ошибке.
 *
 * @author Alexander A. Popov
 * @param string    urlReq      адрес запроса (кроссдоменные запросы запрещены в целях безопасности)
 * @param string    request     передаваемые данные
 * @param function  onSuccess   функция, вызываемая при успешной загрузке контента, имеет формат function(result)
 *                              в переменную result передается результат загрузки
 * @param string    dataType    /optional/  тип получаемых данных
 */
function mrcore_dialog_AjaxLoad(urlReq, request, onSuccess, dataType)
{	
	var loadingType = ('undefined' != typeof(dataType)) ? dataType : 'text';
	// Определение метода передачи данных, если не определен, то выбирается GET
    var loadingMethod = ('undefined' != typeof($('#modalDialogContent' + parseInt(mrcore_dialog_countModal) + ' form').attr('method')) ? $('#modalDialogContent' + parseInt(mrcore_dialog_countModal) + ' form').attr('method') : 'get');

	$.ajax
	(
       {
			url: urlReq,
			type: loadingMethod,
			cache: false,
			async: true, // Необходимо все передавать в асинхронном режиме
			data: request,
			dataType: loadingType,
			success: onSuccess //,
//			error: function(XMLHttpRequest, textStatus, errorThrown)
//			{
//				mrcore_dialog_Message('Ошибка', '<ul>Ошибка при загрузке данных: <li>URL : ' + urlReq + '</li><li>Статус : ' + textStatus + '</li><li>Причина : ' + errorThrown + '</li></ul>', 'circle-close');
//			}
		}
	);
}

/**
 * Формирование запроса на основе данных формы и перегрузка окна после получение ответа.
 *
 * @author     Andrey J. Nazarov
 * @param      object form
 * @param      string href
 */
function mrcore_dialog_ajaxSendForm(form, href)
{
    request = $(form).serialize();
    mrcore_dialog_setTitle('Подождите, пожалуйста...');

    mrcore_dialog_openAjaxModalWindow(href, request);
}

/**
 * Функция отображения окна с загружаемым содержимым.
 * В зависимости от типа окна интерпритация содержимого будет отличаться.
 *
 * @author     Andrey J. Nazarov
 * @param      string href адрес запроса (кроссдоменные запросы запрещены в целях безопасности)
 * @param      string request    передаваемые данные
 */
function mrcore_dialog_openAjaxModalWindow(href, request)
{
	if ('undefined' == typeof(request))
	{
		request = '';
	}

	var parser = function (result)
	{
		var title = $(result).attr('title');
		var wBody = $('#modalDialogBody', result);
		var pType = (wBody.attr('pType')) ? wBody.attr('pType') : 'info';
		var pWidth = (parseInt(wBody.attr('pWidth')) > 0) ? parseInt(wBody.attr('pWidth')) : 550;
		var pHeight = (parseInt(wBody.attr('pHeight')) > 0) ? parseInt(wBody.attr('pHeight')) : 'auto';
		var pResizable = (1 == parseInt(wBody.attr('pResizable')));

		switch (pType)
		{
		    // модальное окно для вывода информации
			case 'info':
				var buttons = (1 == parseInt(wBody.attr('pButtonClose'))) ? {'Закрыть' : function() { mrcore_dialog_container_destroy($(this)); }} : {};
				mrcore_dialog_openModalWindow(title, result, buttons, '' , pWidth, pHeight, pResizable);
				break;

		    // модальное окно с формой
			case 'form':
				var dialogClose = parseInt($(result).attr('dialogClose'));

				// 1 - MRCORE_MODAL_DIALOG_CLOSE_TRUE
				// 3 - MRCORE_MODAL_DIALOG_CLOSE_TRUE_REFRESH 
				// если указано, что диалоговое окно необходимо закрыть
				if (1 == dialogClose || 3 == dialogClose)
				{
					// если требуется перегрузить родительское окно
					// если в dialogResult содержится ссылка, то произойдёт редирект
					// 3 - MRCORE_MODAL_DIALOG_CLOSE_TRUE_REFRESH
					if (3 == dialogClose)
					{
						mrcore_dialog_setTitle('Подождите, пожалуйста...');
						window.location.href = ($(result).attr('dialogResult').substring(0, 4) == 'url:') ?
											       $(result).attr('dialogResult').substring(4) :
											       window.location.href;
					}
					else
					{
					    mrcore_dialog_container_destroy($('#modalDialog' + parseInt(mrcore_dialog_countModal)));
					}
				}
				else
				{
					// если требуется перегрузить родительское окно
					// 2 - MRCORE_MODAL_DIALOG_CLOSE_FALSE_REFRESH
					if (2 == dialogClose)
					{
						$('#modalDialog' + parseInt(mrcore_dialog_countModal)).bind
						(
							'dialogbeforeclose',
							function(event, ui)
							{
								mrcore_dialog_setTitle('Подождите, пожалуйста...');
								window.location.href = window.location.href;
								return false;
							}
						);
					}

					var aButtons = new Array();
					var btnNumber = 0;

					// удаление кнопки из формы и перенос их в модальное окно
					// при использовании этого механизма нет необходимости в шаблоне различать
					// куда грузится форма - в окно или на страницу
					jQuery.each($('form div.bottom :submit, form div.bottom :button', result), function(i, val) 
					{
						if ('button' == val.type || 'submit' == val.type)
						{
							aButtons[btnNumber] = new Array();
							aButtons[btnNumber][0] = val.value;

							if ('button' == val.type)
							{
								// подразумевается, что в onclick содержится метод: mrcore_dialog_openAjaxModalWindow()
								aButtons[btnNumber][1] = ('' != val.onclick) ? val.onclick : function() { mrcore_dialog_container_destroy($(this)); };
							}
							else // if ('submit' == val.type)
							{
								aButtons[btnNumber][1] = function()
								{
									mrcore_dialog_setTitle('Подождите, пожалуйста...');
									mrcore_dialog_AjaxLoad
									(
										$('#modalDialogContent' + parseInt(mrcore_dialog_countModal) + ' form').attr('action'),
										$('#modalDialogContent' + parseInt(mrcore_dialog_countModal) + ' form').serialize() + '&' + $(val).attr('pName') + '=1',
										parser,
										'text'
									);
								}
							}

							btnNumber++;
						}
					});

					if (1 == parseInt(wBody.attr('pButtonClose')))
					{
						aButtons[btnNumber++] = new Array('Закрыть', function() { mrcore_dialog_container_destroy($(this)); });
					}

					var buttons = new Object();

					// формирование кнопок в обратном порядке
					// компенсация того, что в dialog они тоже
					// выводятся в обратном порядке
					for (var i = aButtons.length - 1; i >= 0; i--)
					{
						buttons[aButtons[i][0]] = aButtons[i][1];
					}

					// если форма была отправлена, то диалоговое окно
					// только обновляется, т.к. оно уже открыто
					if ('submit' == $(result).attr('dialogResult'))
					{
						mrcore_dialog_initModalWindow(title, result, buttons, '', pWidth, pHeight, pResizable);
					}
					else
					{
						mrcore_dialog_openModalWindow(title, result, buttons, '', pWidth, pHeight, pResizable);
					}
				}

				if ('undefined' != typeof($(result).attr('fieldsForUpdate')))
				{
				    var fieldsForUpdate = $(result).attr('fieldsForUpdate').split(';');

				    mrcore_dialog_updateFieldsFromIds(fieldsForUpdate[0], fieldsForUpdate[1]);
					// mrcore_dialog_updateFields($(result).attr('fieldsForUpdate'));
				}

				$('#modalDialogContent' + parseInt(mrcore_dialog_countModal) + ' div.bottom').remove();
				break;
		}
	}

	mrcore_dialog_AjaxLoad(href, request, parser, 'text');
}

/**
 * Отображение модального окна
 * с простой информацией в виде html.
 *
 * @author     Andrey J. Nazarov
 * @param      string title
 * @param      string message
 * @param      string icon    /optional/  иконка (набор иконок см. в ui.theme.css -> ui-icon-...)
 */
function mrcore_dialog_openModalMessage(title, message, icon)
{
	if ('' == icon)
	{
        icon = 'info';
	}

    var buttons = {'Ok' : function() { mrcore_dialog_container_destroy($(this)); }}
    mrcore_dialog_openModalWindow(title, '<div class="dialogMessage">' + message + '</div>', buttons, icon, 420, 140);
}

/**
 * Отображение модального окна для
 * подтверждения какого либо действия.
 *
 * @author     Andrey J. Nazarov
 * @param      string message
 * @param      string href адрес запроса (кроссдоменные запросы запрещены в целях безопасности)
 * @param      string icon    /optional/  иконка (набор иконок см. в ui.theme.css -> ui-icon-...)
 * @return     false
 */
function mrcore_dialog_openModalConfirm(message, href, icon)
{
	if ('undefined' == typeof(icon) || '' == icon)
	{
        icon = 'alert';
	}

	var okCallBack = function()
	{
		window.location.href = href;
	}

	var buttons = {'Отмена' : function() { mrcore_dialog_container_destroy($(this)); }, 'Ok' : function() { okCallBack(); mrcore_dialog_container_destroy($(this)); }}
	mrcore_dialog_openModalWindow('Подтверждение', '<div class="dialogMessage">' + message + '</div>', buttons, icon, 420, 140);

	return false;
}

/**
 * Обновления полей в родительском документе.
 *
 * @author    Alexander A. Popov
 * @param     string fields 
 */
function mrcore_dialog_updateFields(fields)
{
    if ('' != fields)
    {
		var collection = fields.split(';');

		jQuery.each
		(
	        collection,
	        function(i, val)
		    {
			    fieldToUpdate = val.split('=');
			    $('#' + fieldToUpdate[0]).text(fieldToUpdate[1]);
		    }
		);
    }
}

/**
 * Установка идентификаторов компонетов
 * для дальнейшего обновления их значений.
 *
 * @author    Dmitriy V. Ibragimov
 * @param     string    fieldId
 * @param     string    fieldHiddenId
 */
function mrcore_dialog_setFieldIdsForUpdate(fieldId, fieldHiddenId)
{
    mrcore_dialog_fieldId = fieldId;

    if ('undefined' != typeof(fieldHiddenId))
    {
        mrcore_dialog_fieldHiddenId = fieldHiddenId;
    }
}

/**
 * Обновление значения компонентов по идентификаторам.
 * 
 * @author    Dmitriy V. Ibragimov
 * @param     string    value
 * @param     string    hiddenValue
 * @return    bool 
 */
function mrcore_dialog_updateFieldsFromIds(value, hiddenValue)
{
    $('#' + mrcore_dialog_fieldId).val(value);

    if ('' != mrcore_dialog_fieldHiddenId)
    {
    	if ('undefined' != typeof(hiddenValue))
        {
            $('#' + mrcore_dialog_fieldHiddenId).val(hiddenValue);
        }
        else
        {
            $('#' + mrcore_dialog_fieldHiddenId).val(value);
        }
    }

    $('#' + mrcore_dialog_fieldId).trigger("txbChange");

    mrcore_dialog_container_destroy($('#modalDialog' + parseInt(mrcore_dialog_countModal)));

    return false;
}
