/*
- load overlay:
window.overlay = new Overlay();

- set close onclick on overlay, then show.
window.overlay.setOpt({onClick: window.overlay.hide.bind(window.overlay)});
window.overlay.show();

- or hide it:
window.overlay.hide();

*/

var Overlay = Class.create({
	initialize: function(options) {
		this._options = {
			parent: false,
			speed: 0.2,
			animate: true,
			id: 'layerOverlay',
			beforeShow: function(){},
			afterShow: function(){},
			beforeHide: function(){},
			afterHide: function(){},
			onClick: function(){}
		};		
		this._style = {
			backgroundColor: '#000',
			display: 'none',
			height: '100%',
			left: 0,
			opacity: 0.4,
			position: 'fixed',
			top: 0,
			width: '100%',
			zIndex: 1000,
			zoom: 1
		};
		
		if(Prototype.Browser.MobileSafari) {
			var arrayWindowSize = this._getWindowSize();
			this._style = Object.extend(this._style, {
				position: 'absolute', 
				width: arrayWindowSize[0] + 'px',
				height: arrayWindowSize[1] + 'px'
			});
		}
		
		// build overlay ..
		this.overlay = new Element('div', {'id':this._options.id});
		// .. and set options (also inserts overlay)
		this.setOpt((options || {}));
	},
	setOpt: function(options) {
		this._options = Object.extend(this._options, options);
		if(typeof(options.style) === 'object') {
			this._style = Object.extend(this._style, options.style);
		}
		this.overlay.setStyle(this._style);
		this._options.style = null;
		// check if parent has changed, if yes, move overlay.
		if(this._options.parent != this.parent) {
			this.parent = (this._options.parent || $$('body')[0]);
			this.parent.insert(this.overlay);
		}
		// check if id has changed
		if(this._options.id != this.overlay.id) {
			this.overlay.id = this._options.id;
		}
	},
	show: function() {
		try {
			if(!this._options.animate) throw 'no animation wanted';
			this.overlay.appear({ 
				duration: this._options.speed,
				to: this._style.opacity, 
				beforeStart: this._hideSelects.bind(this), 
				afterFinish: this._absolutize.bind(this) 
			});
		} catch(e) {
			this._hideSelects();
			this.overlay.show();
			this._absolutize();
		}
	},
	hide: function() {
		try {
			if(!this._options.animate) throw 'no animation wanted';
			this.overlay.fade({
				duration: this._options.speed,
				beforeStart: this._options.beforeHide,
				afterFinish: this._showSelects.bind(this)
			});
		} catch(e) {
			this._options.beforeHide();
			this.overlay.hide();
			this._showSelects();
		}
	},
	_hideSelects: function() {
		this._options.beforeShow();
		if(!Prototype.Browser.IE) return;
		$$('select').each(function(element) {
			if(element.getStyle('visibility') != 'hidden') {
				element.setStyle({ visibility: 'hidden' });
				element.writeAttribute('hiddenforoverlay', 'true');
			}
		}.bind(this));
	},
	_showSelects: function() {
		this._options.afterHide();
		this.overlay.stopObserving('click');
		if(!Prototype.Browser.IE) return;
		selects = $$('select[hiddenforoverlay]');
		selects.invoke('setStyle', {visibility:'visible'});
		selects.invoke('writeAttribute', 'hiddenforoverlay', false);
	},
	_absolutize: function() {
		this._options.afterShow();
		this.overlay.observe('click', this._options.onClick);
		if(!this.overlay.offsetTop && this.parent.nodeName == 'BODY') return;
		this.overlay.setStyle({
			position: 'absolute',
			height: this.parent.getStyle('height'),
			width: this.parent.getStyle('width')
		});
	},
	_getWindowSize: function() {
	    var xScroll, yScroll;
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = window.innerWidth + window.scrollMaxX;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		var windowWidth, windowHeight;
		if (self.innerHeight) {	// all except Explorer
			if(document.documentElement.clientWidth){ windowWidth = document.documentElement.clientWidth; } 
				else { windowWidth = self.innerWidth; }
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}
		// for small pages with total height less then height of the viewport
		if(yScroll < windowHeight){ pageHeight = windowHeight; } 
			else { pageHeight = yScroll; }
		// for small pages with total width less then width of the viewport
		if(xScroll < windowWidth){ pageWidth = xScroll;	}
			else { pageWidth = windowWidth; }
		return [pageWidth,pageHeight];
	}
});
