/*
 * Попапы с текстом
 */
var POPUP = function(options) {
	var self = this,
		config =$.extend({
			object:null,
			container:null,
			container_tail:null,
			name:'',
			height: function() { return $('html').height()+150 },
			duration:500
		}, options || {});
	this.container = $(config.container);
	this.container_tail = $(config.container_tail);
	this.object = $(config.object);
	this.object[0].popup_constructor = this;
	this.close_object = $('.close', this.object);
	this.bad_browser = $.browser.msie && $.browser.version < 7;
	
	this.object.css({marginTop:-config.height()});
	
	this.create = function() {
		this.object.addClass('popup');
		this.context = null;
		this.direction = true;
	}
	
	if(this.bad_browser) this.object.hide();
	
	this.show_ie6 = function(target) {
		self.object.trigger("POPUP_BEFORE_SHOW");
		self.container.show();
		self.object.show().css({marginTop:$(document).scrollTop()+30});
		self.object.find('.ie-shadow').height(self.object.height());
		self.object.removeClass('pause_popup').addClass('active_popup');
		self.object.trigger("POPUP_SHOW");
	}
	
	this.hide_ie6 = function(is_up) {
		where = is_up ? !!is_up : self.direction;
		self.object.add(self.container_tail).hide();
		self.object.removeClass('active_popup');
		is_up || ( self.object.addClass('pause_popup') );
		if(self.context) {
			self.context.object.css({marginTop:0}).removeClass('pause_popup').addClass('active_popup');
			self.direction = true;
			self.context = null;
			try {
				self.object.context.trigger("POPUP_SHOW");
			} catch(err) {}
		}
		self.object.trigger("POPUP_HIDE");
	}
	
	this.show = function(target) {
		if(self.bad_browser) return self.show_ie6.call(this, target || null);
		self.object.trigger("POPUP_BEFORE_SHOW");
		self.container.show();
		//self.object.stop().animate({marginTop:0},{
		self.object.stop().animate({marginTop:$(document).scrollTop()},{
			duration:config.duration,
			step: function(px, fx) {
				if(!self.context) self.container_tail[0].style.marginBottom = -1*px+'px';
			},
			easing:'easeOutBack'
		});
		if(this != self && this.object) {
			self.context = this;
			self.direction = false;
			this.hide(false);
		} else {
			self.container.attr('class', 'popup_container_'+config.name);
		}
		self.object.removeClass('pause_popup').addClass('active_popup');
		self.object.trigger("POPUP_SHOW");
	}
	
	this.hide = function(is_up) {
		if(self.bad_browser) return self.hide_ie6.call(this, is_up);
		where = is_up ? !!is_up : self.direction;
		self.object.add(self.container_tail).stop().animate({marginTop:is_up ? -config.height()-250 : config.height()},{
			duration:config.duration,
			step:self.context ? false : function(px, fx) {
				self.container_tail[0].style.marginBottom = -1*px+'px';
			},
			easing:'easeOutQuad'
		});
		self.object.removeClass('active_popup');
		is_up || ( self.object.addClass('pause_popup') );
		if(self.context) {
			self.context.object.stop().animate({marginTop:0},{
				duration:config.duration,
				step: function(px, fx) {
					self.container_tail[0].style.marginBottom = -1*px+'px';
				},
				easing:'rosnoEaseOutBounce'
			}).removeClass('pause_popup').addClass('active_popup');
			self.direction = true;
			self.context = null;
			try {
				self.object.context.trigger("POPUP_SHOW");
			} catch(err) {}
		}
		self.object.trigger("POPUP_HIDE");
	}
	
	this.hideChain = function() {
		self.object.trigger("POPUP_HIDE");
		self.object.stop().animate({marginTop:-config.height()},{
			duration:config.duration,
			step:self.context ? false : function(px, fx) {
				self.container_tail[0].style.marginBottom = -1*px+'px';
			},
			easing:'rosnoEaseOutBounce'
		}).removeClass('active_popup');
		if(self.context){
			self.context.object.stop().animate({marginTop:-config.height()},{
				duration:config.duration*2,
				step:function(px, fx) {
					self.container_tail[0].style.marginBottom = -1*px+'px';
				},
				easing:'rosnoEaseOutBounce'
			}).removeClass('pause_popup');
			self.object.context.trigger("POPUP_HIDE");
		}
		self.context = null;
	}
	
	this.clickListener = function(e) {
		if(e.target.rel) {
			e.preventDefault();
			e.stopPropagation();
			popup_name = (/^popup\[(.+)\]$/).exec(e.target.rel);
			if(popup_name && (popup_name = popup_name[1]) ) {
				if(popup_manager.popups[popup_name]) {
					popup_manager.popups[popup_name].show.call(self, e.target);
				}
			}
		}
	}

	this.object.click(this.clickListener);
	this.close_object.click(self.hide);

	this.create();
	self.object.trigger("POPUP_CREATE");
}

/*
 * Менеджер кастомных элементов форм
 */
var POPUP_MANAGER = function(options) {
	var self = this,
		config =$.extend({
			objects:'#popups .popup',
			container:'#popups',
			container_tail:'#popups .tail',
			duration:500
		}, options || {});
	
	this.init = function() {
		self.container = $(config.container);
		self.container_tail = $(config.container_tail);
		self.timeout = null;
		self.popups = {};
		self.objects = $(config.objects).each(function(){
			var name = (/popup_([^ ]+)$/).exec( $(this).attr("class") );
			if(name && name[1]) self.popups[name[1]] = new POPUP({object:this, name:name[1], container:self.container, container_tail:self.container_tail, duration:config.duration});
		});
		$(document).click(self.documentListener);
	}
	
	this.documentListener = function(e) {
		if(e.target.rel) {
			e.preventDefault();
			popup_name = (/^popup\[(.+)\]$/).exec(e.target.rel);
			if(popup_name && (popup_name = popup_name[1]) ) {
				if(self.popups[popup_name]) {
					clearTimeout(self.timeout);
					var active = self.objects.filter('.active_popup')[0];
					if(!active || self.popups[popup_name].object[0] != active) {
						self.timeout = setTimeout(self.popups[popup_name].show, self.objects.filter('.pause_popup')[0] ? config.duration*2.01 : config.duration*1.01);

						if(active) {
							active.popup_constructor.hideChain();
						}
					}
				}
			}
		}
	
	}
	
	this.g = function(selector) {
		return $(selector, self.objects).data("constructor");
	}
	this.c = function(selector) {
		return $(selector, self.objects).data("constructor");
	}

}

var popup_manager = new POPUP_MANAGER();
$(popup_manager.init);
