(function ($) {
	
	$.cachedAjaxLightbox = {
	
		onCompleteFunctions: [],
		extensions: {},	
		
		namespace: 'cachedAjaxLightbox',
	
		addOnComplete: function (func) {
			$.cachedAjaxLightbox.onCompleteFunctions.push(func);
		},
		
		addExtension: function (key, opts, func) {
			var regexp	= opts && opts.regexp ? opts.regexp : opts;
				options	= $.extend({}, { regexp: regexp }, opts);
		
			$.cachedAjaxLightbox.extensions[key] = $.extend({}, options, {func: func});
		},
		
		defaults : {
			width			: 600,
			height			: 400,
			videoWidth		: 640,
			videoHeight		: 385,
			removeElement	: 'meta, base, title, #header, #footer',
			fancybox: {
				'overlayColor'	: '#FFF',
				'overlayOpacity'	: 0.8,
				'transitionIn'	: 'fade',
				'transitionOut'	: 'fade'
			}
		},
		
		regExpOnclickWidth	: /width=([0-9]+)/,
		regExpOnclickHeight	: /height=([0-9]+)/,
		
		/**
		 * tmp-container for all cached lightboxes
		 */
		createTempContainer: function () {
			// tmp-container
			if ($('#cachedLightbox-tmp').length) { 
				return;
			}
			
			$('<div />', { 'id'	: 'cachedLightbox-tmp' })
				.hide()
				.appendTo('body');
		},
		
		/**
		 * tmp-Container one cached lightbox
		 */
		createLightboxTemp: function (settings) {
			var $tmp = null;

			name = settings.i.toString();
			
			this.createTempContainer();
			
			if ($('#lightbox-content-' + name.replace('.', '-') + '-container').length) { 
				return;
			}

			$tmp = $('<div />', {
					'id' : 'lightbox-content-' + name.replace('.', '-') + '-container'
				})
				.prepend('<div id="lightbox-content-' + name.replace('.', '-') + '"></div>');
			
			$tmp
				.fancybox($.extend({}, settings.fancybox, {
					'content'			: $('#lightbox-content-' + name.replace('.', '-')).html(),
					'autoDimensions'	: false,
					'height'			: settings.height,
					'width'				: settings.width,
					'onComplete'		: function () {
						var $content = $('#fancybox-content');
						
						// fix height => browser window is smaller than fancybox 
						if (settings.height > $content.height()) {
							$content.height(settings.height);
						}
						
						// fix height => browser window is smaller than fancybox 
						if (settings.width > $content.width()) {
							$content.width(settings.width);
						}
						
						if ($.cachedAjaxLightbox.onCompleteFunctions.length) {
							for (var i = 0; i < $.cachedAjaxLightbox.onCompleteFunctions.length; i++) {
								$.cachedAjaxLightbox.onCompleteFunctions[i]($content);
							}
						}
					}})
				)
				.appendTo($('#cachedLightbox-tmp'));
				
			return $tmp;
		},
		
		/**
		 * set lightbox dimensions. check the onclick-attribute if not set.
		 */
		setDimensions: function (settings, opts) {
			
			opts = opts || settings;
			
			// set video defaults
			if (opts && opts.video) {
				settings.width = settings.videoWidth;
				settings.height = settings.videoHeight;
			}
			
			// set option width
			if (opts && opts.width) {
				settings.width = opts.width;
			}
			
			// set width from onlick-attribute
			if (opts && opts.onclick) {
				settings.width = $.cachedAjaxLightbox.regExpOnclickWidth.test(opts.onclick) ? parseInt(opts.onclick.match($.cachedAjaxLightbox.regExpOnclickWidth)[1], 10) : settings.width;
			}
			
			// set option height
			if (opts && opts.height) {
				this.boxHeight = opts.height;
			}
			
			// set height from onlick-attribute
			if (opts && opts.onclick) {
				settings.height = $.cachedAjaxLightbox.regExpOnclickHeight.test(opts.onclick) ? parseInt(opts.onclick.match($.cachedAjaxLightbox.regExpOnclickHeight)[1], 10) : settings.height;
			}
			
			// remove onlick
			if (opts && opts.onclick) {
				delete opts.onclick;
			}
			
			return settings;
		},
		
		getNamespacedEvent: function (name) {
			name = name || '';
			
			return name + '.' + $.cachedAjaxLightbox.namespace;
		},
		
		/**
		 * init cached lightbox via jQuery(selector)
		 */
		initElement: function (i, $this, settings) {
			
			var	$tmp = $.cachedAjaxLightbox.createLightboxTemp(settings).data('chachedLightbox', settings);
			
			// load content and trigger box
			$this
				.removeAttr('onclick')
				.click(function (event) {
					event.preventDefault();
					
					var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
					
					// load
					if (!$tmp.data($.cachedAjaxLightbox.getNamespacedEvent('loaded'))) {
						$.fancybox.showActivity();
						
						$.get($this.attr('href'), function(response) {
							var lightboxHref = '#lightbox-content-' + i.toString();
							
							$this.attr('href', lightboxHref);
							$tmp.data($.cachedAjaxLightbox.getNamespacedEvent('loaded'), true);
							
							var $response = $(response),
								scripts = response
									// remove comments
									.replace('/<!--(.*)-->/Uis', '')
									// find scripts
									.match(rscript);
							
							if (scripts === null) { scripts = ''; } // empty string instead of »null«
							
							if (scripts.length) {
								
								var $currentScripts = $('script'),
									baseHref = $('base').attr('href') || '';
									currentScriptSources = [],
									$newScripts = $();
								
								// collect script sources
								$currentScripts.each(function (i, script) {
									var src			= script.src,
										paramPos	= src.indexOf('?');
										
									if (src && src != '') {
										if (paramPos > -1) {
											src = src.substr(0, paramPos);
										}
										
										src = src.replace(baseHref, '');
										
										currentScriptSources.push(src);
									}
								});
								
								$.each(scripts, function (i, script) {
									var $script		= $(script),
										src			= $script.attr('src'),
										paramPos;
										
									if (src && src != '') {
										
										paramPos = src.indexOf('?');
										
										if (paramPos > -1) {
											src = src.substr(0, paramPos);
										}
									
										if (src && $.inArray(src, currentScriptSources) == -1) {
											if (src != 'typo3conf/ext/jq_fancybox/fancybox/js/jquery.fancybox-1.3.1.pack.js') {
												
												if (src == 'typo3conf/ext/smateasernavi/js/carousel.js') {
													$script.attr('src', 'http://meisterwerk.sma.de/html-dummies/jQuery.labs/lightbox-carousel/js/carousel.js');
												}
												
												/*if ($script.attr('src').substr(0, 4) != 'http') {
													// absolute paths
													$script.attr('src', '/' + $script.attr('src'));
												}*/
												
												// remove old script block. firefox can't add it twice
												response.replace(script, '');
												$newScripts = $newScripts.add($script);
											}	
										}
									}
								});
								
								if ($newScripts.length) {
									$('body').append($newScripts);
								}
							}
							$("#lightbox-content-" + i.toString(), $tmp)
								.html($response)
								.find(settings.removeElement)
									.remove();
							
							// set fancybox content manually. Prevents an error if the content hasn't been loaded
							var fancybox = $tmp.data('fancybox');
							fancybox.width = settings.width;
							fancybox.height = settings.height;
							fancybox.type	= 'inline';
							fancybox.href	= lightboxHref;
							fancybox.content = $(this).html();
							
							$tmp.trigger('click');
						});
					}
					else {
						$tmp.trigger('click');
					}
					
					return false;
				});
		}
		
		/**
		 * init youtube video lightbox
		 */
	};
	
	/**
	 * jQuery.fn
	 */
	$.fn.cachedAjaxLightbox = function (options) {	
		return this.each(function (i) {
			
			var settings = $.extend({}, $.cachedAjaxLightbox.defaults, options),
				handledByExtension = false,
				link = this,
				$this = $(this);
				
			
			settings.onclick = $this.attr('onclick') ? $this.attr('onclick').toString() : false;
			settings.i = i;
			
			// check extensions
			if (!$.isEmptyObject($.cachedAjaxLightbox.extensions)) {
				
				$.each($.cachedAjaxLightbox.extensions, function (key, ext) {
					var matched = false;
					
					if (typeof ext.regexp == 'string') {
						matched = link.href.match(ext.regexp);
						
					} else if ($.isFunction(ext.regexp)) {
						matched = ext.regexp.call(link);
					}
					
					if (matched) {
						// set flag
						handledByExtension = true;
						
						// update options
						settings = $.cachedAjaxLightbox.setDimensions(settings, ext.options);
						
						// handle
						ext.func.call($.cachedAjaxLightbox, i, $this, settings);
						return;
					}
				});
				
			}
			
			if (!handledByExtension) {
				// update options
				settings = $.cachedAjaxLightbox.setDimensions(settings);
				$.cachedAjaxLightbox.initElement(i, $this, settings);
			}
		});
	};
	
	$.cachedAjaxLightbox.addOnComplete(function () {
		if (Cufon) {
			Cufon.refresh();
		}
	});
	
	$.cachedAjaxLightbox.addExtension('youtube', {
		regexp	: function () {
			return this.href.match('youtube');
		},
		options	: {
			video : true
		}
	}, function (i, $this, settings) {
							
		$this.click(function (event) {
			event.preventDefault();
			
			// hide infos by default
			var href = this.href + '&showinfo=0';

			/*
			 * Youtube parameter options:
			 *
			 * fullscreen button
			 *		href += '&fs=1';
			 *
			 * autoplay
			 *		href += '&autoplay=1';
			 *
			 * hide infos (title, rating)
			 *		href += '&showinfo=0';
			 *
			 * Quality:
			 *	- 320x240:
			 *		href += '&fmt=6';
			 *	- 480x360:
			 *		href += '&fmt=18';
			 *	- 720 HD:
			 *		href += '&fmt=22';
			 *		href += '&hd=1';
			 */	
			$.fancybox($.extend({}, settings.fancybox, {
				'padding'		: 0,
				'autoScale'		: false,
				'height'		: settings.height,
				'width'			: settings.width,
				'href'			: href.replace(new RegExp('watch\\?v=', 'i'), 'v/'),
				'type'			: 'swf',
				'swf'			: {
					'wmode'				: 'transparent',
					'allowfullscreen'	: 'true'
				}
			}));
			
			return false;

		});
	});
	
	// DOM ready -> looking for a.internal-link-lightbox and init lightbox
	$(function () {
		$('a.internal-link-lightbox').cachedAjaxLightbox();
	});
	
}(jQuery));

/**
 * Wrapper via plain-javascript function
 * Useful for calls from Flash or while debugging.
 * 
 * @param String url
 * @param int width (optional)
 * @param int height (optional)
 * @example: <a href="javascript:openAjaxLightbox(String url, int width, int height)">Link</a>
 */
function openAjaxLightbox (url, width, height) {

	if (width && height) {
		var autoDimensions = false;
	}
	else {
		var autoDimensions = true;
	};
	
	jQuery.fancybox({
		'type'				: 'ajax',
		'href'				: url,
		'autoDimensions'	: autoDimensions,
		'width'         	: width,
		'height'        	: height,
		// Begin corporate fancybox settings
		'overlayColor'		: '#FFF',
		'overlayOpacity'	: 0.8,
		'transitionIn'		: 'fade',
		'transitionOut'		: 'fade'
	});
	
	
};

