﻿/* 
Jquery Modal v1.3 (WEBDELO)

Описание: Библиотека работы модального окна.
Разработчик: Хмельницкий Руслан Олегович
Дата: 9.10.2010
Сайт: www.webdelo.org
Требования: 
 - jquery v1.3.2+
*/ 

var webdeloModal = {
	// Класс конфигурации модального окна
	Settings : function(){
		// Дефолтные значения
		this.overlayOpacity = 20; // Прозрачность фона модального окна
		this.overlayColor = '#b2ccff'; // Цвет фона прозрачного окна
		this.overlayImg = '/cp/img/pattern.png?o';
		this.currentType = ''; // Текущий тип окна (эта строка добавляется к CSS-классу контейнера)
		this.loadingType = 'Loading'; // Обозначение типа окна для загрузки (это передается в currentType в быстром методе openLoading)
		
		this.preloadImgType = 'Loading'; // Обозначение типа окна при подгрузке картинки
		this.preloadImgText = 'Загрузка изображения...'; // Текст в окне при подгрузке картинки
		this.loadingImgSrc = '/cp/img/loading.gif';
		this.imgCloseText = 'Щелкни мышью, чтобы свернуть изображние';
		this.isShowBtnOk = false; // Показать ли кнопку Ok
		this.btnOkTitle = "Ok"; // Что выводить в кнопке Ok
		this.btnConfirmOkTitle = "Ok"; // Что выводить в кнопке Ok окна подтверждения
		this.btnConfirmCancelTitle = "Отмена"; // Что выводить в кнопке Cancel окна подтверждения		
		this.fadeEffect = true; // Включать ли эффект увядания
		this.effectFast = true; 
		this.effectSlow = false;
	},
	
	// Создаем дефолтную конфигурацию модального окна
	config : null,
	
	// Объекты 
	overlay : null,
	container : null,
	data : null,
	button : null,
	buttonConfirm : null,
	img: null,
	
	// Вспомогательные переменные
	btnConfirmOkOnClick : function(){}, // Метод-заглушка вызываемый по клику на кнопку подверждения (нужная функция каждый раз передается в методе confirm)
	objDataHTMLType : null,
	
	// Инициализация модального окна
	init : function(){

		if(this.config == null)
			this.config = new this.Settings();
			
		$(document).keydown(this.keyEvent);
		
		// Создаем фон модального окна
		this.overlay = $('<div>')
				.attr('id', 'webdeloModalOverlay')
				.css($.extend({},{
					opacity: this.config.overlayOpacity / 100,
					backgroundColor: this.config.overlayColor,
					backgroundImage: "url('"+this.config.overlayImg+"')",
					height: '100%',
					width: '100%',
					cursor: 'wait',
					position: 'fixed',
					left: 0,
					top: 0,
					zIndex: 3000
				}))
				.hide()
				.appendTo('body');
				
		// Создаем контейнер модального окна
		this.container = $('<div>')
				.attr('id', 'webdeloModalContainer')
				.addClass('webdeloModalContainer' + this.config.currentType)
				.css($.extend({}, {
					position: 'fixed', 
					zIndex: 3100
				}))
				.hide()
				.appendTo('body');
				
		this.data = $('<div>')
				.addClass('webdeloModalData')
				.appendTo('body');
				
		this.button = $('<div>')
				.addClass('webdeloModalButton')
				.append('<button onclick="webdeloModal.close()">' + this.config.btnOkTitle + '</button>')
				.hide()
				.appendTo('body');
				
		this.buttonConfirm = $('<div>')
				.addClass('webdeloModalButtonConfirm')
				.append('<button onclick="webdeloModal.close(); webdeloModal.btnConfirmOkOnClick();">' + this.config.btnConfirmOkTitle + '</button>')
				.append('<button onclick="webdeloModal.close()" class="webdeloModalButtonConfirmCancel">' + this.config.btnConfirmCancelTitle + '</button>')
				.hide()
				.appendTo('body');
				
		this.img = $('<img>')
				.attr('title', this.config.imgCloseText)
				.attr('src', this.config.loadingImgSrc)
				.css($.extend({}, {
					cursor: 'pointer'
				}))
				.hide()
				.click(function() {
					webdeloModal.close();
				})
				.appendTo('body');
				
		this.container.append(this.data);
		this.container.append(this.button);
		this.container.append(this.buttonConfirm);
		this.container.append(this.img);
	},
	
	// Обновление параметров модального окна
	update : function(){
		// Изменяем фон модального окна если надо
		if(this.overlay.css('backgroundColor') != this.config.overlayColor)
			this.overlay.css('backgroundColor', this.config.overlayColor);
				
		// Изменяем контейнер модального окна если надо
		if(this.container.attr('class') != 'webdeloModalContainer' + this.config.currentType)
			this.container.removeClass().addClass('webdeloModalContainer' + this.config.currentType);
			
		setTimeout("webdeloModal.toCenter()", 500);
	},
	
	// Открытие модального окна. Базовый метод, которы вызывается также во всех быстрых методах
	open : function(data, cnfg){ 
		
		if(this.overlay == null || this.container == null)
			this.init();
			
		var isUpdate = false;
		if (typeof cnfg == 'object')
			isUpdate = this.setConfig(cnfg);
		if (typeof data == 'string' || typeof data == 'number') 
		{
			this.data = this.data.html(data);
			isUpdate = true;
			
			this.data.show();
			this.img.hide();
			
			if(this.config.isShowBtnOk)
				this.button.show();
			else
				this.button.hide();
		}
		else if (typeof data == 'object' && data.nodeName && data.nodeName.toLowerCase() == "img") 		{
			this.data.hide();
			this.img.show()
					.attr('src', data.src);
			this.button.hide();
			isUpdate = true;
		}
		else if (typeof data == 'object') {
			this.data.html('');
			this.objDataHTMLType = data;
			this.objDataHTMLType.appendTo(this.data).show();
			isUpdate = true;
			
			this.data.show();
			this.img.hide();
			this.button.hide();
		}

		var effect = this.config.effectFast?'fast':(this.config.effectSlow?'slow':null);
		if(this.config.fadeEffect)
		{
			this.overlay.fadeIn(effect);
			this.container.fadeIn(effect);
		}
		else
		{
			this.overlay.show(effect);
			this.container.show(effect);
		}
		if(isUpdate)
			this.update();
		return false;
	},
	
	// Закрытие модального окна
	close : function() {
		var effect = this.config.effectFast?'fast':(this.config.effectSlow?'slow':null);
		if(this.config.fadeEffect)
		{
			this.overlay.fadeOut(effect);
			this.container.fadeOut(effect);
		}
		else
		{
			this.overlay.hide(effect);
			this.container.hide(effect);
		}
		//this.img.animate({left: "+=0"}, 1000).attr('src', this.config.loadingImgSrc);
		this.button.hide();
		this.buttonConfirm.hide();
		if(this.objDataHTMLType != null)
		{
			this.objDataHTMLType.hide().appendTo('body');
			this.objDataHTMLType = null;
		}
		return false;
	},
	
	// Алерт. Быстрый метод open с текстом и кнопкой Ok
	alert: function(text, type) {
		if(typeof type == "undefined")
			type = '';
		return this.open(text, {currentType : type, isShowBtnOk : true});
	},
	
	// Confirm. Метод открытия окна подтверждения
	confirm: function(text, func, type) {
		if(typeof func == "function")
		{
			this.btnConfirmOkOnClick = func;
			if(typeof type == "undefined")
				type = '';
			this.open(text, {currentType : type, isShowBtnOk : false});
			this.buttonConfirm.show();
		}
		return false;
	},
	
	// Загрузка. Быстрый метод open с текстом и стилем оформления для загрузки.
	openLoading: function(text) {
		return this.open(text, {currentType : this.config.loadingType, isShowBtnOk : false});
	},
	
	// Вывод окна с HTML контентом который в контейнере ID которого передается.
	// Быстрый метод open
	openHTML: function(nodeId) {
		return  this.open($('#'+nodeId), {currentType: '', isShowBtnOk: false});
	},
	
	// Загрузка и показ картинки.
	openImg: function(data) {
		var src = null;
		if(typeof data == 'object' && data.nodeName && data.nodeName.toLowerCase() == "a")
			src = data.href;
		else if(typeof data == 'string')
			src = data;
		
		this.open(this.config.preloadImgText, {currentType: this.config.preloadImgType, isShowBtnOk: false});
		if(this.img == null)
			this.init();
		var Img = document.createElement('img');
		Img.onload = function () { try { webdeloModal.open(this, {currentType : 'Img', isShowBtnOk : false}); } catch (e) {} };
		Img.src = src;

		return false;
	},
	
	// Для совместимости версий
	showImg:  function(data) {
		return this.openImg(data);
	},

	
	// Установка параметров конфига
	setConfig: function (cnfg) {
		
		if(this.config == null)
			this.config = new this.Settings();
			
		var isUpdate = false;
		
		if (typeof cnfg == 'object')
		{
			if(cnfg.overlayOpacity != undefined) {
				this.config.overlayOpacity = cnfg.overlayOpacity;
				isUpdate = true;
			}
			if(cnfg.overlayColor != undefined) {
				this.config.overlayColor = cnfg.overlayColor;
				isUpdate = true;
			}
			if(cnfg.currentType != undefined) {
				this.config.currentType = cnfg.currentType;
				isUpdate = true;
			}
			if(cnfg.isShowBtnOk != undefined) {
				this.config.isShowBtnOk = cnfg.isShowBtnOk;
				isUpdate = true;
			}
			if(cnfg.btnOkTitle != undefined) {
				this.config.btnOkTitle = cnfg.btnOkTitle;
				isUpdate = true;
			}
			if(cnfg.fadeEffect != undefined) {
				this.config.fadeEffect = cnfg.fadeEffect;
				isUpdate = true;
			}
			if(cnfg.effectFast != undefined) {
				this.config.effectFast = cnfg.effectFast;
				isUpdate = true;
			}
			if(cnfg.effectSlow != undefined) {
				this.config.effectSlow = cnfg.effectSlow;
				isUpdate = true;
			}
		}
		return isUpdate;
	},
	
	toCenter : function () {
		this.container.animate({marginTop:  "-" + (this.container.height()/2) + "px",
								marginLeft: "-" + (this.container.width()/2) + "px"}, 'slow');
	},
	
	fixIE: function () {
		var wHeight = $(document.body).height() + 'px';
		var wWidth = $(document.body).width() + 'px';
	
		// hacks
		this.overlay.css({position: 'absolute', height: wHeight, width: wWidth});
	},
	
	// Отлавливает события клавиатуры
	keyEvent: function (event) {
	    var keycode;
		if(!event) 
			var event = window.event;
		if (event.keyCode) 
			keycode = event.keyCode; // IE
		else if(event.which) 
			keycode = event.which; // all browsers
		switch(keycode)
		{
			case 27:
				webdeloModal.close();
				break;
			default:
				break;
		}
	}
};
