var thisNamespace = 'lib.Overlay';
var thisPackage   = {

	visible: false,
	
	initialized: false,
	
	element: Object,
	
	content: Object,
	
	indicator: Object,
	
	initialize: function() {
	
		var self = lib.Overlay;
		
		self.element = $('lightbox');
		self.background = $('lightbox-background');
		self.container = $('lightbox-master-container');
		self.content = $('lightbox-content');
		self.indicator = self.element.down('.lightbox-loading-indicator');
		self.flashVideoPlayer = $('js-flash-video-player-container');
		
		// temporary fixed bug #339
		// variable pageHasOverlay is cached. this give us an unexpected result :-)
		if (modules.Master.getData('pageHasOverlay') && (self.element.visible() || !self.element.hasClassName('hidden'))) {
			self.showEmbedded(false);
		}
		
		self.visible = !self.element.hasClassName('hidden');
		
		if (self.content && self.initialized == false) {
			self.initialized = true;
			Event.observe(window, "scroll", self.handleEventResize);
			Event.observe(window, "resize", self.handleEventResize);
			Event.observe(window, "keypress", function(event) {
				var keyCode = event.keyCode || event.which;
				if (keyCode == Event.KEY_ESC) {
					self.hide();
				}
			});
			
			document.observe('yc:div_updated', function(event) {
				if(!self.visible) return;
				if (event.target.down('#lightbox-content')) {
					self.initialize();
				}
			});
		}
		
		self.refreshBackground();
	},
	
	refreshBackground: function() {
		var self = lib.Overlay;
		self.background.setStyle({height: lib.Helper.getPageSize().pageHeight + 'px'});
	},
	
	handleEventResize: function() {
		
		var self = lib.Overlay;
		
		if (!self.visible) return;
		
		// only fix the position of lightbox, if enought height available
		var contentHeight = parseInt(self.content.getStyle('top')) + self.content.getHeight(); 
		
		if (contentHeight > lib.Helper.getPageSize().windowHeight) return;
		
		var offset = document.viewport.getScrollOffsets();
		
		if (self.content) {
			self.content.setStyle({marginTop: offset.top + "px"});
		}
		
		self.refreshBackground();
	},
	
	show: function(content) {
		
		var self = lib.Overlay;
		
		self.initialize();
		
		if(content) {
			self.update(content);
		}
		
		if(!self.visible) {
			self.showEmbedded(false);
			self.visible = true;
		}
		
		self.element.removeClassName('hidden');
	
		if(!content) {
			self.indicator.removeClassName('hidden');
			self.container.update('');
		}
	},
	
	setContentFromUrl: function(url, events) {
		
		var self = lib.Overlay;
		
		events = events || {};
		
		var ajaxRequest = new Ajax.Request(url, {
			method: 'get',
			requestHeaders: {Accept: 'text/html'},
			evalScripts: true,
			onCreate: function() {
				if(typeof events.onCreate == 'function') {
					events.onCreate();
				}
			},
			onSuccess: function(t) {
				if(typeof events.onSuccess == 'function') {
					events.onSuccess();
				}
			},
			onComplete: function(t) {
				// This will also reset our loading indicator
				self.update(t.responseText);
				self.setLightboxLocation(url);
				if(typeof events.onComplete == 'function') {
					events.onComplete();
				}
			},
			onFailure: function(t) {
				self.indicator.addClassName('hidden');
				if(typeof events.onFailure == 'function') {
					events.onFailure();
				}
			}
		});
	},
	
	showAndLoadFromUrl: function(url, events) {
		
		var self = lib.Overlay;
		
		events = Object.extend(events || {}, {
			onCreate: function() {
				self.show();
			}
		});
		
		self.setContentFromUrl(url, events);
	},
	
	showAlert: function(message) {
		var self = lib.Overlay;
		message = '<div id="lightbox-content" class="alert">'
			+ '<h2>' + __('Hinweis') + '</h2>' 
			+ message 
			+ '<a class="button button-icon-close js-lightbox-close" href="#nolink">' + __('schließen') + '</a>'
			+ '</div>';
		self.show(message);
	},
	
	/**
	 * Displays a confirm dialog as overlay.
	 * 
	 * @param String content    The message/question to display.
	 * @param Object parameters Hash map of dialog options, here is the key list:
	 * 		Key                 Default    Description
	 * 		okLabel             Ok         Ok button label
	 * 		cancelLabel         Abbrechen  Cancel button label
	 * 		className           confirm    CSS class name for the window, message and button containers
	 * 		buttonClass         none       Ok/Cancel button css class name 
	 * 		okButtonClass       none       Ok button css class name 
	 * 		cancelButtonClass   none       Cancel button css class name 
	 * 		onOk                none       Ok callback function called when ok button is pressed
	 * 		onCancel            none       Cancel callback function called when cancel button is pressed
	 * 		callbackParameters  none       Parameters for the ok and cancel callback functions
	 * 		okParameters        none       Parameters for the ok callback function
	 * 		cancelParameters    none       Parameters for the cancel callback function
	 * 		title               none       Dialog window title
	 */
	showConfirm: function(content, parameters) {
		var self = lib.Overlay;
		
		// generate unique id
		var id = new Date().getTime();

		// create a global registry if not yet available
		if (typeof window.__lib_overlay_confirms == 'undefined') {
			window.__lib_overlay_confirms = {};
		}
		
		// create a namespace in the registry
		window.__lib_overlay_confirms[id] = {};
		
		// if a lightbox is open ...
		if (self.visible) {
			// put it away while the confirm is displayed
			window.__lib_overlay_confirms[id].hidden = self.container.down();
			self.hide();
		}
		
		// set default parameters if not specified
		parameters = parameters || {};
		parameters.okLabel = parameters.okLabel || __('Ok');
		parameters.cancelLabel = parameters.cancelLabel || __('Abbrechen');
		parameters.className = parameters.className || 'confirm';
		
		// save parameters for later use in self.confirmCallback
		window.__lib_overlay_confirms[id].parameters = parameters;
		
		// build HTML for the dialog
		var buttonClass = (parameters.buttonClass ? ' ' + parameters.buttonClass : '');
		var okButtonClass = 'button button-ok' + buttonClass + (parameters.okButtonClass ? ' ' + parameters.okButtonClass : '');  
		var cancelButtonClass = 'button button-abort-default2' + buttonClass + (parameters.cancelButtonClass ? ' ' + parameters.cancelButtonClass : '');  
		var content = '<div id="lightbox-content" class="confirm">'
			+ '  <h2>' + (parameters.title || '&nbsp;') + '</h2>'
			+ '  <div class="' + parameters.className + '-message">' + content  + '</div>'
			+ '  <div class="' + parameters.className + '-buttons">'
			+ '    <input type="button" value="' + parameters.okLabel + '" onclick="lib.Overlay.confirmCallback(\'' + id + '\', true)" class="' + okButtonClass + '"/>'
			+ '    <input type="button" value="' + parameters.cancelLabel + '" onclick="lib.Overlay.confirmCallback(\'' + id + '\', false)" class="' + cancelButtonClass + '"/>'
			+ '  </div>'
			+ '  <a class="button button-icon-close js-lightbox-close" href="#nolink" onclick="lib.Overlay.confirmCallback(\'' + id + '\', false)">' + __('schließen') + '</a>'
			+ '</div>';
		
		// show dialog as overlay
		self.show(content);
		self.handleEventResize();
	},
	
	/**
	 * Callback for buttons in the confirm dialog.
	 * 
	 * @see lib.Overlay.showConfirm
	 * 
	 * @param String id		The key in the global confirm dialog registry.
	 * @param bool ok		Indicates which button the user pressed. Ok = true, Cancel = false
	 */
	confirmCallback: function(id, ok) {
		var self = lib.Overlay;

		// check for required parameters 
		if (!id || typeof window.__lib_overlay_confirms == 'undefined' || typeof window.__lib_overlay_confirms[id] == 'undefined') {
			Logger.log('error', 'Unknown confirm "' + id + '".');
			return;
		} 
		
		// if there was a lightbox before, restore it
		if (typeof window.__lib_overlay_confirms[id].hidden != 'undefined') {
			self.update(window.__lib_overlay_confirms[id].hidden);
		} else {
			self.hide();
		}

		// restore saved parameters
		var parameters = window.__lib_overlay_confirms[id].parameters;
		
		// remove credentials from registry
		delete window.__lib_overlay_confirms[id];
				
		// execute appropriate callback with appropriate parameters
		if (ok && typeof parameters.onOk == 'function') {
			if (typeof parameters.okParameters != 'undefined') {
				parameters.onOk(parameters.okParameters);
			} else {
				parameters.onOk();
			}
		}
		else if (!ok && typeof parameters.onCancel == 'function') {
			if (typeof parameters.cancelParameters != 'undefined') {
				parameters.onCancel(parameters.cancelParameters);
			} else {
				parameters.onCancel();
			}
		}
	},
	
	update: function(content, url) {
		var self = lib.Overlay;
		var scripts;
		
		if(self.indicator) {
			self.indicator.addClassName('hidden');
			self.container.update(content);
			self.initialize();
			self.element.fire('yc:div_updated', {content: content});
			self.setLightboxLocation(url);
		}
	},
	
	hide: function() {
		
		var self = lib.Overlay;
		
		if(self.visible) {
			self.showEmbedded(true);
			if (!self.element.hasClassName('hidden')) {
				self.element.addClassName('hidden');
			}
			self.visible = false;
		}
	},
	
	setLightboxLocation: function(url) {
		
		var self = lib.Overlay;
		var inputLightboxLocation = $('lightbox-location');
		
		if (!inputLightboxLocation) {
			var input = new Element('input', {id: 'lightbox-location', type: 'hidden', value: url});
			self.container.appendChild(input);
		} else {
			inputLightboxLocation.value = url;
		}
	},
	
	getLightboxLocation: function() {
		var self = lib.Overlay;
		var inputLightboxLocation = $('lightbox-location');
		return inputLightboxLocation ? inputLightboxLocation.value : null;
	},
	
	showEmbedded: function(show) {
		
		var self = lib.Overlay;
		
		if (show) {
			lib.Helper.showSelectBoxes();
			if (self.flashVideoPlayer) {
				self.flashVideoPlayer.setStyle({visibility: 'visible'})
				if(Prototype.Browser.IE) {
					setTimeout(function() { self.flashVideoPlayer.setStyle({visibility: 'visible'}); }, 1);
				}
			}
		} else {
			lib.Helper.hideSelectBoxes();
			if (self.flashVideoPlayer) {
				self.flashVideoPlayer.setStyle({visibility: 'hidden'})
				if(Prototype.Browser.IE) {
					setTimeout(function() { self.flashVideoPlayer.setStyle({visibility: 'hidden'}); }, 1);
				}
			}
		}
		
		$$('object', 'embed').each(function(object) {
			var container = $(object).up('div.js-embed-container');
			if (!container) {
				var div = new Element('div', {'class': 'js-embed-container'});
				$(object).insert({before: div});
				div.insert($(object));
				container = div;
			}
			
			if (container) {
				if (show) {
					container.setStyle({visibility: 'visible'});
					if(Prototype.Browser.IE) {
						setTimeout(function() { container.setStyle({visibility: 'visible'}); }, 1);
						setTimeout(function() { $(object).setStyle({visibility: 'visible'}); }, 1);
					}
				} else {
					container.setStyle({visibility: 'hidden'});
					if(Prototype.Browser.IE) {
						setTimeout(function() { container.setStyle({visibility: 'hidden'}); }, 1);
						setTimeout(function() { $(object).setStyle({visibility: 'hidden'}); }, 1);
					}
				}
			}
		});
	}
};

addPackage(thisNamespace, thisPackage, true);

/* replace default alert function */
nativeAlert = window.alert;
window.alert = lib.Overlay.showAlert;

/* replace default confirm function */
nativeConfirm = window.confirm;
window.confirm = function() {
	// Real compatibility is impossible because a custom function can't block 
	// script execution like a native confirm(). So this is just for safety reasons. 
	// If confirm() is called with one argument only, it's assumed the callee 
	// expects the native confirm() and acts upon it's return value.
	if (arguments.length == 1) return nativeConfirm(arguments[0]);
	else lib.Overlay.showConfirm.apply(null, arguments);
}