(function() {

	SL.ui._overlayIndex = 65;

	SL.ui._getNewOverlayIndex = function() {
		SL.ui._overlayIndex = SL.ui._overlayIndex + 10;
		return SL.ui._overlayIndex;
	};

	SL.ui.Overlay = Class.create(SL.Component, {

		init : function() {
			this.config.setDefault('backdrop_opacity', 0.7);
			this.config.setDefault('backdrop_duration', 250);
			this.config.setDefault('delete_on_hide', false);
			this.config.setDefault('background-color', '#ffffff');
			this.config.setDefault('load_shaded', true);
			this.config.setDefault('hide_objects', true);

			this.e.setStyle({
				position : 'absolute'
			});

			if (this.config.get('background-color') != 'auto') {
				this.e.setStyle({
					backgroundColor : this.config.get('background-color')
				});
			}

			if (this.config.get('show')) {
				this.show.bind(this).defer();
			}
		},

		show : function() {

			if (this.shown) {
				return;
			}

			SL.ui._closeActiveTooltips();

			if (!this.admin) {
				if (this.e.up('.gui_admin_panel')) {
					this.admin = SL.byID('admin_panel');
				}
			}

			if (this.config.get('hide_objects')) {
				SL.effects.hideEmbededObjects();
			}

			this.exKB = SL.events.pushKeyboardObserver({
				modal : true,
				keydown : this.onKeyDown.bind(this)
			});

			if (SL.admin && (this.admin || this.config.get('admin'))) {
				if (this.id == 'admin_panel_dialog') {
					this.zIndex = 915;
				} else {
					this.zIndex = SL.admin._getNewOverlayIndex();
				}
			} else {
				this.zIndex = SL.ui._getNewOverlayIndex();
			}

			this._showBackdrop();

			this.beforeShowOverlay();

			this.centerToViewport(this.e);

			if (this.zIndex) {
				this.e.setStyle({
					zIndex : (this.zIndex + 1) + ''
				});
			}

			this.e.appear({
				duration : 0.1,
				afterFinish : this.afterShow.bind(this)
			});

			this.shown = true;
			SL.ui.disableForOverlay();
		},

		setCloseJS : function(f) {
			this.closeJS = f;
		},

		beforeShowOverlay : function() {
		},

		afterShow : function() {
		},

		afterHideOverlay : function() {
		},

		beforeHide : function() {
		},

		hide : function(state, ignoreCloseJS) {

			if (!state) {
				state = 'abort';
			}

			if (!this.shown) {
				this._hideBackdrop(state);
				return;
			}

			this.beforeHide();
			SL.events.removeKeyboardObserver(this.exKB);
			this.e.hide();
			this._hideBackdrop(state);

			if (this.onClose) {
				var f = this.onClose.get(state) || this.onClose.get('all');
				if (f) {
					try {
						f(state);
					} catch (e) {
						console.log(e);
					}
				}
			}

			if (!ignoreCloseJS && this.closeJS) {
				this.closeJS(this);
			}

			this.shown = false;
			SL.ui.enableAfterOverlay();
			this.afterHide();

			if (this.id == 'admin_panel_dialog') {
				SL.admin.resetTitle();
				SL.admin.setArea(false);
			} else if (this.id == 'admin_sidebar_left_view') {
				SL.admin.resetTitle();
			}
		},

		afterHide : function() {
		},

		getTopLeftForCenter : function(width, height) {
			var vWidth = document.viewport.getWidth();
			var vHeight = document.viewport.getHeight();

			var top = 0;
			var left = 0;

			if (width < vWidth) {
				left = (vWidth - width) / 2;
			}

			var offsets = document.viewport.getScrollOffsets();

			if (this.admin) {
				return {
					top : 25,
					left : left + offsets.left
				};
			}

			if (height < vHeight) {
				top = (vHeight - height) / 2;
			}

			return {
				top : top + offsets.top,
				left : left + offsets.left
			};
		},

		centerToViewport : function(e) {
			if (!e) {
				e = this.e;
			}
			var tl = this.getTopLeftForCenter(e.getWidth(), e.getHeight());

			this.e.setStyle({
				top : tl.top + 'px',
				left : tl.left + 'px'
			});

			this.afterCentered();
		},

		afterCentered : function() {
		},

		_getBackdrop : function() {

			var id = this.id + '_g_backdrop';

			var e = $(id);
			if (!e) {
				e = SL.utils.createBodyElement('div', {
					id : id
				});
				e.setStyle({
					position : 'absolute',
					top : '0',
					left : '0',
					width : '100%',
					height : SL.effects.getBodyHeight() + 'px',
					backgroundColor : '#000000'
				});
				e.addClassName('dialog_backdrop');
				e.hide();
				e.observe('click', this.hide.bind(this));
			}

			e.setStyle({
				zIndex : this.zIndex + ''
			});

			return e;
		},

		_showBackdrop : function(customCB) {

			this.hideBackdropCB = customCB;

			if (this.admin) {
				this.admin.showBackdrop(this.hide.bind(this));
				return;
			}

			var e = this._getBackdrop(customCB);

			e.setStyle({
				height : SL.effects.getBodyHeight() + 'px'
			});

			e.appear({
				duration : this.config.get('backdrop_duration') / 1000.0,
				from : 0.0,
				to : this.config.get('backdrop_opacity')
			});
		},

		_hideBackdrop : function(state) {

			if (this.admin) {
				if (this.config.get('hide_objects')) {
					SL.effects.showEmbededObjects();
				}
				this.admin.hideBackdrop(state);
				return;
			}

			var e = this._getBackdrop();

			e.fade({
				duration : this.config.get('backdrop_duration') / 1000.0,
				afterFinish : this._afterHideOverlay.bind(this, e)
			});

			if (this.config.get('hide_objects')) {
				SL.effects.showEmbededObjects();
			}
		},

		onKeyDown : function(state) {
			if (state.code == Event.KEY_ESC || state.key == 'q') {
				this.hide();
				return true;
			}
			return false;
		},

		_afterHideOverlay : function(backdrop) {
			/* this._getBackdrop().remove(); */
			this.afterHideOverlay();
			if (this.config.get('delete_on_hide')) {
				backdrop.remove();
				this._destroy();
			}
			if (this.hideBackdropCB) {
				this.hideBackdropCB();
			}
		},

		cleanup : function($super) {
			SL.events.removeKeyboardObserver(this.exKB);
			$super();
		},

		addOnClose : function(states) {
			this.onClose = $H(states);
		}
	});

	SL.ui.Dialog = Class.create(SL.ui.Overlay, {

		isDialog : true,

		init : function($super) {

			this.config.setDefault('backdrop_opacity', 0.6);
			this.config.setDefault('static_height', false);
			this.config.setDefault('min_height', -1);

			$super();

			this.config.setDefault('dialog_class', 'gui_dialog');
			this.config.setDefault('add_class', 'gui_overlay');

			this.css = this.config.get('dialog_class');

			this.e.addClassName(this.css);
			this.e.addClassName(this.config.get('add_class'));

			if (this.config.get('content_only')) {
				this.e.addClassName('content_only');
			}
		},

		onDragStart : function() {
			this.dragged = true;
		},

		onChildComponentChanged : function(component, wasNoReload) {
			this._updateOverlay.bind(this, false, wasNoReload).defer();
		},

		updateScrollPosition : function() {
			if (!this.admin) {
				return;
			}

			// if dialog is not in the visible area scroll up

			var top = this.e.cumulativeOffset().top;
			var scrollOffsets = document.viewport.getScrollOffsets();
			if (top > scrollOffsets.top) {
				return;
			}

			var vpHeight = document.viewport.getHeight();
			var bottom = top + this.e.getHeight();

			if (bottom < scrollOffsets.top + vpHeight) {
				var newTop = bottom - vpHeight;
				if (newTop < 0) {
					newTop = 0;
				}
				window.scrollTo(scrollOffsets.left, newTop);
			}
		},

		onSuccess : function() {
			if (this.draggable) {
				this.draggable.destroy();
			}
			if (!this.admin && this.e.select('.' + this.css + '_head').size() > 0) {
				this.draggable = new SL.dnd.Draggable(this.e, {
					grip_class : this.css + '_head',
					cb : {
						dragStart : this.onDragStart.bind(this),
						moved : this.afterCentered.bind(this)
					}
				});
			}

			if (this.nextMaxWidth) {
				this.maxWidth = this.nextMaxWidth;
				this.nextMaxWidth = undefined;
			}

			this._updateOverlay(true);
		},

		reset : function() {

			this._cleanup(true);

			this.e.update('');
			this.e.setStyle({
				width : '100px',
				height : '100px',
				minHeight : 0,
				maxHeight : 'none'
			});
		},

		showAndLoad : function(url, nextMaxWidth) {

			this.nextMaxWidth = nextMaxWidth > 0 ? nextMaxWidth : undefined;

			if (this.shown) {
				var e = this.e.down('.' + this.css + "_content_outer");
				this.load(url, e ? e.identify() : this.id);
				return;
			}

			this.reset();

			this.show();
			this.load(url);

			if (this.admin) {
				window.scrollTo(0, 0);
			}

			this.centerToViewport();

			setTimeout(function(version) {
				if (this.version == version && this.e.getStyle('visibility') == 'hidden') {
					this.e.setStyle({
						visibility : 'visible'
					});
				}
			}.bind(this, this.version), 250);

			this.e.setStyle({
				visibility : 'hidden'
			});
		},

		afterHide : function() {
			this.reset();
		},

		show : function($super) {
			this.maxWidth = undefined;
			$super();
		},

		setSize : function(size, staticHeight, minHeight) {
			this.config.set('size', size);
			this.config.set('static_height', staticHeight);
			if (minHeight) {
				this.config.set('min_height', minHeight);
			}
			this._updateOverlay();
		},

		setMaxWidth : function(width) {
			this.maxWidth = width;
			this._updateOverlay();
		},

		_updateOverlay : function(withPreloading, withoutCenter) {

			if (this.admin) {

				var e = this.e.down('.' + this.css + "_content_outer");
				var width = this.admin.backdrop.getWidth() - 100;

				if (e && this.maxWidth) {
					if (this.maxWidth < width) {
						width = this.maxWidth;
					}

					this.e.setStyle({
						width : 'auto',
						height : 'auto',
						minHeight : 0
					});

					e.setStyle({
						width : width + 'px',
						height : 'auto',
						maxHeight : (document.viewport.getHeight() - this.admin.backdrop.cumulativeOffset().top - 100) + 'px'
					});
				} else {

					if (e) {
						e.setStyle({
							width : 'auto',
							maxHeight : 'none'
						});
					}

					this.e.setStyle({
						width : width + 'px',
						height : 'auto',
						minHeight : (document.viewport.getHeight() - this.admin.backdrop.cumulativeOffset().top - 100) + 'px',
						maxHeight : 'none'
					});
				}

				if (!withoutCenter) {
					this.centerToViewport();
				}

				if (withPreloading) {
					new SL.effects.Preloader(this.e, this._updateOverlay.bind(this)).run();
				} else {
					this.updateScrollPosition();
				}

				return;
			}

			var e = this.e.down('.' + this.css + "_content_outer");
			if (!e) {
				var size = this.config.get('size');
				if (size) {
					this.e.setStyle({
						width : size.width > 0 ? (size.width + 'px') : 'auto',
						height : size.height > 0 ? (size.height + 'px') : 'auto'
					});
				}

				if (!withoutCenter) {
					this.centerToViewport();
				}

				if (withPreloading) {
					new SL.effects.Preloader(this.e, this._updateOverlay.bind(this)).run();
				}

				return;
			}

			this.e.setStyle({
				width : 'auto',
				height : 'auto'
			});

			var inner = e.down();

			var width = 'auto';
			var height = 'auto';

			var minHeight = true;

			size = this.config.get('size');
			if (!size) {
				if (inner.getWidth() > document.viewport.getWidth() - 60) {
					width = document.viewport.getWidth() - 60 + 'px';
				}
				if (inner.getHeight() > document.viewport.getHeight() - 60) {
					height = document.viewport.getHeight() - 60 + 'px';
				}
			} else {
				minHeight = !(size.height > 0);
				width = (size.width > 0 ? size.width : inner.getWidth() + 2) + 'px';

				if (this.config.get('static_height')) {
					height = (size.height > 0 ? size.height : inner.getHeight() + 2) + 'px';
				} else if (size.height > 0) {
					height = inner.getHeight() > size.height ? size.height : inner.getHeight();
					if (height > document.viewport.getHeight() - 60) {
						height = document.viewport.getHeight() - 60 + 'px';
					} else {
						height = height + 'px';
					}

				} else {
					if (inner.getHeight() > document.viewport.getHeight() - 60) {
						height = document.viewport.getHeight() - 60 + 'px';
					} else {
						height = 'auto';
					}
				}
			}

			if (minHeight) {
				e.setStyle({
					width : width,
					height : 'auto',
					minHeight : height
				});
			} else {
				e.setStyle({
					width : width,
					height : height,
					minHeight : '0'
				});
			}

			if (this.config.get('min_height') > e.getHeight()) {
				e.setStyle({
					height : this.config.get('min_height') + 'px'
				});
			}

			if (!withoutCenter) {
				this.centerToViewport();
			}

			if (withPreloading) {
				new SL.effects.Preloader(this.e, this._updateOverlay.bind(this)).run();
			}
		},

		cleanup : function($super) {
			if (this.draggable) {
				this.draggable.destroy();
			}
		}
	});

	SL.ui.Lightbox = Class.create(SL.ui.Overlay, {
		init : function($super) {
			$super();

			this.config.setDefault('resize_duration', 500);
			this.config.setDefault('counter_template', new Template('#{index} of #{total}'));
			this.config.setDefault('content_dimension', null);
			this.config.setDefault('mode', 'auto');
			this.config.setDefault('show_bottom', true);
			this.config.setDefault('bottom_duration', 100);
			this.config.setDefault('hide_on_click', 'auto');
			this.config.setDefault('counter_top', false);
			this.config.setDefault('switch_duration', 1000);

			this.e.addClassName('lightbox');
			this.currentImage = 0;
			this.mode = this.config.get('mode');
			this.diaTimeout = this.config.get('dia_timeout');

			this.contentDimension = this.config.get('content_dimension');

			if (this.mode == 'auto') {
				var gallery = $(this.config.get('gallery_id'));
				this.images = $A();

				gallery.select('a').each(function(e) {
					this.images.push({
						url : e.readAttribute('href'),
						text : e.readAttribute('title')
					});
					e.observe('click', function(index, event) {
						event.stop();
						this.showImage(index);
					}.bind(this, this.images.length - 1));
				}.bind(this));
			} else if (this.mode == 'json') {
				this.images = $A(this.config.get('data'));
			} else if (this.mode == 'html') {
				var gallery = $(this.config.get('gallery_id'));
				var dimension = this.config.get('content_dimension');
				this._switchImage(this.currentImage + 1);
				this.images = $A();

				gallery.childElements().each(function(e) {
					this.images.push({
						e : e,
						text : e.readAttribute('title')
					});
					SL.effects.reparentToOffscreen(e);

					if (dimension) {
						e.setStyle({
							maxWidth : dimension.width + 'px'
						});
					}

				}.bind(this));

			} else {
				console.log("Unknown mode:", this.mode);
			}

			if (this.config.get('autostart')) {
				this.showImage.bind(this, 0).defer();
			}
		},

		beforeShowOverlay : function() {
			if (this.diaTimeout) {
				this.dia = true;
			}
			this._initDefaultLayout();
		},

		afterShow : function() {
			this._updateForImage();
		},

		showImage : function(index) {
			this.currentImage = index;
			this.show();
		},

		showImageWithID : function(id) {
			for ( var i = 0; i < this.images.length; i++) {
				var image = this.images[i];
				if (image.id == id) {
					this.currentImage = i;
					this.show();
					return;
				}
			}

			console.log("Lightbox: No image with id ", id);
		},

		next : function(event) {

			if (event) {
				event.stop();
			}

			if (this.dia) {
				this.dia = false;
			}
			if (this.currentTimeout) {
				clearTimeout(this.currentTimeout);
			}
			this._switchImage(this.currentImage + 1);
		},

		prev : function(event) {

			if (event) {
				event.stop();
			}

			if (this.dia) {
				this.dia = false;
			}
			if (this.currentTimeout) {
				clearTimeout(this.currentTimeout);
			}
			this._switchImage(this.currentImage - 1);
		},

		_initDefaultLayout : function() {

			if (this.e.childElements().length > 0) {
				return;
			}

			var content;

			if (this.mode == 'html') {
				content = "";
			} else {
				if (!this.config.get('content_dimension') || !this.diaTimeout) {
					content = '<img src="" />';
				} else {
					content = "";
					for ( var i = 0; i < this.images.length; i++) {
						content += '<img style="position:absolute;top:0;left:0;display:none;" src="" />';
					}
				}
			}

			var bottom;

			if (this.config.get('show_bottom')) {
				var details = '<div class="lightbox_details">';

				if (this.config.get('counter_top')) {
					details += '<div class="lightbox_counter"></div><div class="lightbox_text"></div>';
				} else {
					details += '<div class="lightbox_text"></div><div class="lightbox_counter"></div>';
				}
				if (this.config.get('add_content')) {
					details = details + '<div class="lightbox_add_content">' + this.config.get('add_content') + '</div>';
				}
				if (this.config.get('print_img')) {
					details = details + '<div class="lightbox_print"><img src="' + this.config.get('print_img') + '" /></div>';
				}

				details = details + '</div>';

				bottom = '<div class="lightbox_bottom" style="display:none">' + details;
				if (!this.config.get('top_close')) {
					bottom += '<div class="lightbox_close"></div>';
				}
				bottom += '</div>';
			} else {
				bottom = "";
			}

			var hoverNav;
			if (this.images.length > 1 && !this.config.get('hide_nav')) {
				hoverNav = '<div class="lightbox_hnav"><a href="#" class="lightbox_hnav_next"></a><a href="#" class="lightbox_hnav_prev"></a></div>';
				this.hasHoverNav = true;
			} else {
				hoverNav = "";
			}

			var html = '<div class="lightbox_content">' + hoverNav + '<div id="' + this.id + '_content_inner" class="lightbox_content_inner">' + content + '</div></div>' + bottom;

			if (this.config.get('top_close')) {
				html = '<div class="lightbox_close_top"></div>' + html;
			}

			this.e.insert({
				top : html
			});

			this.hoverNext = this.e.down('.lightbox_hnav_next');
			this.hoverPrev = this.e.down('.lightbox_hnav_prev');
			this.content = this.e.down('.lightbox_content');
			this.contentInner = this.e.down('.lightbox_content_inner');

			if (this.config.get('top_close')) {
				this.close = this.e.down('.lightbox_close_top');
			} else {
				this.close = this.e.down('.lightbox_close');
			}

			this.text = this.e.down('.lightbox_text');
			this.counter = this.e.down('.lightbox_counter');
			this.bottom = this.e.down('.lightbox_bottom');
			this.addContent = this.e.down('.lightbox_add_content');

			if (this.hasHoverNav) {
				this.hoverNext.observe('click', this.next.bind(this));
				this.hoverPrev.observe('click', this.prev.bind(this));

				SL.effects.registerHover(this.hoverNext);
				SL.effects.registerHover(this.hoverPrev);
			}

			if (this.close) {
				this.close.observe('click', this.hide.bind(this));
			}

			var dimension = this.config.get('content_dimension');
			if (dimension) {
				this.content.setStyle({
					width : dimension.width > 0 ? (dimension.width + 'px') : 'auto',
					height : dimension.height > 0 ? (dimension.height + 'px') : 'auto',
					overflow : 'hidden',
					position : 'relative'
				});
				this.contentInner.setStyle({
					position : 'relative'
				});
				if (this.bottom) {
					this.bottom.show();
					this.bottom.setStyle({
						width : dimension.width + 'px'
					});
				}
			} else {
				this.content.setStyle({
					width : '200px',
					height : '200px',
					overflow : 'hidden'
				});
			}

			this.contentInner.setStyle({
				overflow : 'hidden',
				width : '100%'
			});

			var hic = this.config.get('hide_nav') || this.config.get('hide_on_click');

			if (hic == 'auto' && this.images.length <= 1) {
				this.e.observe('click', this.hide.bind(this));
			} else if (hic == true) {
				this.e.observe('click', this.hide.bind(this));
			}

			var printDiv = this.e.down('.lightbox_print');
			if (printDiv) {
				printDiv.observe('click', slPrintElement.curry(this.id + "_content_inner"));
			}
		},

		_updateForImage : function() {

			this.inAnimation = true;

			var image = this.images[this.currentImage];

			if (!this.diaTimeout || !this.config.get('content_dimension')) {
				this.content.addClassName('loading');
				this.contentInner.hide();
				this.e.setOpacity(0.8);
			}

			if (this.mode == 'html') {
				new SL.effects.Preloader(image.e, this._updateForHTML.bind(this));
				return;
			}

			var e;
			if (!this.config.get('content_dimension') || !this.diaTimeout) {
				e = this.contentInner.down('img');
			} else {
				e = this.contentInner.children[this.currentImage];
				e.hide();
			}
			var loader = new Image();

			loader.onload = function() {
				e.writeAttribute('src', image.url);
				this._resizeTo.bind(this, loader.width, loader.height, e).defer();
			}.bind(this);

			loader.src = image.url;
		},

		_updateForHTML : function() {

			var image = this.images[this.currentImage];

			var width = image.e.getWidth();
			var height = image.e.getHeight();

			this.contentInner.childElements().each(function(e) {
				SL.effects.reparentToOffscreen(e);
			});

			SL.effects.reparentAndReset(this.contentInner, image.e);

			var dimension = this.config.get('content_dimension');
			if (dimension) {
				if (width > dimension.width) {
					width = dimension.width;
					image.e.setStyle({
						width : width + 'px'
					});
					if (dimension.height > 0) {
						height = dimension.height;
					}
				}
			}

			this._resizeTo(width, height);
		},

		_resizeTo : function(newWidth, newHeight, imageE) {

			var e = this.content;

			var dimension = this.config.get('content_dimension');
			if (dimension != null) {
				var top = 0;
				var left = 0;

				if (dimension.width > 0 && newWidth != dimension.width) {
					left = (dimension.width - newWidth) / 2;
				}

				if (dimension.height > 0 && newHeight != dimension.height) {
					top = (dimension.height - newHeight) / 2;
				}

				if (!imageE || !this.diaTimeout) {
					this.contentInner.setStyle({
						top : top + 'px',
						left : left + 'px',
						width : newWidth + 'px',
						height : newHeight + 'px'
					});
					this._afterUpdateFinished(dimension.width, dimension.height);
				} else {
					this.contentInner.setStyle({
						width : '100%',
						height : dimension.height > 0 ? (dimension.height + 'px') : 'auto'
					});
					if (!this.currentIE) {
						if (imageE) {
							imageE.show();
						}
						this.currentIE = imageE;
						this._afterUpdateFinished(dimension.width, dimension.height);
					} else {
						console.log("appear:" + imageE.src);
						imageE.appear({
							duration : this.config.get('switch_duration') / 1000.0,
							from : 0,
							to : 1.0,
							afterFinish : this._afterUpdateFinished.bind(this, newWidth, newHeight)
						});
						this.currentIE.fade({
							duration : this.config.get('switch_duration') / 1000.0,
							from : 1.0,
							to : 0
						});
						this.currentIE = imageE;
					}
					this.currentIE.setStyle({
						top : top + 'px',
						left : left + 'px'
					});
				}
				this.centerToViewport.bind(this, this.e).defer();
				return;
			}

			var currentWidth = e.getWidth();
			var currentHeight = e.getHeight();

			var left = parseFloat(this.e.getStyle('left') || '0');
			var tl = this.getTopLeftForCenter(newWidth, newHeight);

			var duration = this.config.get('resize_duration') / 2000.0;

			if (duration <= 0) {

				e.setStyle({
					width : newWidth + 'px',
					height : newHeight + 'px'
				});

				this.e.setStyle({
					top : tl.top + 'px',
					left : tl.left + 'px'
				});

				this._afterUpdateFinished(newWidth, newHeight);
				return;
			}

			var q = new SL.effects.Queue({
				afterFinish : this._afterUpdateFinished.bind(this, newWidth, newHeight)
			});

			hScale = newHeight * 100.0 / currentHeight;
			wScale = newWidth * 100.0 / currentWidth;

			if (currentHeight != newHeight) {

				q.add('first', new Effect.Scale(e, hScale, {
					sync : true,
					scaleX : false,
					scaleContent : false,
					duration : duration
				}));

				q.add('first', new Effect.Move(this.e, {
					sync : true,
					y : tl.top,
					x : left,
					duration : duration,
					mode : 'absolute'
				}));
			}

			if (currentWidth != newWidth) {

				q.add('last', new Effect.Scale(e, wScale, {
					sync : true,
					scaleY : false,
					scaleContent : false,
					duration : duration
				}));

				q.add('last', new Effect.Move(this.e, {
					sync : true,
					y : tl.top,
					x : tl.left,
					duration : duration,
					mode : 'absolute'
				}));

			}

			if (!this.contentDimension && this.bottom) {
				SL.effects.resetCurrent(this.bottom);
				this.bottom.hide();
			}

			if (q.isEmpty()) {
				this._afterUpdateFinished(newWidth, newHeight);
				return;
			}

			q.start();
		},

		_switchImage : function(index) {
			if (this.inAnimation) {
				return;
			}
			if (index < 0) {
				index = this.images.length - 1;
			} else if (index >= this.images.length) {
				index = 0;
			}
			this.currentImage = index;
			this._updateForImage();
		},

		_afterUpdateFinished : function(width, height) {

			if (this.dia) {
				if (this.currentTimeout) {
					clearTimeout(this.currentTimeout);
				}
				this.currentTimeout = setTimeout(function() {
					this._switchImage(this.currentImage + 1);
				}.bind(this), this.diaTimeout);
			}

			this.images[this.currentImage].loaded = true;
			var next = (this.currentImage >= this.images.length - 1) ? 0 : this.currentImage + 1;
			if (!this.images[next].loaded) {
				if (this.mode == 'html') {
					new SL.effects.Preloader(this.images[next].e);
				} else {
					new Image().src = this.images[next].url;
				}
			}

			if (this.hasHoverNav) {
				if (this.currentImage >= this.images.length - 1) {
					this.hoverNext.hide();
				} else {
					this.hoverNext.show();
					if (this.contentDimension) {
						this.hoverNext.setStyle({
							height : this.contentDimension.height + 'px',
							width : (width / 2) - 1 + 'px'
						});
					} else {
						this.hoverNext.setStyle({
							height : height > 0 ? (height + 'px') : 'auto',
							width : (width / 2) - 1 + 'px'
						});
					}
				}

				if (this.currentImage <= 0) {
					this.hoverPrev.hide();
				} else {
					this.hoverPrev.show();
					if (this.contentDimension) {
						this.hoverPrev.setStyle({
							height : this.contentDimension.height + 'px',
							width : (width / 2) - 1 + 'px'
						});
					} else {
						this.hoverPrev.setStyle({
							height : height > 0 ? (height + 'px') : 'auto',
							width : (width / 2) - 1 + 'px'
						});
					}
				}
			}

			this.content.removeClassName('loading');
			this.contentInner.show();
			this.e.setOpacity(1.0);

			if (this.bottom) {
				var image = this.images[this.currentImage];
				if (image.text) {
					this.text.show();
					this.text.update(image.text);
				} else {
					this.text.hide();
				}

				if (this.images.length > 1) {
					this.counter.update(this.config.get('counter_template').evaluate({
						total : this.images.length,
						index : this.currentImage + 1
					}));
				}
				if (!this.contentDimension) {
					this.bottom.setStyle({
						width : width + 'px'
					});
					SL.effects.registerCurrent(new Effect.BlindDown(this.bottom, {
						duration : this.config.get('bottom_duration') / 1000.0
					}));
				}
			}

			setTimeout(function() {
				this.inAnimation = false;
			}.bind(this), 50);
		},

		onKeyDown : function($super, state) {

			if ($super(state)) {
				return true;
			}

			if (this.inAnimation || this.images.length < 2) {
				return;
			}

			if (state.code == Event.KEY_LEFT) {
				this.prev();
			} else if (state.code == Event.KEY_RIGHT) {
				this.next();
			}
		}

	});

	SL.ui.showSimpleLightbox = function(id, data, size, printImg, diaTimeout, switchDuration, counterTemplate, hideOnClick, hideNav) {
		new SL.ui.Lightbox(id, {
			counter_template : counterTemplate,
			mode : 'json',
			hide_on_click : hideOnClick,
			delete_on_hide : true,
			content_dimension : size,
			print_img : printImg,
			dia_timeout : diaTimeout,
			switch_duration : switchDuration,
			hide_nav : hideNav,
			data : data
		}).showImage(0);
	};

	SL.ui.getDialog = function(id) {
		var c = SL.byID(id);
		while (c) {
			if (c.isDialog) {
				return c;
			}
			c = c.getParentComponent();
		}
	};

	SL.ui.disableForOverlay = function() {
		$$('div.you_tube>iframe').each(function(e) {
			if (e.getStyle('visibility') != 'hidden') {
				e.addClassName('__sl__hidden');
				e.setStyle({
					visibility : 'hidden'
				});
			}
		});
	};

	SL.ui.enableAfterOverlay = function() {
		$$('.__sl__hidden').each(function(e) {
			e.removeClassName('__sl__hidden');
			e.setStyle({
				visibility : 'visible'
			});
		});
	};

})();

