
/*
 * Popup modal windows
 */

var Overlay = new Class({
 	Implements: [Options, Events],

	options: {
		opacity: 0.6,
		className: 'overlay',
		background: '',
		zIndex: 100,
		closeByClick: true
	},

	initialize: function(options) 
	{
		this.setOptions(options);
		this.overlay = null;
		this.listeners = {
			resize: this.resize.bind(this),
			click: this.click.bind(this)
		};
	},

	toggleListeners: function(state) 
	{
		var task = state ? 'addEvent' : 'removeEvent';
		window[task]('resize', this.listeners.resize);
		window[task]('scroll', this.listeners.resize);
	},

	build: function() 
	{
		if (!this.overlay) 
		{
			this.overlay = new Element('div', {
				'class': this.options.className,
				'styles': {
					'position': Browser.Engine.trident ? 'absolute' : 'fixed',
					'left': 0,
					'top': 0,
					'width': 1,
					'height': 1,
					'padding': 0,
					'margin': 0,
					'opacity': 0,
					'visibility': 'hidden',
					'z-index': this.options.zIndex
				}
			}).inject(document.body, 'top');
			
			if (this.options.background != '')
				this.overlay.setStyle('background', this.options.background);

			this.overlay.addEvent('click', this.listeners.click);
			this.overlay.addEvent('mouseup', function(event) { new Event(event).stop(); } );
		}
	},

	resize: function() 
	{
		this.fireEvent('resize');
		
		if (this.overlay) {
			var sizes = {
				scroll: window.getScroll(),
				scrollSize: window.getScrollSize(),
				size: window.getSize()
			}
			if (Browser.Engine.trident) {
				this.overlay.setStyles({
					'left': sizes.scroll.x,
					'top': sizes.scroll.y
				});
			}
			this.overlay.setStyles({
				'width': sizes.size.x,
				'height': sizes.size.y
			});
		}
	},

	show: function() 
	{
		if (this.overlay && this.overlay.getStyle('visibility') != 'hidden') return;
		this.fireEvent('show');
		this.build();
		if (this.overlay) {
			this.resize();
			this.toggleListeners(true);
			this.overlay.setStyle('visibility', 'visible').set('tween', {duration: 250}).tween('opacity', this.options.opacity);
		}
	},

	hide: function() 
	{
		if (!this.overlay || this.overlay.getStyle('visibility') == 'hidden') 
			return;
			
		this.fireEvent('hide');
		if (this.overlay) 
		{
			this.toggleListeners(false);
			this.overlay.set('tween', {
				duration: 250,
				onComplete: function() {
					this.overlay.setStyles({
						'visibility': 'hidden',
						'left': 0,
						'top': 0,
						'width': 0,
						'height': 0
					});
				}.bind(this)
			}).tween('opacity', 0);
		}
	},

	click: function() 
	{
		this.fireEvent('click');
		if (this.options.closeByClick)
			this.hide();
	},

	destroy: function() 
	{
		if (!this.overlay)
			return;

		this.toggleListeners(false);
		this.overlay.removeEvent('click', this.listeners.click);
		this.overlay.destroy();
		this.overlay = null;
	}
});

PopupForm = new Class({
 	Implements: [Options, Events],
	Binds: ['cancel'],

	formLoadHandler: null,
	overlay: null,
	formContainer: null,
	tmp: null,

	options: {
		opacity: 0.6,
		className: 'popupForm',
		background: '',
		zIndex: 101,
		closeByClick: true,
		ajaxFields: {},
		closeByEsc: true
	},

	initialize: function(formLoadHandler, options)
	{
		this.setOptions(options);
		this.formLoadHandler = formLoadHandler;
		this.show();
		window.PopupWindows.push(this);
	},
	
	show: function()
	{
		this.overlay = new Overlay({
			onClick: cancelPopup, 
			onResize: this.alignForm.bind(this), 
			closeByClick: this.options.closeByClick,
			zIndex: 101 + window.PopupWindows.length + 1
		});
		
		addPopup();
		
		this.overlay.show();

		this.formContainer = new Element('div', {
			'class': 'popupLoading',
			'styles': {
				'position': Browser.Engine.trident ? 'absolute' : 'fixed',
				'visibility': 'hidden',
				'z-index': this.options.zIndex + window.PopupWindows.length + 1
			}
		}).inject($('content'), 'top');

		this.tmp = new Element('div', {'styles': {'visibility': 'hidden', 'position': 'absolute'}}).inject($('content'), 'top');
		new Element('div', {'class': 'popupForm'}).inject(this.tmp, 'top');

		this.alignForm();
		this.formContainer.setStyle( 'visibility', 'visible' );
		
		if (this.options.closeByEsc)
	    	$(document).addEvent('keyescape', this.cancel);
		
		new Request.Phpr({url: location.pathname, handler: this.formLoadHandler, extraFields: this.options.ajaxFields, update: this.tmp.getFirst(), 
		loadIndicator: {show: false}, onSuccess: this.formLoaded.bind(this)}).post({});
	},
	
	cancel: function() 
	{
		this.destroy();
	    $(document).removeEvent('keyescape', this.cancel);
		return false;
	},

	formLoaded: function()
	{
		var newSize = this.tmp.getSize();

		var myEffect = new Fx.Morph(this.formContainer, {
			duration: 'short', 
			transition: Fx.Transitions.Sine.easeOut, 
			onStep: this.alignForm.bind(this),
			onComplete: this.loadComplete.bind(this)});

		myEffect.start({
		    'height': newSize.y,
		    'width': newSize.x+1
		});
	},
	
	loadComplete: function()
	{
		this.tmp.getFirst().inject(this.formContainer);
		this.tmp.destroy();
		this.formContainer.removeClass('popupLoading');
		this.formContainer.setStyles({'width': 'auto', 'height': 'auto'});
		
		var top_element = this.formContainer.getFirst().getFirst();
		if (top_element)
			top_element.fireEvent('popupLoaded');
	},
	
	alignForm: function()
	{
		if (!this.formContainer)
			return;

		var windowSize = window.getSize();
		var formSize = this.formContainer.getSize();

		if (!Browser.Engine.trident)
		{
			this.formContainer.setStyles({
				'left': Math.round(windowSize.x/2-formSize.x/2),
				'top': Math.round(windowSize.y/2-formSize.y/2)
			});
		} else
		{
			var scroll = window.getScroll();
			var scrollSize = window.getScrollSize();

			this.formContainer.setStyles({
				'left': Math.round(windowSize.x/2-formSize.x/2),
				'top': Math.round(scroll.y + windowSize.y/2-formSize.y/2)
			});
		}
	},
	
	destroy: function()
	{
		this.overlay.destroy();
		this.formContainer.destroy();
		window.PopupWindows.pop();
	}
});

window.PopupWindows = [];

function cancelPopup()
{
	if (window.PopupWindows.length)
		window.PopupWindows.getLast().cancel();
		
	if (!window.PopupWindows.length)
		window.fireEvent('popupHide');

	return false;
}

function cancelPopups()
{
	while (window.PopupWindows.length)
		cancelPopup();
}

function addPopup()
{
	if (window.PopupWindows.length == 0)
		window.fireEvent('popupDisplay');
}

function realignPopups()
{
	window.PopupWindows.each(function(popup){popup.alignForm()});
}
