;(function(jQuery) {
	
	//static class functions
	jQuery.ifwsxbox = {
			
		init: function(gallery, addHandler) {
			//TODO to use more than once first search for the box...
			xbox = jQuery('body').find('#ifwsxbox');
			if (!xbox.attr('id')) jQuery('body').append('<div id="ifwsxbox"></div>');
			return jQuery('#ifwsxbox').ifwsxbox().initialize(gallery, addHandler);
		},
	
		 /** THIRD FUNCTION
		 * getPageSize() by quirksmode.com
		 *
		 * @return Array Return an array with page width, height and window width, height
		 */
		getPageSize: function() {
			var xScroll, yScroll;
			if (window.innerHeight && window.scrollMaxY) {	
				xScroll = window.innerWidth + window.scrollMaxX;
				yScroll = window.innerHeight + window.scrollMaxY;
			} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
				xScroll = document.body.scrollWidth;
				yScroll = document.body.scrollHeight;
			} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
				xScroll = document.body.offsetWidth;
				yScroll = document.body.offsetHeight;
			}
			var windowWidth, windowHeight;
			if (self.innerHeight) {	// all except Explorer
				if(document.documentElement.clientWidth){
					windowWidth = document.documentElement.clientWidth; 
				} else {
					windowWidth = self.innerWidth;
				}
				windowHeight = self.innerHeight;
			} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
				windowWidth = document.documentElement.clientWidth;
				windowHeight = document.documentElement.clientHeight;
			} else if (document.body) { // other Explorers
				windowWidth = document.body.clientWidth;
				windowHeight = document.body.clientHeight;
			}	
			// for small pages with total height less then height of the viewport
			if(yScroll < windowHeight){
				pageHeight = windowHeight;
			} else { 
				pageHeight = yScroll;
			}
			// for small pages with total width less then width of the viewport
			if(xScroll < windowWidth){	
				pageWidth = xScroll;		
			} else {
				pageWidth = windowWidth;
			}
			arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight);
			return arrayPageSize;
		},
	
		/**
		 / THIRD FUNCTION
		 * getPageScroll() by quirksmode.com
		 *
		 * @return Array Return an array with x,y page scroll values.
		 */
		getPageScroll: function () {
			var xScroll, yScroll;
			if (self.pageYOffset) {
				yScroll = self.pageYOffset;
				xScroll = self.pageXOffset;
			} else if (document.documentElement && document.documentElement.scrollTop) {	 // Explorer 6 Strict
				yScroll = document.documentElement.scrollTop;
				xScroll = document.documentElement.scrollLeft;
			} else if (document.body) {// all other Explorers
				yScroll = document.body.scrollTop;
				xScroll = document.body.scrollLeft;	
			}
			arrayPageScroll = new Array(xScroll,yScroll);
			return arrayPageScroll;
		}
	
	};
	
	var defaults = {
		wrapperBorder: 			10, //should be the same as in the css .ifwsxbox-image-wrapper{padding}
		controlPanelHeight: 	30,
		closeCaption: 			'',
		prevCaption: 			'',
		nextCaption: 			''			
	};
	
	//extend the fn for the methods
	jQuery.fn.ifwsxbox = function(settings) {
		
		jQuery.extend(this,{
			images: {},
			imageCount: 0,
			
			onClickHandler: function(e, xboxlink) {
				this.showXbox(xboxlink);
				e.preventDefault();
			},
			
			onOverlayClickHandler: function(e) {
				this.hideXbox();
				e.preventDefault();
			},
			
			onNextClickHandler: function(e) {
				this.showNext();
				e.preventDefault();
			},
			
			onPrevClickHandler: function(e) {
				this.showPrev();
				e.preventDefault();
			},
			
			initialize: function(gallery, addHandler) {
				var box = this;
				
				this.$slideshow = jQuery(gallery.find('.ifwsxgallery-slideshow-wrapper'));
				this.$thumbs = jQuery(gallery.find('.ifwsxgallery-thumbs'));

				if (addHandler) 
					jQuery(box.$slideshow.find('a.ifwsxgallery-largeimage')).click(function(e){
						box.onClickHandler(e, this); //,link);
					});
				
				jQuery(window).resize(function() {
					var pagesize = jQuery.ifwsxbox.getPageSize();
					var pagescroll = jQuery.ifwsxbox.getPageScroll();
					
					//var overlay = jQuery('#ifwsxbox').find('#ifwsxbox-overlay');
					//jQuery(overlay).css...
					jQuery(box.find('#ifwsxbox-overlay')).css({
						width: pagesize[0],
						height: pagesize[1]
					});

					var $wrapper = jQuery(box.find('#ifwsxbox-xbox-wrapper"'));
					//jQuery(wrapper).css({
					jQuery(box.find('#ifwsxbox-xbox-wrapper')).css({
						top:	pagescroll[1] + (pagesize[3] / 10),
						left:	pagescroll[0] + (pagesize[0] / 2) - ($wrapper.width() / 2)
					});
				});
				
				return this;
			},
			
			showImage: function(index,title,rel) {
				//get image
				//var image = jQuery(xboxlink).find('img');
				//now check if image already loaded 
				//var img = jQuery.ifwsxbox.getImage(index);
				var img = this.images[index];
				
				if (img && img.image) {
					this.appendNewImage(img);
				} else {
					this.buildNewImage(index,title,rel);
				}
				return this;
			},
			
			appendNewImage: function(img) {
				var $wrapper = jQuery(this.find('#ifwsxbox-image-wrapper'));
				//jQuery('#ifwsxbox-image-wrapper').prepend(jQuery(img.image));
				$wrapper.prepend(jQuery(img.image));
				
				var $img = jQuery($wrapper.find('img'));
								
				$img.addClass('ifwsxbox-xboximage').css({
					display: 'none'
				});
				
				this.resizeXboxWrapper($img);
				
				return this;
			},
			
			showNewImage: function(img) {
				var box = this;

				//add the caption
				var $caption = jQuery(this.find('.ifwsxbox-caption'));
				var $pcaption = jQuery($caption.find('p')); 
				if (!$pcaption) {
					$caption.append('<p>'+img.title+'</p>');
				} else {
					$pcaption.text(jQuery(img).attr('title'));
				}
				//fadein the image
				jQuery(img).fadeIn('slow', function() {
					box.showControlPanel(img);
				});
				
				return this;
			},
			
			buildNewImage: function(index,title,rel) {
				//var linkimage = jQuery(xboxlink).find('img');
				
				//var title = linkimage.attr('title');
				//var index = linkimage.attr('rel');
				this.imageCount++;
				
				var box = this;
				
				var img = {
					title:title,
					box:this,
					index:index
				};
			
				var image = new Image();
				var box = this;
				
				image.onload = function() {
					img.image = this;
					box.images[index] = img;
					box.appendNewImage(img);
				};
				
				image.rel = img.index;
				image.title = img.title;
				//image.src = xboxlink.attr('rel');
				image.src = rel;
				
				return this;
			},
			
			showNext: function() {
				var $currentimg = this.find('img');
				if ($currentimg) {
					var index = $currentimg.attr('rel');
					index++;
					$xboxlink = this.findLink(index);
					if ($xboxlink) {
						var index = $xboxlink.attr('rel');
						var title = $xboxlink.attr('title');
						var rel = $xboxlink.find('img').attr('rel');
						//this.showImage(index,title,rel);
						this.hideControlPanel(index,title,rel);
					}
				};
				
				return this;
			},
			
			showPrev: function() {
				var $currentimg = this.find('img');
				if ($currentimg) {
					var index = $currentimg.attr('rel');
					index--;
					$xboxlink = this.findLink(index);
					if ($xboxlink) {
						var index = $xboxlink.attr('rel');
						var title = $xboxlink.attr('title');
						var rel = $xboxlink.find('img').attr('rel');
						//this.showImage(index,title,rel);
						this.hideControlPanel(index,title,rel);
					}
				};
				
				return this;
			},
			
			findLink: function(index) {
				if (index<0) { //the last one in list
					var rel = 'ul:last-child > li:last-child > a:last-child'; 
				} else {
					var rel = '> ul > li > a[rel='+index+']';
				}
				var $link = jQuery(this.$thumbs.find(rel));
				
				if (!$link.attr('rel')) { //get the first image
					rel = 'ul:first-child > li:first-child > a:first-child';
					$link = jQuery(this.$thumbs.find(rel));
				}
				
				return $link;
			},
			
			showControlPanel: function(img) {
				var $controlpanel = jQuery(this.find('#ifwsxbox-control-panel'));
				var imgwidth = jQuery(img).width();
				var wrapperwidth = imgwidth + (2*this.wrapperBorder);
				$controlpanel.css('width',wrapperwidth);
				$controlpanel.show().animate({top: 0}, 'normal');
				
				return this;
			},

			hideControlPanel: function(index,title,rel) {
				var box = this;
				
				var $img = jQuery(this.find('#ifwsxbox-image-wrapper img'));
				jQuery(this.find('#ifwsxbox-control-panel')).animate({top: -this.controlPanelHeight},'fast',function() {
					jQuery(this).hide();
					$img.fadeOut('fast', function(){
						jQuery(this).remove();
						box.showImage(index,title,rel);
					});
				});
				
				return this;
			},
			
			resizeXboxWrapper: function(img) {
				var currentWrapperWidth = jQuery(this.find('#ifwsxbox-xbox-wrapper')).width();
				var currentWrapperHeight = jQuery(this.find('#ifwsxbox-xbox-wrapper')).height();
				var pagesize = jQuery.ifwsxbox.getPageSize();
				var pagescroll = jQuery.ifwsxbox.getPageScroll();
				
				var imgheight = jQuery(img).height();
				var imgwidth = jQuery(img).width();
				
				var wrappertop = pagescroll[1] + (pagesize[3] / 10) ;
				var wrapperleft = pagescroll[0] + (pagesize[0] / 2) - ((imgwidth+this.wrapperBorder) / 2);				
				var wrapperwidth = imgwidth+(2*this.wrapperBorder);
				var wrapperheight = imgheight+(2*this.wrapperBorder);
				
				var box = this;
				jQuery(this.find('#ifwsxbox-xbox-wrapper')).animate({top: wrappertop, left: wrapperleft, width: wrapperwidth, height: wrapperheight}, 'slow', function() {
					box.showNewImage(img);
				});
				
				return this;
			},
			
			showXbox: function(xboxlink) {
				var box = this;
				var rel = jQuery(xboxlink).attr('rel'); //the source of the original image
				var index = jQuery(xboxlink).find('img').attr('rel'); //the index of the image
				var title = jQuery(xboxlink).find('img').attr('title'); //the title of the image
				
				var pagesize = jQuery.ifwsxbox.getPageSize();
				var pagescroll = jQuery.ifwsxbox.getPageScroll();
				
				this.append('<div class="ifwsxbox-overlay" id="ifwsxbox-overlay"></div>');
				var $overlay = jQuery(this.find('#ifwsxbox-overlay'));
				//set size of overlay to pageheight and pagewidth
				$overlay.css({
					width: pagesize[0],
					height: pagesize[1]
				});
				$overlay.click(function(e) {
					box.onOverlayClickHandler(e);
				});
				
				this.append('<div id="ifwsxbox-xbox-wrapper" class="ifwsxbox-xbox-wrapper"></div>');
				var $wrapper = jQuery(this.find('#ifwsxbox-xbox-wrapper"'));
				$wrapper.append('<div id="ifwsxbox-image-wrapper" class="ifwsxbox-image-wrapper"></div>');
				
				this.generateControlPanel($wrapper);
			
				//center the wrapper and fadein
				$wrapper.css({
					top:	pagescroll[1] + (pagesize[3] / 10),
					left:	pagescroll[0] + (pagesize[0] / 2) - (($wrapper.width()+this.wrapperBorder) / 2)
				}).fadeIn('fast');
				
				$overlay.fadeTo('fast', 0.65, function() {
					box.showImage(index,title,rel);
				});
				
				return this;
			},
			
			generateControlPanel: function($wrapper) {
				var box = this;
				
				$wrapper.append('<div id="ifwsxbox-control-panel" class="ifwsxbox-control-panel"></div>');
				var	$controlpanel = jQuery(this.find('#ifwsxbox-control-panel"'));
				
				//set the css for the controlpanel
				$controlpanel.css({
					width: $wrapper.width(),
					height: this.controlPanelHeight,
					top: -this.controlPanelHeight
				});
				
				$controlpanel.append('<div class="ifwsxbox-caption"><p></p></div>');
				$controlpanel.append('<div class="ifwsxbox-controls"><a href="#" id="ifwsxbox-prev-link">'+this.prevCaption+'</a><a href="#" id="ifwsxbox-next-link">'+this.nextCaption+'</a><a href="#" id="ifwsxbox-close-link">'+this.closeCaption+'</a></div>');
				
				$controlpanel.find('#ifwsxbox-close-link').click(function(e) {
					box.onOverlayClickHandler(e);
				});
				
				$controlpanel.find('#ifwsxbox-next-link').click(function(e) {
					box.onNextClickHandler(e);
				});
				
				$controlpanel.find('#ifwsxbox-prev-link').click(function(e) {
					box.onPrevClickHandler(e);
				});
				return this;

			},
			
			hideXbox: function() {
				var box = this;
				jQuery(this.find('#ifwsxbox-xbox-wrapper')).fadeOut('fast', function() {
					jQuery(this).remove();
					jQuery(box.find('#ifwsxbox-overlay')).fadeOut('fast', function(){
						jQuery(this).remove();
						box.remove();
					});
				});
			}
			
		});
		
		//extend the defaults with the optional values
		jQuery.extend(this, defaults, settings);		
		
		return this;
	};
})(jQuery);
