/*
 * Flybox - flying box
 * $Id$
 */
var Flybox = {
	config: {
		width: 500,
		height: 300,
		close: true,
		callbackClose: function(){},
		managePanelTop: false,
		managePanelBottom: false,
		managePanelHeight: 17
	},
	getElement: function() {
		if (!this.$element)
			this.$element = $('<div id="flybox"><a href="#close" class="btn_close" onclick="Flybox.hide();return false;"></a><div class="container"></div></div>').appendTo("body");
		return this.$element;
	},
	getContainer: function() {
		if (!this.$container)
			this.$container = $('.container',this.getElement());
		return this.$container;
	},
	/*
	 * возвращает ширину и высоту видимой области окна браузера
	 */
	screen : {
		width: function(){
			return (document.documentElement.clientWidth ? document.documentElement.clientWidth : (window.innerWidth ? window.innerWidth : document.body.offsetWidth));
			return (window.innerWidth ? window.innerWidth : (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.offsetWidth));
		},
		height: function(){
			return (window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight));
		}
	},
	/*
	 * @param id object|string - набор параметров, объект jQuery, либо строка селектора
	 */
	show: function(options) {
		if (!options) return false;

		var $content, config;
		/*if (typeof options == "string")
		{
			$content = jQuery(options);
		}
		else if (options instanceof jQuery)
		{
			$content = options;
		}
		else if (typeof options == "object")
		{
			$content = options.id instanceof jQuery ? options.id : jQuery(options.id);

			if (typeof options == "object" && !(options instanceof jQuery))
				config = jQuery.merge(this.config,options);
			else
				config = this.config;
		}
		else return false;*/

		// получаем элемент содержимого окна
		$content = !(options instanceof jQuery) ? (typeof options == "string" ? jQuery(options) : (options.id instanceof jQuery ? options.id : jQuery(options.id))) : options;

		if (!$content.length) return false;

		if (typeof options == "object" && !(options instanceof jQuery))
			config = jQuery.extend({},this.config,options);
		else
			config = this.config;

		var delayShow = false, $box = this.getElement(), $container = this.getContainer();
		/*
		 * если Flybox ещё не активен, показываем прелоадер
		 */
		if ($box.css("display") == "none") {
			$box.find("a").hide(); // хак - скрываем все кнопки
			this.preloader.show(function(){
				Flybox._show();
			},config.callbackClose);
			delayShow = true;
		}

		// расстояние требуемое окну Flybox
		var boxWidth = 20; // сумма паддингов
		var scrollWidth = 17; // ширина полоски скролла

		$container.css("overflow","hidden");

		if ($container.has($content).length) {
			var _bak_content = $content;
			$content = $content.clone().appendTo('body');
		}
		/*
		 * узнаём ширину элемента:
		 * - из переданных параметров
		 * - из css свойств элемента
		 * - максимального размера окна, устанавливаем её элементу
		 */
		// хак для корректного учёта margin'a подсчёта
		// элементов при подсчёте ширины и высоты
		if (   !$content.css("paddingTop")
			&& !$content.css("paddingBottom")
			&& !$content.css("paddingLeft")
			&& !$content.css("paddingRight")
			)
				$content.css("padding","1px")

		var width = parseInt(options.width) ? options.width : $content.width() + parseFloat($content.css("paddingLeft")) + parseFloat($content.css("paddingRight"));
		var height = parseInt(options.height) ? options.height : $content.height() + parseFloat($content.css("paddingTop")) + parseFloat($content.css("paddingBottom"));

		if (width+boxWidth > this.screen.width())
		{
			$container.css("overflow","auto");
			width = this.screen.width() - (boxWidth+40);
			$content.width(width);
			height += scrollWidth;
		}

		/*
		 * определяем высоту
		 */
		if (config.managePanelTop) boxWidth += config.managePanelHeight;
		if (config.managePanelBottom) boxWidth += config.managePanelHeight;

		if ($content.height()+boxWidth > this.screen.height() || (options.height && $content.height()+boxWidth > options.height))
		{
			if (!config.managePanelTop) {
				config.managePanelTop = true;
				boxWidth += config.managePanelHeight;
			}

			$container.css("overflow","auto");//.css("marginTop",17);
			if ($content.height()+boxWidth > this.screen.height())
				height = this.screen.height() - (boxWidth+40);
			//$content.height(height);
			width += scrollWidth;
		}

		if (_bak_content) {
			$content.remove();
			$content = _bak_content;
		}
		this._tempData = [$content, width, height, config];

		if (!delayShow) this._show();
	},
	_show: function() {
		var $box = this.getElement(),
			$container = this.getContainer(),
			$content = this._tempData[0],
			width = this._tempData[1],
			height = this._tempData[2],
			config = this._tempData[3];

		// хак на случай если окошко пустое
		//if (!$("*:first",$container).length) $("*:first",$container).html("<div/>");

		// прячем контент
		$container.fadeOut(100, function(){
			// запускаем анимацию
			$box.stop().animate({width: width, height: height, marginTop: '-'+(height/2+10)+'px', marginLeft: '-'+(width/2+10)+'px'}, 500, "easeInQuad", function(){

				// удаляем содержимое контейнера
				$container.html("").css("margin",0).height("100%");
				// либо, переносим содержимое в боди
				//$("*:first",$container).removeAttr("style").hide().appendTo("body");

				// если активны панели управления, задаём нужную высоту контейнеру
				if (config.managePanelTop || config.managePanelBottom)
					$container.height(height - (config.managePanelTop + config.managePanelBottom) * config.managePanelHeight);
				if (config.managePanelTop) $container.css("marginTop",config.managePanelHeight);
				if (config.managePanelBottom) $container.css("marginBottom",config.managePanelHeight);

				if (!$content.hasClass("loader"))
					$content.css("margin",0);
				
				// добавляем новый контент в контейнер
				$content.appendTo($container).show();
				//$container.append($content.show());

				if (!config.close) $(".btn_close",$box).hide();
				// показываем новый контент
				$container.fadeIn(200,function(){
					if (config.close) $(".btn_close",$box).fadeIn(100);
				});
			});
		});
	},
	hide: function() {
		Flybox.getElement().fadeOut(100,function(){
			Flybox.fader.hide();
			Flybox.preloader.callbackClose();
			Flybox.getElement().find(".container *:first").remove();
		});
	},
	fader: {
		$: null,
		get: function() {
			if (!this.$)
				this.$ = $('<div id="flybox_fader">').click(Flybox.preloader.cancel).appendTo("body");
			return this.$;
		},
		show: function(callback) {
			this.get().fadeIn(300,callback);
			if ($.browser.msie) this.get().get(0).style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity=80)";
		},
		hide: function() {
			this.get().fadeOut(200);
		}
	},
	preloader: {
		$: null,
		get: function() {
			if (!this.$)
				this.$ = $("<div/>").addClass("loader").click(Flybox.preloader.cancel);
			return this.$;
		},
		show: function(callback) {
			this.callbackClose = (arguments.length == 2 && typeof arguments[1] == "function") ? arguments[1] : function(){};
			var $box = Flybox.getElement(), $container = Flybox.getContainer();
			var $preloader = this.get();

			$("a",$box).hide();

			if ($box.css("display") != "none")
			{
				//var $content = $("<div/>").css({width: 100, height: 100}).html($preloader).appendTo("body");
				Flybox._tempData = [$preloader, 100, 100, false];
				Flybox._show();
			} else {
				Flybox.fader.show(function(){
					// убираем контент в окне в пространство body
					$("*:first",$container).hide().appendTo("body");
					$container.css("overflow","hidden").append($preloader.hide().show(180));
					$box.removeAttr("style");
					if ($.browser.msie)
						$box.fadeIn(200,callback);
					else
						$box.show("scale",{},200,callback);

				});
			}
		},
		cancel: function() {
			$(this).stop();
			Flybox.preloader.callbackClose();
			Flybox.hide();
		}
	},
	ajax: function(url, options) {
		this.preloader.show();
		options = options ? options : {};
		jQuery.get(url, options.data, function(data){
			var $content = $("<div></div>").hide().html(data).appendTo("body");
			if (options.width) $content.width(options.width);
			//$content.appentTo("body");
			options.id = $content;
			Flybox.show(options);
		});
	},
	rame: function(url, width, height) {
		this.preloader.show();
		$('<iframe src="'+url+'" width="'+width+'" height="'+height+'" style="border:0">')
			.hide()
			.appendTo("body")
			.load(function(){
				$(this).unbind("load");
				if ($(this).css("display") == "none")
					Flybox.show({id:$(this),managePanelTop:true});
			});
	}
}
