Odx.ModalPopup = new Class ({
	
	/**************************************
		Static Members
	**************************************/
	getOptions: function()
	{
		return {
			'duration'			: 250,
			'transition'		: Fx.Transitions.quadOut,
			'backgroundColor'	: 'black',
			'maxOpacity'		: .5,
			'closeOnClick'		: false,
			'top'				: 'auto'
		};
	},
	
	
	/**************************************
		Constructor
	**************************************/
	initialize: function(id, trigger, triggerEvent, closeTrigger, closeTriggerEvent, options)
	{
		this.setOptions(this.getOptions(), options);
		
		return this
			.SetId(id)
			.SetTrigger(trigger, triggerEvent)
			.SetCloseTrigger(closeTrigger, closeTriggerEvent)
			._CreateOverlay()
			._CreateContainer()
			._CreateEffect()
			._PrepareContent()
			._AttachEvents()
		;
	},
	
	
	/**************************************
		Public Properties
	**************************************/
	GetId: function()
	{
		return this.$_id;
	},
	
	SetId: function(id)
	{
		this.$_content = $(id);
		this.$_id = this.$_content.getProperty('id') || 'Modal';
		return this;
	},
	
	GetContent: function()
	{
		return this.$_content;
	},
	
	GetOverlay: function()
	{
		return this.$_overlay;
	},
	
	GetContainer: function()
	{
		return this.$_container;
	},
		
	SetTrigger: function(trigger, triggerEvent)
	{
		this.$_trigger = $(trigger);
		
		if (this.$_trigger)
			this.$_trigger.addEvent(triggerEvent, this.Show.bind(this));
		
		return this;
	},
	
	SetCloseTrigger: function(trigger, triggerEvent)
	{
		this.$_closeTrigger = $(trigger);
		
		if (this.$_closeTrigger)
			this.$_closeTrigger.addEvent(triggerEvent, this._OnClose.bindWithEvent(this));
			
		return this;
	},
	
	IsOpen: function()
	{
		return this.GetOverlay().IsOpen();
	},
	
	
	/**************************************
		Private Methods
	**************************************/
	_CreateOverlay: function()
	{
		this.$_overlay = new Odx.Overlay(this.GetId() + '_Overlay', window, this.options)
			.addEvent('closing', this._HideContainer.bind(this))
			.addEvent('opening', this._ShowContainer.bind(this))
		;
		
		return this;
	},
	
	_CreateContainer: function()
	{
		if (window.ie6)
		{
			this.$_container = new Element('div')
				.setStyles({
					'position'		: 'absolute',
					'text-align'	: 'center',
					'width'			: '100%',
					'left'			: 0,
					'opacity'		: 0
				})
			;
			
			window.onscroll = function()
			{
				this.$_container.setStyle('top', this.options.top + window.getScrollTop());
			}.bind(this);
		}
		else
		{
			this.$_container = new Element('div')
				.setStyles({
					'position'		: 'fixed',
					'text-align'	: 'center',
					'width'			: '100%',
					'left'			: 0,
					'opacity'		: 0
				})
			;
		}
			
		if (this.options['closeOnClick'])
		{
			this.$_container
				.addEvent('click', this.Hide.bind(this))
				.setStyle('cursor', 'pointer')
			;
		}
		
		return this;
	},
	
	_CreateEffect: function()
	{
		this.$_effect = new Fx.Style(
			this.GetContainer(),
			'opacity',
			{
				'duration'		: this.options['duration'],
				'transition'	: this.options['transition'],
				'onComplete'	: this._OnEffectComplete.bind(this)
			}
		);
		
		return this;
	},
	
	_PrepareContent: function()
	{
		this.GetContent()
			.setStyles({ 
				'display':	'block',
				'margin':	'0 auto'
			})
			.injectInside(this.GetContainer())
		;
		
		return this;
	},
	
	_AttachEvents: function()
	{
		window.addEvent('resize', this._Reposition.bind(this));
		return this;
	},
	
	_Reposition: function()
	{
		var
			windowSize		= window.getSize().size,
			containerSize	= this.GetContainer().getSize().scrollSize;
		
		this.GetContainer().setStyles({
			'top': this.options['top'] == 'auto' ? Math.round((windowSize.y - containerSize.y) / 2) : this.options['top']
		});
	},
	
	_ShowContainer: function()
	{
		if (this.IsOpen())
		{
			document.body.appendChild(this.GetContainer());
			this._Reposition();
			this.$_effect.start(0, 1);
		}
		
		return this;
	},
	
	_HideContainer: function()
	{
		if (!this.IsOpen())
		{
			this.$_effect.start(this.options['maxOpacity'], 0).chain(
				this.GetContainer().remove.bind(this.GetContainer())
			);
		}
		
		return this;
	},
	
	_OnEffectComplete: function()
	{
		if (this.IsOpen())
			this.fireEvent('open');
		else
			this.fireEvent('close');
	},
	
	/**************************************
		Public Methods
	**************************************/
	Show: function()
	{
		this.GetOverlay().Show();
		return this;
	},
	
	Hide: function()
	{
		this.GetOverlay().Hide();
		return this;
	},
	
	/**************************************
		Event Handling
	**************************************/
	_OnClose: function(e)
	{
		e.stop();
		return this.Hide();
	}
});

Odx.ModalPopup.implement(new Options, new Events);
