/**
 * Lightwindow Mark-II                                         _...._
 *                                                           .'      '.
 * Inspired by the original lightwindow from Stickmanlabs   /          \
 * by Kevin P Miller                                        |          |
 *                                                           \   ~~   /
 *                                                            `\ || /`
 * @author Eric van Blokland                                   |_||_|
 * @version 1.0.6                                              {____}
 * @copyright Footsteps (http://www.footsteps.nl)          jgs {____}
 *                                                               ()
 */
 
 var lightwindow=new function lightwindow2() {

	var overlay=null;
	var oWindow=null;
	
	var me=this;
	
	var IE6=(navigator.userAgent.indexOf('MSIE 6')>-1);
	var IE=(navigator.userAgent.indexOf('MSIE')>-1);
	var dom=document.documentElement;
	
	var events={};
	var images={};
	var objects={};
	var handlers={};
	
	var heightAdjust=0;
	var widthAdjust=0;
	
	var transitionTime=.2;
	
	var loaded=false;
	var queued=null;
	
	var marginHeight=180;
	var marginWidth=180;
	
	var _viewPortHeight=null;
	var _viewPortWidth=null;
	
	var language=null;
	var translations= {
		'en' : {'close' : 'Close',
				'cancel' : 'Cancel',
				'loading' : 'Loading, one moment please...',
				'image' : 'Image',
				'imageOf' : 'of'},
		'nl' : {'close' : 'Sluiten',
				'cancel' : 'Annuleren',
				'loading' : 'Laden, een ogenblik geduld a.u.b.',
				'image' : 'Afbeelding',
				'imageOf' : 'van de '}
	};
	var mediaTypes={
		'image' : ['bmp', 'gif', 'jpg', 'png', 'tiff'],
		'media' : ['swf']
	};			
	var mediaContentObjects={
		'inline' : function inlineContent(src,arguments) {
				makeObservable(this);							
				var src=src.substr(src.indexOf('#')+1);				
				var loadEvent=null;
				var container=document.createElement('div');
				var width=0;
				var height=0;
				
				this.load=function() {			
					
					loadEvent=null;					
									
					this.triggerEvent('load');
					
				}
				/*
				this.show=function() {
					setStyle(container,{'display':'inline'});
				}
				this.hide=function() {
					setStyle(container,{'display':'none'});
				}
				*/
				this.destruct=function () {
					this.detachAll();
					if(container.parentNode) {
						container.parentNode.removeChild(container);
					}
				}
				this.appendTo=function(object) {
				
					object.appendChild(container);
				}	
				this.getHeight=function() {
					// BF20100203:	Use cached height.				
					if(!container.childNodes[0].getAttribute('lightwindowHeight'))
						container.childNodes[0].setAttribute('lightwindowHeight',container.childNodes[0].offsetHeight);
					return parseFloat(container.childNodes[0].getAttribute('lightwindowHeight'));
				}
				this.getWidth=function() {
					// BF20100203:	Use cached width.
					if(!container.childNodes[0].getAttribute('lightwindowWidth'))
						container.childNodes[0].setAttribute('lightwindowWidth',container.childNodes[0].offsetWidth);
					return parseFloat(container.childNodes[0].getAttribute('lightwindowWidth'));
				}
				this.dispatch=function() {
					this.load();												
				}
				
				container.className='lightwindowInline';
				if(arguments['width'])
					setStyle(container,{'width':arguments['width']+'px'});
				if(arguments['height'])
					setStyle(container,{'height':arguments['height']+'px'});
									
				if(!objects[src]) {
					if(!document.getElementById(src))
						return;
					objects[src]=document.getElementById(src);
					objects[src].style.position='relative';										
				}							
				container.appendChild(objects[src]);
				
			
		},
		'media' : function mediaContent(src,arguments) {
				makeObservable(this);
				var mediaContainer=null;
				var mediaObject=null;
				var mediaObject2=null;
				var src=src;
				var width=0;
				var height=0;
				var loadEvent=null;
				
				var classids ={
					'mov' : 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',
					'swf' : 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000',
					'wmv' : 'clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6'
				};
				var codebases = {
					'mov' : 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0',
					'swf' : 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0',
					'wmv' : 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715'
				};
				var mimetypes = {
					'mov' : 'video/quicktime',
					'swf'	: 'application/x-shockwave-flash',
					'wmv' : 'application/x-mplayer2'			
				};
				this.load=function() {			
					//loadEvent.detach();	
					loadEvent=null;					
									
					this.triggerEvent('load');
					
				}
				this.show=function() {
					setStyle(mediaContainer,{'display':'inline'});
				}
				this.hide=function() {
					setStyle(mediaContainer,{'display':'none'});
					if(mediaContainer.childNodes[0])
						mediaContainer.removeChild(mediaContainer.childNodes[0]);
				}
				this.destruct=function () {
					this.detachAll();
					if(mediaContainer.parentNode) {
						mediaContainer.parentNode.removeChild(mediaContainer);
					}
				}
				this.appendTo=function(object) {
					object.appendChild(mediaContainer);
				}	
				this.getHeight=function() {
					return height;
				}
				this.getWidth=function() {
					return width;
				}
				this.dispatch=function() {
					this.load();												
				}
				
				// AF20100205:	Youtube support
				var youtube = new RegExp("http:\\/\\/www.youtube.com\\/watch\\?v=([a-zA-Z0-9]+)", "i");		
				if(youtube.test(src)) {		
					var orgSrc=src;
					var result=youtube.exec(orgSrc);
					src='http://www.youtube.com/v/'+result[1];					
					var classid=classids['swf'];
					var codebase=codebases['swf'];
					var mimetype=mimetypes['swf'];
					var RegexHeight=new RegExp("height=([0-9]+)", "i");
					result=RegexHeight.exec(orgSrc);
					
					if(result && result[1])
						arguments['height']=parseFloat(result[1]);
					var RegexWidth=new RegExp("width=([0-9]+)", "i");
					result=RegexWidth.exec(orgSrc);
					if(result && result[1])
						arguments['width']=parseFloat(result[1]);
				}
				else {
					var classid=classids[getExtension(src)];
					var codebase=codebases[getExtension(src)];
					var mimetype=mimetypes[getExtension(src)];
				}
				
				// BF20100205:	Should fix width and height independantly
				// BC20100205:	We no longer scale contents depending on viewport
				if(!arguments['height']) { // || arguments['height']>dom.offsetHeight-marginHeight  ) {					
					height=getViewPortHeight()-marginHeight;
				}	
				else {
					height=arguments['height'];
				}
				// BC20100205:	We no longer scale contents depending on viewport
				if( !arguments['width']) { // || arguments['width']>dom.offsetWidth-marginWidth  ) {
					width=getViewPortWidth()-marginWidth;					
				}	
				else {
					width=arguments['width'];
				}		
				
				mediaContainer=document.createElement('div');
				mediaObject=document.createElement('object');
				mediaObject.setAttribute('classid',classid);				
				mediaObject.setAttribute('codebase',codebase);
				mediaObject.setAttribute('codetype',mimetype);
				mediaObject.setAttribute('width',width);
				mediaObject.setAttribute('height',height);				
				
										
				addParam('quality','high');
				addParam('wmode','transparent');								
				addParam('movie',src);
				addParam('allowFullScreen','true');
				addParam('allowscriptaccess','always');
				if(!IE) {
					mediaObject2=document.createElement('embed');		
					mediaObject2.setAttribute('wmode','transparent');				
					mediaObject2.setAttribute('quality','high');
					mediaObject2.setAttribute('width',width);
					mediaObject2.setAttribute('height',height);					
					mediaObject2.setAttribute('src',src);
					//mediaObject.appendChild(mediaObject2);
					mediaContainer.appendChild(mediaObject2);		
				}else {					
					mediaContainer.innerHTML=mediaObject.outerHTML;					
				}
				
				/* Bah, not giving any useful events 		
				if(mediaObject2)
					loadEvent=this.attachTo(mediaObject2,'load',this.load,this);
				else 
					loadEvent=this.attachTo(mediaObject,'load',this.load,this);
				*/
				
				setStyle(mediaContainer,{'width':width+'px','height':height+'px'});
				setStyle(mediaContainer,{'display':'none'});
				
				function addParam(name,value) {
					var param = document.createElement('param');
					param.setAttribute('name', name);
					param.setAttribute('value', value);					
					mediaObject.appendChild(param);					
				}
				function getExtension(url) {
					if (url.indexOf('?') > -1) {
						url = url.substring(0, url.indexOf('?'));
					}
					var extenstion = '';
					for (var x = (url.length-1); x > -1; x--) {
						if (url.charAt(x) == '.') {
							return extenstion;
						}
						extenstion = url.charAt(x)+extenstion;
					}
				}
				
			},
		'iframe' : function iframeContent(src,arguments) {
				makeObservable(this);
				var iframe=null;
				var src=src;
				var width=0;
				var height=0;
				var loadEvent=null;
				this.load=function() {			
					loadEvent.detach();	
					loadEvent=null;					
					this.triggerEvent('load');
					
				}
				this.show=function() {
					setStyle(iframe,{'display':'block'});
				}
				this.hide=function() {
					setStyle(iframe,{'display':'none'});
					if(loadEvent) {
						loadEvent.detach();	
						loadEvent=null;
					}				
				}
				this.destruct=function () {
					this.detachAll();
					if(iframe.parentNode) {
						iframe.parentNode.removeChild(iframe);
					}
				}
				this.appendTo=function(object) {					
					object.appendChild(iframe);
				}	
				this.getHeight=function() {
					return height;
				}
				this.getWidth=function() {
					return width;
				}
				this.dispatch=function() {
					iframe.src=src;
				}
				
				iframe=document.createElement('iframe');
				if(!arguments['height'] || !arguments['width'] || arguments['height']>getViewPortHeight()-marginHeight|| arguments['width']>getViewPortWidth()-marginWidth  ) {
					width=getViewPortWidth()-marginWidth;
					height=getViewPortHeight()-marginHeight;
				}	
				else {
					width=arguments['width'];
					height=arguments['height'];
				}					
				setStyle(iframe,{'width':width+'px','height':height+'px'});
				setStyle(iframe,{'display':'none'});
				loadEvent=this.attachTo(iframe,'load',this.load,this);
			},
		'image' : function imageContent(src) {
				makeObservable(this);								
				var image=null;				
				var src=src;				
				var loadEvent=null;
				this.load=function() {			
					loadEvent.detach();	
					loadEvent=null;
					this.triggerEvent('load');
					
				}
				this.appendTo=function(object) {					
					object.appendChild(image);
				}
				this.destruct=function () {
					this.detachAll();
					if(image.parentNode) {
						image.parentNode.removeChild(image);
					}
				}	
				this.hide=function() {
					if(loadEvent) {
						loadEvent.detach();	
						loadEvent=null;
					}	
				}
				this.dispatch=function() {
					if(!loadEvent) {						
						this.triggerEvent('load');
					}
					else {								
						image.src=src;
					}	
				}
				this.getHeight=function() {
					return image.offsetHeight;
				}
				this.getWidth=function() {
					return image.offsetWidth;
				}
				if(!images[src]) {
					image=document.createElement('img');
					images[src]=image;
					loadEvent=this.attachTo(image,'load',this.load,this);
				}
				else {					
					image=images[src];					
				}						
			}
	
	}
	
	var galleries={};
	
	var effectsTimer=createTimer(50);
	
	
	function createOverlay() {
		overlay=document.createElement('div');
		overlay.id='lightwindowOverlay';		
		setStyle(overlay,{'display': 'none'});
		if(IE6)
			setStyle(overlay,{'position':'absolute'});	
		appendBody(overlay);
	}
	
	function showOverlay() {		
		setStyle(overlay,{'display':'block'});	
	}
	function hideOverlay() {
		setStyle(overlay,{'display':'none'});
	}
	function createWindow() {			
		oWindow=new function lightwindowWindow() {
			var container=null;
			var titleBar=createTitlebar();
			var loader=createLoader();
			var stage=createStage();
			var contents=createContents();
			var descriptionBar=createDescriptionbar();
			var me=this;
			var cacheContentObject=null;
			var cacheArguments=null;
			var loaded=false;
			contents.attachEvent('hidden',function() {				
				if(cacheContentObject) {
					titleBar.hide();
					descriptionBar.hide();					
					me.sizeTo(640,480);					
					var previous=null;
					var next=null;
					if(cacheArguments['gallery']) {
						if(parseInt(cacheArguments['galleryId']) >0) {
							previous=galleries[cacheArguments['gallery']][parseInt(cacheArguments['galleryId'])-1];
						}
						if(parseInt(cacheArguments['galleryId']) <galleries[cacheArguments['gallery']].length-1) {
							next=galleries[cacheArguments['gallery']][parseInt(cacheArguments['galleryId'])+1];
						}
					}
					stage.setNext(next);
					stage.setPrevious(previous);
					contents.setContents(cacheContentObject);
					
					for(var i in handlers) {
						if(cacheArguments['handlers'][i])						
							handlers[i].setContents(cacheArguments['handlers'][i]);
						else 
							handlers[i].setContents(null);
					}
					cacheContentObject=null;
								
				}
				else {
					contents.setContents(null);
				}
			});
			contents.attachEvent('loaded',function() {								
				loaded=true;
				me.sizeTo(contents.getWidth()+widthAdjust,contents.getHeight()+heightAdjust);				
				
			});
			var sizeEffect=createSizeEffect(this,transitionTime);
			var sizeEvent=sizeEffect.attachEvent('complete',function() {
				me.sizeComplete();
			});
			var left=0;
			var top=0;
			var width=0;
			var height=0;
			
			this.getContainer=function() {
				return container;
			}
			function createContainer() {
				container=document.createElement('div');
				container.id='lightwindowWindow';
				setStyle(container,{'display':'none'});
				if(IE6)
					setStyle(container,{'position':'absolute'});
				me.setSize(0,0);			
			}
			this.sizeComplete=function() {
				if(loaded==true) {
					titleBar.setCaption(cacheArguments['title']);								
					descriptionBar.setDescription(cacheArguments['description'],parseInt(cacheArguments['galleryId'])+1,(cacheArguments['gallery'] ? galleries[cacheArguments['gallery']].length : null));
					loader.hide();
					contents.show();
					stage.showNav(contents);												
					titleBar.show();
					descriptionBar.show();
				}
			}
			this.update=function() {
				contents.update();
				stage.showNav(contents);
				descriptionBar.update();
				// On update, height - 30, don't ask me why... (makes no sense)
				this.setSize(contents.getWidth()+widthAdjust,contents.getHeight());
			}
			this.show=function(newContentObject,newArguments) {	
				if(width==0)						
					this.setSize(640,480);													
				loaded=false;
				cacheArguments=newArguments;
				cacheContentObject=newContentObject;
				loader.show();
				contents.hide();
				titleBar.hide();
				stage.hideNav();
				descriptionBar.hide();
				setStyle(container,{'display':'block'});
			}			
			this.hide=function() {
				setStyle(container,{'display':'none'});
				contents.hide(true);
				loader.hide(true);
				titleBar.hide(true);
				stage.hideNav();
				descriptionBar.hide(true);
				this.setSize(0,0);
			}
			this.setSize=function(newWidth,newHeight) {				
				width=newWidth;
				height=newHeight;
							
				left=dom.offsetWidth/2-(width)/2;
				top=dom.offsetHeight/2-height/2-30;	
				if(IE6)
					top=top+dom.scrollTop;
						
				setStyle(container,{'left':left+'px',
									'top':top+'px',
									'width':width+'px',
									'height':height+'px'});
			}
			this.sizeTo=function(newWidth,newHeight) {
				sizeEffect.sizeTo(newWidth,newHeight);
			}
			this.getWidth=function() {
				return width;
			}
			this.getHeight=function() {
				return height;
			}
			this.append=function(object) {
				container.appendChild(object);
				return object;
			}
			this.appendHandler=function(containerName,handler) {
				if(containerName=='window') {
					container.appendChild(handler.getContainer());
				}
				else {
					descriptionBar.appendHandler(containerName,handler);
				}
			}
			createContainer();
			this.append(titleBar.getContainer());
			titleBar.setCaption('');
			loader.setCaption(language['loading']+' <a href="" onclick="lightwindow.hide();return false">'+language['cancel']+'</a>');
			stage.append(loader.getContainer());
			stage.append(contents.getContainer());			
			this.append(stage.getContainer());
			this.append(descriptionBar.getContainer());			
		}
		
				
		appendBody(oWindow.getContainer());
		
		for(var i in handlers) {
			oWindow.appendHandler(handlers[i].getContainerName(),handlers[i]);
		}
	}
	function createLoader() {
		return new function lightwindowLoader() {
			var container=null;
			var contents=null;
			var opacityEffect=createOpacityEffect(this,transitionTime);
			var opacity=0;
			var me=this;
			this.getContainer=function() {
				return container;
			}
			function createContainer() {
				container=document.createElement('div');
				container.id='lightwindowLoader';
				contents=document.createElement('div');
				contents.id='lightwindowLoaderContents';
				container.appendChild(contents);
				me.setOpacity(0);						
			}			
			this.setCaption=function(newCaption) {
				contents.innerHTML=newCaption;
			}
			this.setOpacity=function(newOpacity) {
				opacity=newOpacity;
				setOpacity(container,opacity);
			}
			this.getOpacity=function() {
				return opacity;
			}
			this.opacityTo=function(newOpacity) {
				opacityEffect.opacityTo(newOpacity);
			}
			this.show=function() {
				setStyle(container,{'zIndex' : 1});
				this.opacityTo(100);				
			}
			this.hide=function(immediate) {
				setStyle(container,{'zIndex' : 0});
				if(immediate) {
					opacityEffect.cancel();
					this.setOpacity(0,0);
				}
				else {
					this.opacityTo(0);
				}
			}
			createContainer();
		}
	}
	function createTitlebar() {
		return new function lightwindowTitlebar() {
			var container=null;	
			var closeButton=null;
			var caption=null;		
			var width=0;
			var height=0;
			var me=this;
			var sizeEffect=createSizeEffect(this,transitionTime);
			
			this.getContainer=function() {
				return container;
			}
			this.setCaption=function(newCaption) {
				caption.innerHTML=newCaption;
			}
			this.setSize=function(newWidth,newHeight) {
				width=newWidth;
				height=newHeight;
				setStyle(container,{'marginTop':(-height)+'px',
									'height':height+'px'});
			}
			this.sizeTo=function(newHeight) {
				sizeEffect.sizeTo(0,newHeight);
			} 
			this.getHeight=function() {
				return height;
			}
			this.getWidth=function() {
				return width;
			}
			this.show=function() {
				this.sizeTo(30);
			}
			this.hide=function(immediate) {
				if(immediate) {
					sizeEffect.cancel();
					this.setSize(0,0);
				}
				else {
					this.sizeTo(0);
				}
			}
			function createContainer() {
				container=document.createElement('div');
				container.id='lightwindowTitlebar';
				caption=document.createElement('div');
				caption.id='lightwindowTitlebarCaption';
				closeButton=document.createElement('a');
				closeButton.id='lightwindowTitlebarClose';
				closeButton.innerHTML=language['close'];
				closeButton.href='#';
				closeButton.onclick=function(e) {
					e=e||window.event;
					lightwindow.hide();
					e.cancelBubble=true;
					if(e.preventDefault)
						e.preventDefault();
					return false;
				}
				container.appendChild(caption);
				container.appendChild(closeButton);
				me.setSize(0,0);												
			}
			
			createContainer();
		}
	}
	function createDescriptionbar() {
		return new function lightwindowDescriptionbar() {
			var container=null;		
			var galleryInfo=null;
			var galleryInfoImages=null;
			var description=null;	
			var width=0;
			var height=0;
			var me=this;
			var sizeEffect=createSizeEffect(this,transitionTime);
			var contentHeight=0;
			this.getContainer=function() {
				return container;
			}
			this.setDescription=function(newCaption,imageId,imageTotal) {
				setStyle(container,{'visibility':'hidden',
									'height':'auto'});
				description.innerHTML=newCaption;
				if(imageId) {
					setStyle(galleryInfo,{'display':'block'});
					galleryInfoImages.innerHTML=language['image']+' '+imageId+' '+language['imageOf']+' '+imageTotal;
				}
				else {
					setStyle(galleryInfo,{'display':'none'});
				}
				contentHeight=container.offsetHeight-26;
				if(contentHeight<0)
					contentHeight=0;
				setStyle(container,{'height':'0px',
									'visibility':'visible'});
			}
			this.update=function() {
				setStyle(container,{'visibility':'hidden',
								'height':'auto'});
				contentHeight=container.offsetHeight-26;
				if(contentHeight<0)
					contentHeight=0;
				setStyle(container,{'visibility':'visible',
									'height':contentHeight+'px',
									'marginTop':'-10px'});
				
			}
			this.setSize=function(newWidth,newHeight) {
				width=newWidth;
				height=newHeight;
				var marginTop=(height-contentHeight)-10;				
				setStyle(container,{'height':height+'px',
									'marginTop': (marginTop)+'px' });
			}
			this.sizeTo=function(newHeight) {
				sizeEffect.sizeTo(0,newHeight);
			} 
			this.getHeight=function() {
				return height;
			}
			this.getWidth=function() {
				return width;
			}
			this.show=function() {
				// @TODO: Better content detection			
				if(contentHeight>6)	
					this.sizeTo(contentHeight);
				setStyle(container,{'display':'block'});
			}
			this.hide=function(immediate) {
				if(immediate) {
					sizeEffect.cancel();
					this.setSize(0,0);
				}
				else { 
					this.sizeTo(0);
				}
			}
			this.appendHandler=function(containerName,handler) {				
				switch(containerName) {
					case 'descriptionBar':
						container.appendChild(handler.getContainer());
						break;					
					case 'galleryInfo':											
						galleryInfo.appendChild(handler.getContainer());
						break;
				}
			}
			function createContainer() {
				container=document.createElement('div');
				container.id='lightwindowDescriptionbar';
				description=document.createElement('div');
				description.id='lightwindowDescription';
				galleryInfo=document.createElement('div');
				galleryInfo.id='lightwindowGalleryInfo';
				galleryInfoImages=document.createElement('span');
				galleryInfoImages.id='lightwindowGalleryInfoImages';
				setStyle(galleryInfo,{'display':'none'});				
				container.appendChild(galleryInfo);
				container.appendChild(description);
				galleryInfo.appendChild(galleryInfoImages);
				contentHeight=10;				
				me.setSize(0,0);												
			}
			
			createContainer();
		}
	}
	function createStage() {
		return new function lightwindowLoader() {
			var container=null;
			
			var navPrevious=null;
			var navNext=null;
						
			var previous=null;
			var next=null;
			
			var nextClick=null;
			var previousClick=null;
			var nextOver=null;
			var previousOver=null;
			var nextOut=null;
			var previousOut=null;
			
			this.getContainer=function() {
				return container;
			}
			this.append=function(object) {
				container.appendChild(object);
			}
			this.setNext=function(newNext) {
				next=newNext;					
			}
			this.showNav=function(contents) {
				var overflow=contents.getOverflow();
				if(overflow=='vertical' || overflow=='both') 
					setStyle(navNext,{'marginRight':'26px'});
				else 
					setStyle(navNext,{'marginRight':'10px'});
				if(overflow=='horizontal' || overflow=='both') { 
					setStyle(navNext,{'height':(contents.getHeight()-16)+'px'});
					setStyle(navPrevious,{'height':(contents.getHeight()-16)+'px'});
				}
				else { 
					setStyle(navNext,{'height':contents.getHeight()+'px'});
					setStyle(navPrevious,{'height':contents.getHeight()+'px'});
				}
					
				if(next) {
					setStyle(navNext,{'display':'block'});
				}			
				else {
					setStyle(navNext,{'display':'none'});	
				}
				if(previous) {
					setStyle(navPrevious,{'display':'block'});
				}			
				else {
					setStyle(navPrevious,{'display':'none'});
				}
			}
			this.hideNav=function() {
				setStyle(navNext,{'display':'none'});
				setStyle(navPrevious,{'display':'none'});
			}			
			this.setPrevious=function(newPrevious) {
				previous=newPrevious;
				
			}
			function createContainer() {
				container=document.createElement('div');
				container.id='lightwindowStage';		
				
				navPrevious=document.createElement('div');
				navPrevious.id='lightwindowPrevious';
				navNext=document.createElement('div');
				navNext.id='lightwindowNext';
				container.appendChild(navPrevious);
				container.appendChild(navNext);
				nextClick=attachTo(navNext,'click',function() {
					lightwindow.show(next);
				});
				nextOver=attachTo(navNext,'mouseover',function() {
					setOpacity(navNext,100);					
				});
				nextOut=attachTo(navNext,'mouseout',function() {
					setOpacity(navNext,0);
				});
				previousClick=attachTo(navPrevious,'click',function() {
					lightwindow.show(previous);
				});
				previousOver=attachTo(navPrevious,'mouseover',function() {
					setOpacity(navPrevious,100);
				});
				previousOut=attachTo(navPrevious,'mouseout',function() {
					setOpacity(navPrevious,0);
				});
								
				setOpacity(navNext,0);
				setOpacity(navPrevious,0);
				setStyle(navNext,{'display':'none'});
				setStyle(navPrevious,{'display':'none'});				
			}			
			createContainer();
		}
	}
	
	function createContents() {
		return new function lightwindowContents() {
			var container=null;
			
			
			var width=0;
			var height=0;
			var overflow='none';
			
			var opacityEffect=createOpacityEffect(this,transitionTime);			
			var opacity=0;
			var me=this;
			var contentObject=null;
			var transitionEvent=null;
			makeObservable(this);
			
						
			opacityEffect.attachEvent('complete',function() {				
				me.triggerEvent(transitionEvent);
				if(transitionEvent=='shown') {
					if(overflow!='none') 
						setStyle(container,{'overflow':'auto'});
					else
						setStyle(container,{'overflow':'visible'});
				}				
				
			});
			this.getContainer=function() {
				return container;
			}
			this.getOverflow=function() {
				return overflow;
			}
			function createContainer() {
				container=document.createElement('div');
				container.id='lightwindowContents';
				
				
				me.setOpacity(0);			
				
			}			
			this.setContents=function(newContentObject) {
				if(contentObject) {					
					contentObject.destruct();
					contentObject=null;					
				}
				if(newContentObject==null)
					return;			
				contentObject=newContentObject;							
				contentObject.attachEvent('load',function() {
					me.callibrate();					
					me.triggerEvent('loaded');
				});
				contentObject.appendTo(container);				
				contentObject.dispatch();
			}
			this.setOpacity=function(newOpacity) {
				opacity=newOpacity;				
				setOpacity(container,opacity);
			}			
			this.getOpacity=function() {
				return opacity;
			}
			this.callibrate=function() {
				if(contentObject) {
					overflow='none';
					
					width= contentObject.getWidth();
					if(width>getViewPortWidth()-marginWidth) { 
						width=getViewPortWidth()-marginWidth;
						if(width<200)
							width=200;
						overflow='horizontal';
					}
					height=contentObject.getHeight();
					if(overflow=='horizontal') {
						height=height+17;
					}
					if(height>getViewPortHeight()-marginHeight) {
						height=getViewPortHeight()-marginHeight;
						if(height<50)
							height=50;
						if(overflow=='none') {
							width=width+17;
							overflow='vertical';
						}
						else 
							overflow='both';
						
					}		
										
					setStyle(container,{'width':width+'px',
										'height':height+'px'});
				
				}	
			}
			
			this.getWidth=function() {
				if(contentObject) {
					return width;
				}
				return 0;
			}
			this.getHeight=function() {
				if(contentObject) {
					return height;
				}
				return 0;
			}
			this.update=function() {
				this.callibrate();
				if(overflow!='none') 
					setStyle(container,{'overflow':'auto'});
				else
					setStyle(container,{'overflow':'visible'});
			}
			this.hide=function(immediate) {			
				transitionEvent='hidden';
				setStyle(container,{'zIndex' : 0});
				if(contentObject && contentObject.hide) 
					contentObject.hide();
				setStyle(container,{'overflow':'hidden'});
				if(immediate)  {
					opacityEffect.cancel();					
					this.setOpacity(0);
					// While tempted, do not destroy content object here. It might have started
					// some load operation and it should finish. Content objects should kill their
					// events when hidden;				
				}
				else {					
					this.opacityTo(0);
				}
			}
			this.show=function() {				
				transitionEvent='shown';
				setStyle(container,{'zIndex' : 1});
				if(contentObject && contentObject.show) 
					contentObject.show();
				this.opacityTo(100);
			}
			this.opacityTo=function(newOpacity) {
				opacityEffect.opacityTo(newOpacity);
			}
			createContainer();
		}
	}
	function getViewPortWidth() {
		if(_viewPortWidth && _viewPortWidth< dom.offsetWidth)
			return _viewPortWidth;
		else 
			return dom.offsetWidth;
	}
	function getViewPortHeight() {
		if(_viewPortHeight && _viewPortHeight< dom.offsetHeight)
			return _viewPortWidth;
		else 
			return dom.offsetHeight;
	}
	
	this.show=function(src,media,width,height,viewPortWidth,viewPortHeight) {	
		if(loaded==false) {
			queued=src;
			return false;		
		}
		var arguments=getArguments(src);
		// AF20100205:	Set width and height if not done by element
		if(!arguments['width'] && width)
			arguments['width']=parseFloat(width);
		if(!arguments['height'] && height)
			arguments['height']=parseFloat(height);
			
		if(viewPortWidth)
			_viewPortWidth=parseFloat(viewPortWidth);
		else
			_viewPortWidth=null;
		if(viewPortHeight)
			_viewPortHeight=parseFloat(viewPortHeight);
		else 
			_viewPortHeight=null;
			
		if(!arguments)
			return;		
		showOverlay();		
		if(!media)
			media=detectMedia(arguments['src']);
		oWindow.show(new mediaContentObjects[media](arguments['src'],arguments),arguments,media);
	}	
	this.hide=function() {
		hideOverlay();
		oWindow.hide();
	}
	this.setMarginHeight=function(margin) {
		marginHeight=margin;
	}
	this.setMarginWidth=function(margin) {
		marginWidth=margin;
	}
	this.setTransitionTime=function(time) {
		transitionTime=time;
	}
	this.addContentHandler=function(name,containerName,handler,containerType) {		
		handlers[name]=new lightwindowContentHandler(name,containerName,handler,containerType); 
		function lightwindowContentHandler(name,containerName,handler,containerType) {			
			var name=name;
			if(!handler)
				handler=function(contents) { return contents; }; 
			var handler=handler;
			var containerName=containerName;
			if(!containerType)
				containerType='span';
			var containerType=containerType;
			var container=null;			
			this.setContents=function(contents) {				
				container.innerHTML=handler(contents);
			}
			function createContainer() {
				container=document.createElement(containerType);
				container.id=name;										
			}
			this.getContainerName=function() {
				return containerName;
			}	
			this.getContainer=function() {				
				return container;
			}
			createContainer();
		}
		if(oWindow)
			oWindow.appendHandler(containerName,handlers[name]);
	}
	function IE6Update() {		
		setStyle(overlay,{'width':dom.scrollWidth+'px',
						  'height':dom.scrollHeight+'px'});
	}
	function Update() {
		if(IE6)
			IE6Update();		
		oWindow.update();
	}
	function getArguments(src) {
		var arguments={'title':'',
						'description':'',
						'gallery':null,
						'galleryId':null,
						'handlers': {}};
		if(src) {
			if(src.tagName)
			
				switch(src.tagName) {
					case 'A':
						if(src.getAttribute('title')!==null)
							arguments['title']=src.getAttribute('title');
						else
							arguments['title']='';
						if(src.getAttribute('rel') && src.getAttribute('rel').indexOf('[')>-1) {
							var rel=src.getAttribute('rel');
							arguments['gallery']=rel.substring(rel.indexOf('[')+1, rel.indexOf(']'));
						}	
						if(src.getAttribute('rel') && src.getAttribute('rel').indexOf('(')>-1) {
							var rel=src.getAttribute('rel');
							var additionalArguments=rel.substring(rel.indexOf('(')+1, rel.indexOf(')'));
							additionalArguments=additionalArguments.split(';');
							for(var i=0;i<additionalArguments.length;i++) {								
								var argument=additionalArguments[i].split('=');
								switch(argument[0]) {
									case 'width':
									case 'height':
										arguments[argument[0]]=parseInt(argument[1]);
										break;
									default:
										arguments[argument[0]]=argument[1];
										break;
								}
																
							}
						}						
						if(src.getAttribute('galleryId')>=0) {
							arguments['galleryId']=src.getAttribute('galleryId');
						}
						// Lightwindow compat
						if(src.getAttribute('caption')!=null) {						
							if(src.getAttribute('caption').indexOf("#")===0) {								
								if(document.getElementById(src.getAttribute('caption').substr(1))) {
									arguments['description']+=document.getElementById(src.getAttribute('caption').substr(1)).innerHTML;
								}
							}
							else {
								arguments['description']+=src.getAttribute('caption');
							}
						}										
						var spans=src.getElementsByTagName('span');
						for(var span in spans) {							
							switch(spans[span].className) {
								case 'lightwindowDescription': 
									arguments['description']+=spans[span].innerHTML;
									break;
								default:
									if(handlers[spans[span].className]) {
										arguments['handlers'][spans[span].className]=spans[span].innerHTML;
									}								
									break;
							}
						}												
						arguments['src']=src.getAttribute('href');
						break;
					default:
						return;	
			}
			else if((typeof src)=='string') {
				arguments['src']=src;
			} else {
				return;
			}
		}
		else {
			return;
		}
		return arguments;
	}
	function appendBody(object) {
		if(document.body) {
			document.body.appendChild(object);
		}
		else {
			document.documentElement.appendChild(object);
		}
	}

	function setStyle(object,styles) {
		for(var style in styles) {
			try {
				object.style[style]=styles[style]
			}
			catch(e) {
				alert("Can't apply style "+style+"="+styles[style]+" to object #"+object.id);
			}
		}
	}
	function setOpacity(object,opacity) {
		
		 // IE/Win
		try {
			object.style.filter = "alpha(opacity:"+opacity+")";
			if(opacity==100) 
				object.style.filter = "";			
	    }
		catch(e) {
		}
	    // Safari<1.2, Konqueror
		try {
			object.style.KHTMLOpacity = opacity/100;
		}
		catch(e) {
		}
	    // Older Mozilla and Firefox
		try {
			object.style.MozOpacity = opacity/100;
		}
		catch(e) {
		}
	    // Safari 1.2, newer Firefox and Mozilla, CSS3
		try {
			object.style.opacity = opacity/100;
		}
		catch(e) {
		}		
				
		
	}
	
	function detectMedia(url) {
		// Special recognition			
		if(url.indexOf('image.php')>-1) {
			return 'image';
		}	
		if(url.indexOf('rpc.php')>-1) {
			return 'rpc';
		}	
		var image = new RegExp("[^\.]\.("+mediaTypes.image.join('|')+")\s*$", "i");
		if(image.test(url)) {
			return 'image';
		}
		var media = new RegExp("[^\.]\.("+mediaTypes.media.join('|')+")\s*$", "i");
		if(media.test(url)) {
			return 'media';
		}
		// AF20100205:	Youtube support		
		var youtube = new RegExp("http:\\/\\/www.youtube.com\\/watch\\?v=([a-zA-Z0-9]+)", "i");		;		
		if(youtube.test(url)) {						
			return 'media';
		}		
		if(url.indexOf('#')===0 || url.indexOf(window.location.href.substr(0,window.location.href.indexOf('/',8)+1)+'#')===0) {						                                                                                             
			return 'inline';
		}
		return 'iframe';
	}
	
	function makeObservable(observableObject) {	
		var tmp=new function eventHandler() {
			var observers=new Array();
			var wrappers=new Array();			
			observableObject.triggerEvent=function(eventName,eventParams) {
				for(var observer in observers) {
					observer=observers[observer];
					if(observer['eventName']===null || observer['eventName']==eventName) {
						observer['callBack'].apply(observer['observingObject'],[eventName,eventParams]);
					}
				}
			}
			observableObject.observe=function(callBack,observingObject) {
				return this.attachEvent(null,callBack,observingObject);
			}
			
			observableObject.attachEvent=function(eventName,callBack,observingObject) {
				if(!observers)
					return false;
				observers.push({ 'eventName' : eventName, 'observingObject':observingObject,'callBack':callBack});
				return observers.length-1;
			}
			observableObject.detachEvent=function(eventId) {
				delete observers[eventId];
			}
			observableObject.detachAll=function()  {				
				while(wrappers.length>0) {					
					var wrapper=wrappers.pop();										
					wrapper.detach();
				}
				delete observers;
				
			}
			observableObject.attachTo=function(srcObject,srcEvent,targetMethod,targetObject) {
				var newWrapper= attachTo(srcObject,srcEvent,targetMethod,targetObject);
				wrappers.push(newWrapper);
				return newWrapper;
			}
		}
			
	}
	
	function attachTo(srcObject,srcEvent,targetMethod,targetObject) {
		return new eventWrapper(srcObject,srcEvent,targetMethod,targetObject);
		function eventWrapper(srcObject,srcEvent,targetMethod,targetObject) {
			
			if(srcObject.attachEvent) {
				srcObject.attachEvent("on"+srcEvent,AttachEventWrapper );
			}
			else {
				srcObject.addEventListener(srcEvent,AddEventListenerWrapper,false);
			}
			
			function AttachEventWrapper() {
				return targetMethod.apply(targetObject,[srcEvent,window.event]);
				
			}
			function AddEventListenerWrapper(e) {
				return targetMethod.apply(targetObject,[srcEvent,e]);
				
			}
			this.detach=function() {
				if(srcObject.detachEvent) {
					srcObject.detachEvent("on"+srcEvent,AttachEventWrapper);
				}
				else {
					srcObject.removeEventListener(srcEvent,AddEventListenerWrapper,false);
				}
			}
		}
	
	}
	
	function createTimer(delay) {
		return new function() {			
			var timer=this;			
			this.delay=delay;
			this.interval=null;
			
			makeObservable(this);
	
			this.start=function() {				
				if(!this.interval)
					this.interval=window.setInterval( this.time,this.delay);
				else
					return false
				return true;
			}
			this.stop=function() {				
				if(this.interval)  {
					window.clearInterval(this.interval);
				}
				else
					return false;
				return true;
			}
			this.time=function() {		
				timer.triggerEvent('time');
			}
			this.destruct=function() {				
				this.stop();
				this.detachAll();
			}
			
	
		}
		this.create= function(delay) {
			var newTimer= new timer(delay,timers.length);
			timers.push(newTimer);
			return newTimer;
		}
		this.timer=function(timerId) {
			return timers[timerId];
		}
		this.destroy=function(timerId) {
			if(timers[timerId]) {
				timers[timerId]._destroy();
				delete timers[timerId];
			}
		}
	}
	function createSizeEffect(targetObject,transitionTime) {
		return new function sizeEffect() {
			var eventId= null;
			
			
			var sourceWidth=0;
			var sourceHeight=0;
			
			var targetWidth=0;
			var targetHeight=0;
			
			var currentWidth=0;
			var currentHeight=0;
			
			var widthStep=0;
			var heightStep=0;
			
			var step=0;
			if(transitionTime<0.05)
				transitionTime=0.05;
			var stepSize=5/transitionTime;
			
			var active=false;
			
			makeObservable(this);
			
			this.sizeTo= function(width,height) {
				active=false;
				sourceWidth=targetObject.getWidth();
				sourceHeight=targetObject.getHeight();
				targetWidth=width;
				targetHeight=height;
				
				widthStep=((targetWidth-sourceWidth)/(100/stepSize));
				heightStep=((targetHeight-sourceHeight)/(100/stepSize));
				
				step=0;
				active=true;	
			}
			this.step=function() {
				if(!active)
					return;			
				step=step+stepSize;
				if(step>=100) {
					sourceWidth=targetWidth;
					sourceHeight=targetHeight;
					active=false;
				}
				else {
					sourceWidth=sourceWidth+widthStep;
					sourceHeight=sourceHeight+heightStep;
				}
				targetObject.setSize(Math.floor(sourceWidth),Math.floor(sourceHeight));
				if(step>=100)
					this.triggerEvent('complete');				
			}
			this.cancel=function() {
				active=false;
			}
			this.destruct=function() {
				timer.detachEvent(eventId);
				this.detachAll();
			}
			eventId=effectsTimer.attachEvent('time',this.step,this);
			
		}
	}
	function createOpacityEffect(targetObject,transitionTime) {
		return new function opacityEffect() {
			var eventId= null;
			
			
			
			var sourceOpacity=0;
		
			var targetOpacity=0;
			
			var currentOpacity=0;
	
			var opacityStep=0;
	
			
			var step=0;
			if(transitionTime<0.05)
				transitionTime=0.05;
			var stepSize=5/transitionTime;
	
			var active=false;
			
			makeObservable(this);
			
			this.opacityTo= function(opacity) {
				active=false;
				sourceOpacity=targetObject.getOpacity();
				targetOpacity=opacity;
				
				opacityStep=((targetOpacity-sourceOpacity)/(100/stepSize));
				
				step=0;
				active=true;	
			}
			this.step=function() {
				if(!active)
					return;
				step=step+stepSize;
				if(step>=100) {
					sourceOpacity=targetOpacity;
					active=false;
				}
				else {
					sourceOpacity=sourceOpacity+opacityStep;
				}
				targetObject.setOpacity(Math.floor(sourceOpacity));
				if(step>=100)
					this.triggerEvent('complete');		
			}
			this.cancel=function() {
				active=false;
			}
			this.destroy=function() {
				timer.detachEvent(eventId);
				this.detachAll();
			}
			eventId=effectsTimer.attachEvent('time',this.step,this);
			
		}
	}
	function domLoading() {
		function IELoaded() {
			if(document.readyState=='complete') {
				domLoaded();				
				document.detachEvent('onreadystatechange',IELoaded);
			}				
		}
		function GeckoLoaded() {
			document.removeEventListener("DOMContentLoaded",GeckoLoaded,false);
			domLoaded();
		}						
		if(document.addEventListener) {
		    document.addEventListener("DOMContentLoaded",GeckoLoaded, false);
		} else {						 
			document.attachEvent('onreadystatechange',IELoaded);
		}
	}
	function domLoaded() {	
		
		createOverlay();
		createWindow();
		if(IE6) {
			IE6Update();			
		}	
		events['unload']=attachTo(window,'unload',function() { destruct() });
		events['overlay']=attachTo(overlay,'click',me.hide,this);		
		events['resize']=attachTo(window,'resize',Update);
		if(IE6)
			events['scroll']=attachTo(window,'scroll',Update);
		effectsTimer.start();
		processLinks();	
		loaded=true;
		if(queued)
			me.show(queued);		
	}
	function detectLanguage() { 		
		// BF20091102:	Gecko/webkit compatibility
		var language = navigator.userLanguage || navigator.language;

		if ( language ) {
			var sUserLang = language.toLowerCase() ;
			
			if ( sUserLang.length >= 5 )
			{
				sUserLang = sUserLang.substr(0,5) ;
				if ( translations[sUserLang] ) return sUserLang ;
			}
			
			if ( sUserLang.length >= 2 )
			{
				sUserLang = sUserLang.substr(0,2) ;
				if ( translations[sUserLang] ) return sUserLang ;
			}
		}
		return 'en';
	}
	function processLinks() {
		var links=dom.getElementsByTagName('a');
		for(var i in links) {
			if(links[i].className=='lightwindow') {
				// IE hrefs are not always static string. Making them static here.
				if(IE)
					links[i].href=links[i].href;
				var arguments=getArguments(links[i]);				
				if(!links[i].onclick || links[i].onclick.toString().indexOf('lightwindow')==-1) {				
					attachTo(links[i],'click',function(eventName,e) {
						e = e || window.event;									
						me.show(this);
						e.cancelBubble=true;
						if(e.preventDefault)
							e.preventDefault();
						return false;					
					},links[i]);					
				}
				
				if(arguments['gallery']) {
					if(!galleries[arguments['gallery']]) {
						galleries[arguments['gallery']]=new Array();
					}					
					links[i].setAttribute('galleryId',galleries[arguments['gallery']].length);					
					galleries[arguments['gallery']].push(links[i]);
				}
			}
		}
		
	}
	this.appendToGallery=function(oLink,sGallery) {
		if(!galleries[sGallery]) {
			galleries[sGallery]=new Array();
		}	
		oLink.setAttribute('galleryId',galleries[sGallery].length);					
		galleries[sGallery].push(oLink);
	}
	function destruct() {
		for(var event in events) {		
			events[event].detach();
		}
		delete galleries;
		effectsTimer.destruct();
	}
	language=translations[detectLanguage()];
	domLoading();		
	
}
