/**
 * ModaLay Base Class...
 */

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

	options: {
		// prefix for css-elements:
		cssPrefix: 'ml_',
		// options for overlay:
		overlayZIndex: 10,
		overlayColor: '#000',
		overlayOpacity: 0.7,
		overlayClickable: true,
		overlayScrollable: true,
		// options for centered box:
		boxWidth: 300,
		boxHeight: 200,
		boxColor: '#FFF',
		boxBorderWidth: 10,
		boxBorderColor: '#8A8A8A',
		// width and height of content:
		contentWidth: 600,
		contentHeight: 400,
		contentEmpty: true,
		// height of bottom:
		bottomHeight: 32,
		// close-event-function:
		onClose: $empty,
		// MacMozFlash-opacity-bugfix:
		// PNG with alpha as opacity-replacement:
		macMozFlashPNG: 'images/overlay.png'
	},

	initialize: function(links, options){
		// set options:
		this.setOptions(options);
		// add click-event to provided links:
		if (links.length){
			links.each(function(link){
				link.addEvent('click', function(ev){
					ev.stop();
					this.link = link.get('href');
					this.linkTitle = link.get('text').trim() || link.getFirst().get('alt');
					this.show('overlay');
				}.bind(this));
			}, this);
		}
		// bound event-functions, needed for removing events:
		this.positionBound = this.position.bind(this);
		this.hideBound = this.hide.bind(this);
		// MacMozFlash-opacity-bugfix:
		// check for Mac, and flash on page:
		var macFlash = Browser.Platform.mac && $$('object[type=application/x-shockwave-flash]'
		, 'embed[type=application/x-shockwave-flash]').length > 0;
		// Mac and Moz and flash on page:
		this.options.macMozFlash = macFlash && Browser.Engine.gecko;
		// Mac and Opera and flash on page:
		this.options.macOpFlash = macFlash && Browser.Engine.presto;
	},

	// create html-elements:
	create: function(el){
		this[el] = new Element('div', {
			id: this.options.cssPrefix + el
		});
		switch(el){
			// add overlay element:
			case 'overlay':
				this.overlay.set({
					styles: {
						position: 'absolute',
						left: 0,
						width: '100%',
						'z-index': this.options.overlayZIndex,
						// MacMozFlash-opacity-bugfix:
						'background': this.options.macMozFlash
						? 'transparent url(' + this.options.macMozFlashPNG + ')'
						: this.options.overlayColor
					},
					tween: {
						onComplete: function(){
							if (this.overlay.get('opacity'))
								this.overlay.fireEvent('onShow');
							else
								this.overlay.fireEvent('onHide');
						}.bind(this)
					},
					events: {
						onShow: function(){
							// add click event to overlay:
							if (this.options.overlayClickable)
								this.overlay.addEvent('click', this.hideBound);
							// go ahead by showing centered box:
							this.show('box');
						}.bind(this),
						onHide: function(){
							if (this.hidden.length)
								$$(this.hidden).setStyle('visibility', 'visible');
							this.fireEvent('onClose');
						}.bind(this)
					}
				}).inject(document.body);
				// MacMozFlash-opacity-bugfix:
				if (this.options.macMozFlash)
					this.overlay.setStyle('visibility', 'hidden');
				else
					this.overlay.fade('hide');
				break;
			// add centered box:
			case 'box':
				this.box.set({
					styles: {
						display: 'none',
						position: 'absolute',
						left: window.getScroll().x + window.getSize().x / 2, //'50%',
						top: window.getScroll().y + window.getSize().y / 2, //'50%', 
						'z-index': this.options.overlayZIndex + 1,
						'background-color': this.options.boxColor,
						border: this.options.boxBorderWidth + 'px solid ' + this.options.boxBorderColor,
						overflow: 'visible'
					},
					morph: {
						onComplete: function(){
							this.content.setStyles({
								width: this.options.contentWidth || 'auto',
								height: this.options.contentHeight || 'auto',
								display: 'block',
								visibility: 'visible'
							});
							this.show('bottom');
						}.bind(this)
					}
				}).inject(document.body);
				this.create('content')
				this.create('bottom');
				break;
			// add content-div:
			case 'content':
				this.content.setStyle('display', 'none').inject(this.box);
				break;
			// add bottom-div:
			case 'bottom':
				this.bottom.set({
					styles: {
						height: this.options.bottomHeight || 'auto',
						'background-color': this.options.boxBorderColor
					}
				}).adopt(new Element('a', {
					id: this.options.cssPrefix + 'close',
					href: 'javascript:void(0);',
					events: {
						click: this.hide.bind(this)
					}
				})).inject(this.box).slide('hide');
				break;
		}
	},

	// show elements:
	show: function(el){
		if (!this[el]) this.create(el);
		switch(el){
			// show overlay:
			case 'overlay':
				this.hidden = [];
				if (Browser.Engine.trident)
					this.hidden.extend($$('select'));
				if (this.options.macOpFlash){
					$$('object[type=application/x-shockwave-flash]'
					, 'embed[type=application/x-shockwave-flash]').each(
						function(obj) {
							obj = obj.getParent();
							if (obj.getStyle('visibility') == 'visible')
								this.hidden.push(obj);
						}, this
					);
				}
				if (this.hidden.length)
					$$(this.hidden).setStyle('visibility', 'hidden');
				// MacMozFlash-opacity-bugfix:
				// no fade and no opacity:
				if (this.options.macMozFlash)
					this.position().setStyle('visibility', 'visible').fireEvent('onShow');
				else
					this.position().fade(this.options.overlayOpacity);
				// add window events (resize and scroll):
				window.addEvents({
					'resize': this.positionBound,
					'scroll': this.positionBound
				});
				break;
			// show centered box:
			case 'box':
				this.box.setStyles({
					display: 'block',
					visibility: 'visible',
					width: this.options.boxWidth,
					height: this.options.boxHeight,
					'margin-left': -(((this.options.boxWidth
					+ this.options.boxBorderWidth * 2) / 2).toInt()),
					'margin-top': -(((this.options.boxHeight
					+ this.options.boxBorderWidth * 2) / 2).toInt())
				}).addClass(this.options.cssPrefix + 'loading');
				this.load();
				break;
			// resize box and show content:
			case 'content':
				var cW = this.options.contentWidth || this.content.getSize().x;
				var cH = this.options.contentHeight || this.content.getSize().y;
				var bH = this.options.bottomHeight || this.bottom.getSize().y;
				this.box.morph({
					width: cW,
					height: cH,
					'margin-left': -(((cW + this.options.boxBorderWidth * 2) / 2).toInt()),
					'margin-top': -(((cH + bH + this.options.boxBorderWidth * 2) / 2).toInt())
				}).removeClass(this.options.cssPrefix + 'loading');
				break;
			// show box-bottom:
			case 'bottom':
				this.box.setStyle('height', 'auto');
				this.bottom.slide('in');
				break;
		}
	},

	// position overlay:
	position: function(){
		if (this.box) {
			this.box.setStyles({
				left: window.getScroll().x + window.getSize().x / 2,
				top: window.getScroll().y + window.getSize().y / 2
			});
		}
		return this.overlay.setStyles({
			left: window.getScroll().x,
			top: window.getScroll().y,
			width: window.getSize().x,
			height: window.getSize().y
		});
	},

	// load content (dummy-function):
	load: function(){
		(function(){
			this.show('content');
			this.content.setStyle('background-color', '#000');
		}.bind(this)).delay(1000);
	},

	// hide ModaLay:
	hide: function(){
		// hide box, content, and bottom divs:
		//this.box.setStyle('display', 'none');
		this.box.setStyle('visibility', 'hidden');
		if (this.options.contentEmpty)
			this.content.empty()
		this.content.setStyles({
			//display: 'none',
			visibility: 'hidden',
			width: 'auto',
			height: 'auto'
		});
		this.bottom.slide('hide');
		// hide overlay:
		// MacMozFlash-opacity-bugfix:
		if (this.options.macMozFlash){
			this.overlay.setStyle('visibility', 'hidden');
			this.fireEvent('onClose');
		}
		else
			this.overlay.fade('out');
		// remove events:
		this.overlay.removeEvent('click', this.hideBound);
		window.removeEvent('resize', this.positionBound)
		.removeEvent('scroll', this.positionBound);
	}

});
