var Modal = new Class({
	Implements: [Events, Options],
	options: {
		speed: 500,
		effect: '',
		maskOpacity: 0.3,
		maskColor: '#000000',
		width: 400,
		height: 'auto',
		classPrefix: 'Modal',
		onHide: $empty,
		onShow: $empty,
		onStart: $empty
	},
	initialize: function(options) {
		this.setOptions(options);
		this.isShowing = false;
		this.mask = new Element('div', {
			'class':this.options.classPrefix+'Mask',
			'styles':{
				'position':'absolute',
				'top': 0,
				'left': 0,
				'opacity': 0,
				'z-index': 9999,
				'background-color':this.options.maskColor
			},
			'events': {
				'click':this.hide.bindWithEvent(this)
			}
		});
		this.message = new Element('div',{
			'class':this.options.classPrefix+'Message',
			'styles':{
				'height':this.options.height
			}
		});
		this.title = new Element('div',{
			'class':this.options.classPrefix+'Title'
		});
		this.close = new Element('div',{
			'class':this.options.classPrefix+'Close',
			'events':{
				'click':this.hide.bindWithEvent(this)
			}
		});
		this.pop = new Element('div', {
			'class':this.options.classPrefix+'Pop',
			'styles':{
				'position': 'absolute',
				'visibility': 'hidden',
				'width': this.options.width,
				'left':'50%',
				'z-index': 10000
			}
		}).adopt(this.title, this.message, this.close);
 
		this.fx = { 
			mask: new Fx.Tween(this.mask, {property: 'opacity', duration: this.options.speed}), 
			slide: new Fx.Tween(this.pop, {property: 'top', duration:this.options.speed}),			
			fade: new Fx.Tween(this.pop, {property: 'opacity', duration:this.options.speed})
		};
		
		window.addEvents({
			'keydown': this.hide.bindWithEvent(this),
			'resize': this.update.bindWithEvent(this),
			'scroll': this.update.bindWithEvent(this)
		});
		this.fireEvent('onStart');
	},
 
	show: function(el, options) {
		this.message.empty();
		switch($type(el)) {
			case 'element':
				this.message.adopt(el.clone().cloneEvents(el));
				break;
			case 'string':
				this.message.set('html', el);
				break;
			default:
				return false;
				break;
		}
		if(options && options.title){
			this.title.set('html',options.title);
		}else{
			//this.title.empty();
			this.title.destroy();
		} 
		if(options && options.close && !options.closeCoords) {
			this.close.set('html',options.close);
			this.close.setStyles({
				color:'#FFFFFF',
				top:'2px',
				left:(options.width-60)+'px',
				textAlign:'right'
			});
		}else if(options && options.closeCoords) {
			if(options.close)
				this.close.set('html',options.close);
			var coords = options.closeCoords.split(' ');
			this.close.setStyles({
				top:coords[0],
				left:coords[1],
				width:coords[2],
				height:coords[3]
			});		
			if(options.debug) {
				this.close.setStyle('border','1px solid');
			}
		}
		if(options && options.width){
			this.pop.setStyle('width',options.width);
		}
		if(options && options.height){
			this.message.setStyle('height',options.height);
		}
		if(options && options.transparent) {
			this.message.removeClass(this.options.classPrefix+'Message');
			this.pop.removeClass(this.options.classPrefix+'Pop');
		}
		if(!this.isShowing){
 
			$$('object', 'select','embed').setStyle('visibility', 'hidden');
			$$('body').adopt(this.mask, this.pop);
			this.pop.setStyles({
				'top': window.getScroll().y - this.pop.getSize().y,
				'visibility':'visible',
				'marginLeft': -(this.pop.getSize().x/2)
			});
			var size = window.getSize();
			var scrollSize = window.getScrollSize();
			this.mask.setStyles({
				'height': (size.y > scrollSize.y)?size.y:scrollSize.y,
				'width': size.x
			});
			this.fx.mask.start(this.options.maskOpacity);
			switch(this.options.effect) {
				case 'slide': this.fx.slide.start(window.getScroll().y + (window.getSize().y/2 - this.pop.getSize().y/2));
					break;
				default:
					this.pop.setStyles({
						top:window.getScroll().y + (window.getSize().y/2 - this.pop.getSize().y/2),
						opacity:0
					});
					this.fx.fade.start(1);
			}
			this.isShowing = true;
			this.fireEvent('onShow');
		}
	},
 
	hide: function(e) {
		var event = new Event(e);
		if((event.key && event.key != 'esc')||!this.isShowing) return true;
		event.stop();
		$$('object', 'select','embed').setStyle('visibility', 'visible');
		switch(this.options.effect) {
			case 'slide':
				this.fx.slide.cancel();
				this.fx.slide.start(-this.pop.getSize().y).chain(function() {
					this.pop.setStyle('visibility','hidden').dispose();
					this.fx.mask.start(0).chain(function() {
						this.mask.dispose();
						this.isShowing = false;
						this.fireEvent('onHide');
					}.bind(this));
				}.bind(this));
				break;
			default:
				this.fx.fade.start(0).chain(function() {
					this.pop.setStyle('visibility','hidden').dispose();
					this.fx.mask.start(0).chain(function() {
						this.mask.dispose();
						this.isShowing = false;
						this.fireEvent('onHide');
					}.bind(this));
				}.bind(this));	
		}
	},
 
	update: function(e) {
		if(e) e = new Event(e).stop();
		if(this.isShowing) {
			this.fx.slide.cancel();
			var size = window.getSize();
			var scrollSize = window.getScrollSize();
			this.mask.setStyles({
				'height': (size.y > scrollSize.y)?size.y:scrollSize.y,
				'width': size.x
			});
			this.fx.slide.start(window.getScroll().y + (window.getSize().y/2 - this.pop.getSize().y/2))
		}
	},
	
	updateContent: function(html) {
		this.message.set('html',html);
	}
	
});