;(function(jQuery) {
	//static class functions
	/*jQuery.ifwsxgallery = {
			everything has to be in context 
	};
	*/
	
	var defaults = {
		startImageIndex: 	0,
		pageNaviMode:		0, //0 = fadeIn/fadeOut; 1 = scroll horizontal; 2 = scroll vertical
		thumbWidth:			100,
		thumbHeight:		80,
		thumbPageWidth:		960,
		thumbPageHeight:	120,
		nextPageCaption:	'Next Page',
		prevPageCaption:	'Previous Page',
		showImageCaption:	1,
		thumbOpacity:		0.65,
		showLinkLabels:		1,
		userPages:			1,
		labelPage:			'Page',
		labelPhoto:			'Photo',
		useLightbox:		1,
		imageWidth:			500,
		imageHeight:		375,
		spaceOffset:		20 //&nbsp; for vertically centering the slideshow image
	};
	
	//extend the fn for the methods
	jQuery.fn.ifwsxgallery = function(settings) {
		
		jQuery.extend(this,{
			images: {},
			imageCount: 0,
			inImageFading: false,
			inImageTitleFading: false,
			
			// the handler function for the thumbs
			clickThumbHandler: function(e, link, ga) {
				ga.gotoImage(jQuery(link).attr('rel'));
				e.preventDefault();
			},

			getImage: function(index) {
				//if (!index)
				//	return undefined;
				return this.images[index];
			},
			
			addImage: function(lielement) {
				var aThumb = lielement.find('a');
				var href = aThumb.attr('href');
				var rel = aThumb.attr('rel');
				var title = aThumb.attr('title');
				var imagerel = aThumb.find('img').attr('rel');
				this.imageCount++;
				
				var ga = this;
				
				var img = {
					title:title,
					href:href,
					gallery:this,
					index:this.data.length,
					rel:imagerel
				};
				
				// Add the imageData to this gallery's array of images
				this.data.push(img);

				// Register the image globally
				this.images[rel] = img;
				
				//set the clickHandler for the thumb
				aThumb.click(function(e) {
					ga.clickThumbHandler(e, this, ga);
				});
				
				return this;
			},
			
			initialize: function() {
				this.curPage = 0;
				this.curImageIndex = this.startImageIndex;
				
				this.$thumbs = jQuery(this.find('.ifwsxgallery-thumbs'));
				this.$slideshow = jQuery(this.find('.ifwsxgallery-slideshow-wrapper'));
						
				this.pageCount = this.$thumbs.find('ul').length;
				this.thumbsPerPage = this.$thumbs.find('ul:first-child > li').length-1;
				
				this.initializeImages();
				
				//now would be the right time to ...
				if (this.data.length==0)
					return this;
				
				this.initializeNavigation();
				
				if (this.usePages) {
					this.addPageNavi();
					if (this.pageCount > 0) {
						this.initializePages();
						this.showPageNavi();
					}
					this.showPage(this.curPage);
				}

				this.resizeElements();
				
				this.curImage = this.getImage(this.curImageIndex);
				
				if (this.showImageCaption==2) {
					this.initializeImageTitle();
					this.showImageTitle();
				}
				
				return this;
			},
			
			initializeImages: function() {
				this.data = [];				
				
				var ga = this;
				
				this.$thumbs.find('li').each(function(i) {
					//add the rollover effects
					jQuery(this).css('opacity',ga.thumbOpacity)
						.hover(function(){
							jQuery(this).fadeTo('fast',1);
						}, function(){
							if (!jQuery(this).hasClass('selected')) 
								jQuery(this).fadeTo('fast', ga.thumbOpacity);
						});
					
					//add the images
					ga.addImage(jQuery(this));
				});
				
				return this;
			},

			initializeNavigation: function () {
				this.$imagenavi = jQuery(this.find('.ifwsxgallery-navi'));
				
				var ga = this;
				
				this.$imagenavi.find('a.ifwsxgallery-previmage').click(function(e) {
					ga.gotoImage(ga.getPrevIndex(ga.curImage.index));
					e.preventDefault();
				});
				this.$imagenavi.find('a.ifwsxgallery-nextimage').click(function(e) {
					ga.gotoImage(ga.getNextIndex(ga.curImage.index));
					e.preventDefault();
				});
				
				//add the gotoNextImage click event if no lightbox is used
				if (this.useLightbox) {
					this.$slideshow.find('a.ifwsxgallery-largeimage').click(function(e) {
						ga.showLightbox(ga, this);
						e.preventDefault();
					});
				} else  {
					this.$slideshow.find('a.ifwsxgallery-largeimage').click(function(e) {
						ga.gotoImage(ga.getNextIndex(ga.curImage.index));
						e.preventDefault();
					});
				}

				//set the width as style to make margin auto work
				this.$imagenavi.css('width', this.$imagenavi.width());
				
				return this;
			},
			
			addPageNavi: function() {
				this.$pagenavi = jQuery(this.find('.ifwsxgallery-thumbpage-navi'));
				var ga = this;
				
				//number links for the pages
				this.$thumbs.find('ul').each(function(i) {
					var id='ifwsxgallery-thumb-pagelink'+(i);
					ga.$pagenavi.append('<a href="#" id="'+id+'" class="ifwsxgallery-thumb-page" alt="'+(ga.labelPage+' #'+(i+1))+'" title="'+(ga.labelPage+' #'+(i+1))+'" rel="'+i+'">'+(i+1)+'</a>');
					var link = ga.$pagenavi.find('#'+id);
					if (link) {
					    link.click(function(e) {
							//ga.hidePage(ga.curPage);
					    	index = jQuery(this).attr('rel');
					    	if (ga.curPage!=index)
					    		ga.showPage(index);
							e.preventDefault();
					    });
					}
				});
				var label = '';
				if (this.showLinkLabels) {label = this.prevPageCaption;} else {label = '';}
				//jQuery(pagenavi).prepend('<a href="#" id="ifwsxgallery-thumbpage-prev" title="'+this.prevPageCaption+'" alt="'+this.prevPageCaption+'" >'+label+'</a>');
				this.$pagenavi.prepend('<a href="#" class="ifwsxgallery-thumbpage-prev" title="'+this.prevPageCaption+'" alt="'+this.prevPageCaption+'" >'+label+'</a>');
				if (this.showLinkLabels) {label = this.nextPageCaption;} else {label = '';}
				//jQuery(pagenavi).append('<a href="#" id="ifwsxgallery-thumbpage-next" title="'+this.nextPageCaption+'" alt="'+this.nextPageCaption+'" >'+label+'</a>');
				//TODO: testen ob hier das click gleich auf das append drangehaeng werden kann
				this.$pagenavi.append('<a href="#" class="ifwsxgallery-thumbpage-next" title="'+this.nextPageCaption+'" alt="'+this.nextPageCaption+'" >'+label+'</a>');
				//prev next links
				this.$pagenavi.find('.ifwsxgallery-thumbpage-prev').click(function(e) {
					ga.showPage(ga.getPrevPageIndex(ga.curPage));
					e.preventDefault();
				});
				
				this.$pagenavi.find('.ifwsxgallery-thumbpage-next').click(function(e) {
					ga.showPage(ga.getNextPageIndex(ga.curPage));
					e.preventDefault();
				});
				
				//set the width as style to make margin auto work
				this.$pagenavi.css('width', this.$pagenavi.width());
				
				return this;
			},
			
			initializePages: function() {
				this.$scrollable = jQuery(this.find('.ifwsxgallery-scrollable'));
				var ga = this;
				
				this.$scrollable.css({
					overflow: 'hidden',
					/*float: 'left', TODO: Check if this works in every case*/ 
					width: this.thumbPageWidth,
					height: this.thumbPageHeight,
					position: 'relative'
				});
				
				if (this.pageNaviMode == 1) {
					
					this.$thumbs.css({
						left: 0,
						position: 'absolute',
						width: (this.thumbPageWidth*this.pageCount)
					});
					
					//set all list to visible
					this.$thumbs.find('ul').each(function(i){
						jQuery(this).css({
							width: ga.thumbPageWidth,
							float: 'left',
							display: 'block'
						});
					});
				} else if (this.pageNaviMode == 2) {
					
					this.$thumbs.css({
						left: 0,
						top: 0,
						position: 'absolute',
						height: (this.thumbPageHeight*this.pageCount)						
					}).find('ul').each(function(i){
						jQuery(this).css({
							display: 'block',
							height: ga.thumbPageHeight
						});
					});
				}
			},
	
			showPageNavi: function() {
				if (this.$pagenavi)
					this.$pagenavi.show();
			},

			showPage: function(index) {
				var ga = this;
				var oldindex = this.curPage;

				this.curPage = index;
				
				if (this.pageNaviMode == 0) {
					//fadein/fadeout mode
					this.$thumbs.find('ul.ifwsxgallery-thumblist-page[rel='+oldindex+']').fadeOut('normal', function() {
						ga.$thumbs.find('ul.ifwsxgallery-thumblist-page[rel='+ga.curPage+']').fadeIn('normal');
					});
				} else if (this.pageNaviMode == 1) {
					//scroll left and right mode
					var pageleft = index * this.thumbPageWidth;
					this.$thumbs.animate({left: -pageleft},'slow');
										
				} else if (this.pageNaviMode == 2) {
					var pagetop = index * this.thumbPageHeight;
					
					this.$thumbs.animate({top: -pagetop},'slow');
				}

				var firstindex = this.getFirstIndexOfPage(this.curPage);
				if (firstindex != this.curImageIndex) 
					this.gotoImage(firstindex);
				
				//update page navigation
				this.$pagenavi.find('a.selected').removeClass('selected');
				this.$pagenavi.find('a[rel='+this.curPage+']').addClass('selected');
				
				return this;
			},
			
			resizeElements: function() {
				var $img = jQuery(this.$slideshow.find('.ifwsxgallery-largeimage'));
				var imgheight = $img.outerHeight();
				var imgwidth = this.imageWidth+this.spaceOffset;
				
				this.$slideshow.find('.ifwsxgallery-show-loading').css({
					height: imgheight,
					width: imgwidth
				});
				
				$img.css({
					lineHeight: (imgheight+'px'),
					height: imgheight,
					width: imgwidth
				});
				
				this.$slideshow.css({height: imgheight, width: imgwidth});
				
				return this;
			},
			
			initializeImageTitle: function() {
				$imagetitlewrapper = jQuery(this.$slideshow.find('.ifwsxgallery-imagecaption-wrapper'));
				var $largeimg = jQuery(this.$slideshow.find('.ifwsxgallery-largeimage'));
				var $img = jQuery($largeimg.find('img'));
				var innerh = $img.height();
				var innerw = $img.width();
				var imgposition = $img.position();
				
				//initialize the fade in content
				$imagetitlewrapper.css({
					position: 'absolute',
					overflow: 'hidden',
					display: 'block',
					top: imgposition.top,
					left: imgposition.left,
					width: innerw,
					height: innerh,
					zIndex: 1
				});
				$imagetitlewrapper.find('.ifwsxgallery-image-caption').css({
					position: 'relative',
					top: (imgposition.top+innerh),
					background: '#000',
					display: 'block',
					opacity: 0.6,
					color: '#fff',
					padding: 5
				});
				
				return this;
			},

			showImageTitle: function() {
				this.inImageTitleFading = true;
				var $largeimg = jQuery(this.$slideshow.find('.ifwsxgallery-largeimage'));
				var $img = jQuery($largeimg.find('img'));
				var innerh = $img.height();
				var innerw = $img.width();
				var outerh = $img.outerHeight();
				var outerw = $img.outerWidth();
				var diffh = (outerh-innerh)/2;
				var diffw = (outerw-innerw)/2;
				var imgposition = $img.position();
				var imgoffset = $img.offset();

				var $captionwrapper = this.$slideshow.find('.ifwsxgallery-imagecaption-wrapper');
				var $caption = jQuery($captionwrapper.find('.ifwsxgallery-image-caption'));
				//first set the width of the to get the correct height
				$captionwrapper.css('width', innerw);
				//now the capheight should be correct
				var capheight = $caption.outerHeight();
				
				$captionwrapper.css({
					top: (imgposition.top+diffh+innerh-capheight),
					left: (imgposition.left+diffw),
					height: capheight
				});
				$caption.css({
					top: capheight
				});				
				
				var ga = this;

				if (this.curImage.title)
					$caption.animate({top: 0}, 'normal', function() {
						ga.inImageTitleFading = false;
					});
			},
			
			getFirstIndexOfPage: function(pageindex) {
				var $link = jQuery(this.$thumbs.find('ul.ifwsxgallery-thumblist-page[rel='+pageindex+'] > li:first-child > a:first-child'));
				firstIndex = $link.attr('rel');
				
				return firstIndex;
			},
			
			getPageIndexOfImage: function(imageindex) {
				var pageIndex = this.$thumbs.find('ul.ifwsxgallery-thumblist-page li.selected').parent().attr('rel');
				
				//var pageIndex = Math.floor((imageindex-1) / this.thumbsPerPage);	
				//if (pageIndex < 0) 
				//	pageIndex = 0;
				
				return pageIndex;
			},
			
			gotoImage: function(index) {
				var img = this.getImage(index);

				//var index = img.index;

				//just fading -> do nothing
				if (this.inImageFading)
					return this;
			
				//same image -> do nothing
				if (this.curImage && index == this.curImage.index) 
					return this;
				
				this.inImageFading = true;
				
				this.updateSelectedThumb(this.curImageIndex, index);
				
				this.curImage = img;
				this.curImageIndex = img.index;
				
				//this.refresh();
				//var imagecontainer = jQuery('#ifwsxgallery-slideshow'); 
				//var image = imagecontainer.find('img');
				var $image = jQuery(this.$slideshow.find('img'));
				$image.addClass('previous-image').removeClass('current-image');
				
				var ga = this;
				if ((this.showImageCaption==2) && (this.$slideshow.find('.ifwsxgallery-image-caption').text())) {
					this.hideImageTitle(img, $image);
				} else {
					$image.fadeOut('normal', function() {
						//fadeout first then fadein
						ga.buildNewImage(img);
						ga.removeImage($image);
					});
				}
				//update pages
				var pageIndex = this.getPageIndexOfImage(index);

				if (pageIndex != this.curPage)
					this.showPage(pageIndex);
				
				return this;
			},
			
			removeImage: function(img) {
				img.remove();
				
				return this;
			},	
			
			buildNewImage: function(img) {
		
				if (!img.image) {
					var image = new Image();
					var ga = this;
					image.onload = function() {
						img.image = this;
						ga.showNewImage(img);
					};
										
					image.src = img.href;
				} else {
					this.showNewImage(img);
				}
				
				return this;
			},
			
			showNewImage: function(img) {
				if (!this.inImageFading)
					return this;
				
				var ga = this;
				
				var $imagelink = jQuery(this.$slideshow.find('a.ifwsxgallery-largeimage'));
				//imagecontainer.find('a').append('<img class="current-image" src="'+img.href+'" style="display: none;" />');
				$imagelink.append(jQuery(img.image));
				$imagelink.attr('rel', img.rel);
				$imagelink.attr('title', img.title);
				//newimage.css('display','none');
				$newimage = jQuery($imagelink.find('img'));
				$newimage.attr('rel', img.index);
				$newimage.attr('title', img.title);
				$newimage.attr('alt',img.title);
				$newimage.css('display','none').addClass('current-image').removeClass('previous-image');
				
				//set the new image title
				if ((this.showImageCaption==1) || (this.showImageCaption==2)) {
					jQuery(this.$slideshow.find('.ifwsxgallery-image-caption')).text(img.title);
				}
				
				//now fading
				$newimage.fadeIn('slow', function(){
					if (ga.inImageFading) { 
						if ((ga.showImageCaption==2) && (img.title)) {
							ga.inImageFading = false; //imagefading is finished
							ga.showImageTitle(); 
						} else {
							ga.inImageFading = false;	
						}
					}
				});
				
				return this;
			},
						
			hideImageTitle: function(newimage, oldimage) {
				this.inImageTitleFading = true;
				var ga = this;
				
				var $cap = jQuery(this.$slideshow.find('.ifwsxgallery-image-caption'));
				var capposition = $cap.position();
				
				var newtop = $cap.outerHeight();
				$cap.animate({top: newtop}, 'normal', function(){
					oldimage.fadeOut('normal', function() {
						//fadeout first then fadein
						ga.buildNewImage(newimage);
						ga.removeImage(oldimage);
					});
				});
			},
			
			getNextIndex: function(idx) {
				var newIndex = ++idx;
				if (newIndex > this.data.length-1) {
					newIndex = 0;
				}
				return newIndex;
			},
			
			getPrevIndex: function(idx) {
				var newIndex = --idx;
				if (newIndex < 0) {
					newIndex = this.data.length-1;
				}
				return newIndex;
			},	
			
			getNextPageIndex: function(idx) {
				var newIndex = ++idx;
				if (newIndex > this.pageCount-1) 
					newIndex = 0;
				
				return newIndex;
			},
			
			getPrevPageIndex: function(idx) {
				var newIndex = --idx;
				if (newIndex < 0)
					newIndex = this.pageCount-1;
				
				return newIndex;
			},
			
			updateSelectedThumb: function(oldindex, newindex) {
				this.$thumbs.find('ul > li.selected').removeClass('selected').fadeTo('fast',this.thumbOpacity);
				var rel = 'ul > li > a[rel='+newindex+']';
				this.$thumbs.find(rel).parent('li').addClass('selected').fadeTo('fast',1);
				
				return this;
			},
			
			showLightbox: function(ga, xboxlink) {
				var lightbox = jQuery.ifwsxbox.init(ga, false).showXbox(xboxlink);
			}
			
		});
		
		jQuery.extend(this, defaults, settings);
		
		return this;
	};
})(jQuery);
