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

	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_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);
	
		if(isImage)
		{		
			gallery.command('load', function(r){
					obj.className = '';
					obj.innerHTML = r;
					
					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();					
				}
			, 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+'&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)
	{
		var img = document.getElementById(ids.image);
		var text = document.getElementById(ids.title);

		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();			
		};
		
		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('|', 2);
				gallery.view(stripSizes(ret[0]), ret[1]);
			}
		);
	};	
	
	/* 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);			
}
