function ego_gallery(params)
{
	var ids = { // Verschiedene IDs
		gallery : 'gallery',
		image : 'gallery_image',
		title : 'gallery_title',
		short : 'gallery_short',
		current : 'gallery_current',
		max : 'gallery_max'
	};

	// Optionale Parameter
	if (typeof params.parent == 'undefined')
	{
		params.parent = 0;
	}

	var script = 'bin/lightbox/ajax.gallery.php'; // PHP Skript

	var thumb_index = 0; // Index des ersten angezeigten Thumbnails
	var container = null; // Lightbox Container Objekt

	/* Skriptinterne Texte übersetzt ausgeben */
	function label(mode)
	{
		var langs = {
			preload : {
				de: 'Lade, bitte warten...',
				en: 'Loading, please wait...',
				fr: 'Chargé, veuillez attendre...'
			},

			no_image : {
				de: '<b>Fehler</b>: dieser Link verweist auf kein Bild',
				en: '<b>Error</b>: this link does not refer to an image',
				fr: '<b>Erreur</b>: Ce renvoi ne montre pas sur d\'image'
			}
		};

		return (langs[mode][params.lang] !== undefined)? langs[mode][params.lang]:langs[mode].en;
	}

	/* Scrollposition ermitteln */
	function scrollPos()
	{
		return ((y = window.pageYOffset)? y:document.documentElement.scrollTop)+'px';
	}

	/* Holt die URL des aktuell angezeigten Bildes */
	function currentImage()
	{
		var img = document.getElementById(ids.image);
		return stripSizes(img.src);
	}

	/* Entfernt width und height Parameter aus der URL, ggf auch den Pfad
	 * @todo: prüfen ob diese Funktion noch notwendig ist */
	function stripSizes(str, basename)
	{
		var output = str;

		// Pfad entfernen
		if(basename)
		{
			var base = output.match(/[\/|\\]([^\\\/]+)$/);
			output = base? base[1]:output;
		}

		return output;
	}

	/* Setzt, überschreibt Parameter in der URL */
	function url_params(url, p)
	{
		// Art der Parameter Übermittlung bestimmen
		var mode = /^.*index\.php/.test(url)? 'index':'image';

		switch(mode)
		{
			case 'index':
				for(prop in p)
				{
					var new_param = '&'+prop+'='+p[prop];
					url = url.replace(new RegExp('&?'+prop+'=[^&]+', 'i'), '');
					url += new_param;
				}
				return url;
				break;

			case 'image':
				var split = url.match(/(.*)(\.[^.]+)$/); // Trennt den Dateinamen von seinem Dateiformat
				for(prop in p)
				{
					var new_param = '-'+prop+'-'+p[prop];
					split[1] = split[1].replace(new RegExp('-'+prop+'-[^-]+', 'i'), '');
					split[1] += new_param;
				}

				return split[1]+split[2];
				break;
		}
	}

	/* Angezeigtes Bild skalieren */
	function scaleImage(newImg)
	{
		var img = document.getElementById(ids.image);

		if(img)
		{
			var thumbImg = new Image();

			// Bild während der Skalierung ausblenden
			img.style.display = 'none';

			thumbImg.onload = function() // Skalierung erst durchführen wenn das Bild geladen ist
			{
				var origWidth = thumbImg.width;
				var origHeight = thumbImg.height;

				img.width = origWidth;
				img.height = origHeight;
				img.style.width = origWidth+'px';
				img.style.height = origHeight+'px';

				var newWidth = (params.width != '' && origWidth > params.width)? params.width:origWidth;
				var newHeight = Math.round(origHeight * (newWidth / origWidth));

				if(params.height != '' && newHeight > params.height)
				{ // Maximale Höhe überschritten, Breite neu anpassen
					newWidth = Math.round(origWidth * (params.height / origHeight));
					newHeight = params.height;
				}

				img.width = newWidth;
				img.height = newHeight;
				img.style.width = newWidth+'px';
				img.style.height = newHeight+'px';

				// Bild wieder einblenden
				img.style.display = '';
				wait(false);
			}

			thumbImg.src = img.src;

			// Bildposition in der Galerie ermitteln
			gallery.command('count', function(r){
					var ret = r.split('|');
					updateCount(ret);
				}
			);
		}
	}

	/* Ermittelt eine gültige URL */
	function get_url(obj)
	{
		var url = obj.href;

		// Zu übergebende Parameter
		var p = {
			view_image: 1,
			called_by: params.skin,
			original_site: params.site,
			original_lang: params.lang,
			original_page: params.id,
			lightbox: 1,
			thumbs: params.thumbs
		};

		return url_params(url, p);
	}

	/* Event Handler Objekt */
	var event = {
		/* Eine Funktion einem Event hinzufügen ohne es zu überschreiben */
		add : function(obj, event, func)
		{
			if(obj.addEventListener)
			{
				obj.addEventListener(event, func, false);
				return true;
			}
			else if(obj.attachEvent)
			{
				var rev = obj.attachEvent('on'+event, func);
				return rev;
			}

			return false;
		},

		/* Eine Funktion einem Event entfernen ohne es zu löschen */
		remove : function(obj, event, func)
		{
			if(obj.removeEventListener)
			{
				obj.removeEventListener(event, func, false);
				return true;
			}
			else if(obj.detachEvent)
			{
				var rev = obj.detachEvent('on'+event, func);
				return rev;
			}

			return false;
		}
	};

	/* Ladevorgang anzeigen */
	function preloader(box, obj)
	{
		box.className = 'preload';
		var loader = new Image();
		// Galerie erst laden wenn die Preloader Grafik geladen ist
		loader.onload = function(){
			loadGallery(box, get_url(obj)); // Galerie in Container laden
			loader.onload = null;
		};

		loader.src = params.path+'bin/lightbox/img/loader.gif';

		// Preloader HTML
		box.innerHTML = '<div class="preloader">'+
			label('preload')+'<br/>'+
			'<a href="javascript:gallery.close()"><img src="'+loader.src+'" border="0" alt="preloader" /></a>'+
			'</div>';
	}

	/* Galerie laden */
	function loadGallery(obj, url)
	{
		var isImage = /\.(jpg|jpeg|gif|png)$/i.test(url);
		isImage = isImage? true:/[?&](width|height)=\d+/i.test(url);
		thumb_index = 0;

		if(isImage)
		{
			gallery.command('load', function(r){
					obj.className = '';
					obj.innerHTML = r;
					obj.style.visibility = 'hidden';

					window.setTimeout(function()
					{
						var width = obj.offsetWidth;
						var thumbs = document.getElementById('gallery_thumbs');

						if(thumbs && width < thumbs.offsetWidth)
						{
							var thumbnails = thumbs.getElementsByTagName('img');
							var maxWidth = parseInt((width-250)/params.thumbs);

							for(var i=0;i<thumbnails.length;i++)
							{
								thumbnails[i].width = maxWidth;
							}
						}

						scaleImage();
						displayArrows();

						obj.style.visibility = 'visible';
					}, 100);
				}
			, url);
		}
		else
		{
			// Kein Verweis auf ein Bild, Galerie schliessen
			obj.innerHTML = '<div class="preloader">'+label('no_image')+'</div>';
			window.setTimeout(function(){
					gallery.close();
				},
				2000
			);
		}
	}

	/* Aktualisiert die Position des Hauptcontainers je nach Scrollposition */
	function updatePos()
	{
		container.style.top = scrollPos();
	}

	/* Zähler für das aktuelle Bild in der Galerie */
	function updateCount(ret)
	{
		// Bild Nummer in der aktuellen Galerie
		var current = document.getElementById(ids.current);

		if(current)
		{
			current.innerHTML = ret[0];
		}

		// Maximale Bilder in dieser Galerie
		var max = document.getElementById(ids.max);

		if(max)
		{
			max.innerHTML = ret[1];
		}
	}

	/* Vor und Zurück Pfeile anzeigen / verbergen */
	function displayArrows()
	{
		gallery.command('siblings', function(r){
				var ret = r.split('|');

				var arrows = [
					document.getElementById('gallery_image_back'),
					document.getElementById('gallery_image_next'),
					document.getElementById('gallery_image_back_text'),
					document.getElementById('gallery_image_next_text')
				];

				arrows[0].style.display = (ret[0] == 1)? '':'none';
				arrows[1].style.display = (ret[1] == 1)? '':'none';

				// Optionale zusätzliche Pfeile
				if(arrows[2])
				{
					arrows[2].style.display = (ret[0] == 1)? '':'none';
				}

				if(arrows[3])
				{
					arrows[3].style.display = (ret[1] == 1)? '':'none';
				}
			}
		);
	}

	/* Auf das Laden eines Bildes warten */
	function wait(visible)
	{
		var wait_id = 'wait_container';
		var img = document.getElementById(ids.image);

		if(visible)
		{
			var obj = document.createElement('div');
			obj.id = wait_id;

			obj.style.width = '220px';
			obj.style.height = '19px';

			var waiter = document.createElement('img');
			waiter.src = params.path+'bin/lightbox/img/loader.gif';
			waiter.border = 0;
			waiter.alt = 'wait';

			obj.appendChild(waiter);
			img.parentNode.insertBefore(obj, img);
		}
		else
		{
			var obj = document.getElementById(wait_id);

			if(obj)
			{
				obj.parentNode.removeChild(obj);
			}
		}
	}

	/* Ajax Objekt */
	var ajax = {
		_factories : [
			function(){ return new XMLHttpRequest(); },
			function(){ return new ActiveXObject('Msxml2.XMLHTTP'); },
			function(){ return new ActiveXObject('Msxml3.XMLHTTP'); },
			function(){ return new ActiveXObject('Microsoft.XMLHTTP'); }
		],

		newObject : function()
		{
			var req = false;

			for(var i=0;i<this._factories.length;i++)
			{
				try {
					req = this._factories[i]();
				} catch(e) { continue; }
				break;
			}

			return req;
		}
	};

	var req = ajax.newObject();

	/* Befehl ausführen */
	this.command = function(command, func, url)
	{
		var r = ajax.newObject();

		r.open('POST', params.path+script, true);
		r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');


		url = (typeof url == 'undefined')? currentImage():url;

		if(/\/index\.php\?/i.test(url))
		{ // Bei einer index.php URL die Parameter Trennzeichen umwandeln
			url = url.replace(/&/g, '{_AND_}');
		}

		r.send('path='+params.path+'&site='+params.site+'&id='+params.id+'&lang='+params.lang+'&parent='+params.parent+'&media='+params.media+'&width='+params.width+'&height='+params.height+'&command='+command+'&url='+url);

		r.onreadystatechange = function()
		{
			if(r.readyState == 4 && r.responseText != 0)
			{
				if(typeof func == 'function')
				{
					func(r.responseText);
				}
			}
		};
	};

	/* Öffnet die Galerie und erstellt den Container */
	this.open = function(obj)
	{
		container = document.createElement('div');
		container.setAttribute('id', ids.gallery);
		container.style.top = scrollPos();

		var background = document.createElement('div');
		background.setAttribute('id', 'g_background');

		var content = document.createElement('div');
		content.setAttribute('id', 'g_content');

		var box = document.createElement('div');
		box.setAttribute('id', 'g_box');

		content.appendChild(box);
		event.add(window, 'scroll', updatePos); // Position beim Scrollen anpassen

		container.appendChild(background);
		container.appendChild(content);

		document.body.appendChild(container, document.body.firstChild);
		preloader(box, obj); // Preloader laden
	};

	/* Schliesst die Galerie und entfernt den Container */
	this.close = function()
	{
		var gallery = document.getElementById(ids.gallery);

		if(gallery)
		{
			event.remove(window, 'scroll', updatePos); // Scroll Event entfernen
			document.body.removeChild(gallery);
		}
		else
		{ // Galerie wurde nicht in der Lightbox geöffnet, Fenster schliessen
			window.close();
		}
	};

	/* Zeigt ein Bild an */
	this.view = function(url, title, shorttext, highres_url, lowres_url)
	{
		var img = document.getElementById(ids.image);
		var text = document.getElementById(ids.title);
		var short = document.getElementById(ids.short);

		/* Anpassung für Hunkeler */;
		var highres_url_obj = document.getElementById('highres_url');
		var lowres_url_obj = document.getElementById('lowres_url');

		var newImg = new Image();

		// Ladegrafik für diese Zeitspanne einblenden
		img.style.display = 'none';
		wait(true);

		newImg.onload = function(){
			img.src = url;
			scaleImage(newImg);

			// Pfeile anzeigen, verbergen
			displayArrows();
		};

		if (typeof short != 'undefined' && short != null)
		{
			short.innerHTML = shorttext;
		}

		/**
		 *  Anpassungen für Hunkeler
		 */
		if (typeof highres_url_obj != 'undefined' && highres_url_obj != null)
		{
			highres_url_obj.href = highres_url;
		}
		if (typeof lowres_url_obj != 'undefined' && lowres_url_obj != null)
		{
			lowres_url_obj.href = lowres_url;
		}

		newImg.src = url;
		text.innerHTML = title;
	};

	/* Bild in einem neuen Fenster öffnen */
	this.popup = function(url)
	{
		// Parameter für Breite und Höhe entfernen
		url = url.replace(/(-width-\d+)/i, '').replace(/(-height-\d+)/i, '');
		url = url.replace(/(&?width=\d+)/i, '').replace(/(&?height=\d+)/i, '');

		var popup = window.open(stripSizes(url), 'gallery_popup');
		popup.focus();
	};

	/* Nächstes, bzw vorheriges Bild anzeigen */
	this.nextImage = function(dir)
	{
		this.command((dir?'next':'prev'), function(r){
				var ret = r.split('|', 5);
				gallery.view(stripSizes(ret[0]), ret[1], ret[2], ret[3], ret[4]);
			}
		);
	};

	/* Thumbnail Liste vor, bzw zurück schieben */
	this.thumblist = function(dir)
	{
		var thumbs = [
			document.getElementById('gallery_thumb_'+(thumb_index-(dir?0:1))),
			document.getElementById('gallery_thumb_'+(thumb_index+params.thumbs-(dir?0:1))),
			document.getElementById('gallery_thumb_back'),
			document.getElementById('gallery_thumb_next')
		];

		if(thumbs[0] || thumbs[1])
		{
			// Je nach Schieberichtung das erste/letzte und nächste/vorherige Thumbnail aus-/einblenden
			if(thumbs[0])
			{
				thumbs[0].style.display = dir? 'none':'';
			}

			if(thumbs[1])
			{
				thumbs[1].style.display = dir? '':'none';
			}

			// Thumbnail Index aktualisieren
			thumb_index += dir? 1:-1;

			// Thumbnail Pfeile am Anfang/Ende aus-/einblenden
			thumbs[2].style.visibility = (thumb_index > 0)? 'visible':'hidden';
			thumbs[3].style.visibility = document.getElementById('gallery_thumb_'+(thumb_index+params.thumbs))? 'visible':'hidden';
		}
	};

	/* Bild beim Laden skalieren, auch in einem Popup Fenster */
	event.add(window, 'load', scaleImage);
}

