(function($j){
	
	Website.registerNamespace('Website.Lib');
	
	Website.Lib.LinkGallery = function(){};
	Website.Lib.LinkGallery.prototype = {
		
		/*
		 * Private attributes
		 */
		_linksSelector: null,
		_imageContainerSelector: null,
		_imageUrls: null,
		_preloadedImages: null,
		_listItemEls: null,
		_currentActiveItemEl: null,
		_imageContainerJObj: null,
		_currentImageJObj: null,
		_crossFadeImageJObj: null,
		//_loadingLayerJObj: null,
		_currentActiveIndex: null,
		_animationTimeout: null,
		_isCrossFading: null,
		_settings: null,
		
		
		/*
		 * Initialises the LinkGallery.
		 * All parameters req'd except settings
		 * 
		 */
		init: function(linksSelector, imageContainerSelector, imageUrls, settings){
			var self = this;
			self._isCrossFading = false;
			self._linksSelector = linksSelector;
			self._imageContainerSelector = imageContainerSelector;
			self._imageUrls = imageUrls;
			self._settings = $j.extend({
				activeClass: 'active',
				loaderClass: 'loader',
				animationSpeed: 5000,
				restartAnimationSpeed: 10000,
				fadeInSpeed: 1500
			}, settings);
			
			self._setElementPointers();
			
			// NEED TO PREVENT CLICK WHILE PRELOADING
			
			// Preload images
			//self._loadingLayerJObj.show();
			//return;
			var imageLoader = new ImagePreloader();
			imageLoader.initialise(
				self._imageUrls, 
				function(images, totalLoaded, totalErrored, totalAborted){
					self._preloadedImages = images;
					//self._loadingLayerJObj.fadeOut();
					self._setEvents();
					self._animate();
				}
			);
		},
		
		
		/*
		 * Set pointers to common elements used
		 * by the class
		 */
		_setElementPointers: function(){
			var self = this;
			
			// Get list items
			self._listItemEls = $j(self._linksSelector);
			if (self._listItemEls.length < 1){
				throw "Unable to find any items to rotate through."
			}
			
			if (self._listItemEls.length != self._imageUrls.length){
				throw "Number of items does not match number of images.";
			}
			
			// Get the index of the current active item
			// This may have been set by the server
			var index = $j(self._listItemEls).index( $j('li.' + self._settings.activeClass)[0] );
			if (index < 1){
				index = 0;
			}
			
			
			self._imageContainerJObj = $j(self._imageContainerSelector).eq(0);
			if (self._imageContainerJObj.length != 1){
				throw 'Unable to find image container';
			}
			
			self._currentImageJObj = $j('img', self._imageContainerJObj).eq(0);
			if (self._imageContainerJObj.length != 1){
				throw 'Unable to find image within the image container';
			}
			
			self._currentImageJObj.css({
				zIndex: 0
			});
			
			// Add cross fade image
			self._crossFadeImageJObj = $j('<img />');
			self._crossFadeImageJObj
				.css({
					position: 'absolute',
					top: 0,
					left: 0,
					zIndex: 1
				})
				.appendTo(self._imageContainerJObj)
				.hide();
			
			
			// Add loading layer
			//self._loadingLayerJObj = $j('<div class="' + self._settings.loaderClass + '"></div>');
			//self._loadingLayerJObj
			//	.css({
			//		position: 'absolute',
			//		top: 0,
			//		left: 0,
			//		width: '100%',
			//		height: self._imageContainerJObj.height() + 'px',
			//		zIndex: 2,
			//		opacity: 0.6
			//	})
			//	.appendTo(self._imageContainerJObj)
			//	.hide();
			
			self._setActiveItem(index);
		},
		
		
		/*
		 * Sets interactive events, e.g. clicking on a link
		 */
		_setEvents: function(){
			var self = this;
			
			// Stop any link firing
			//$j('a', self._listItemEls).click(function(event){
			//	event.preventDefault();
			//});
			
			// Set click event on each list item
			//$j(self._listItemEls).click(function(event){
			//	self._onItemClick(event);
			//});
		},
		
		
		/*
		 * Fires when an item is clicked
		 */
		_onItemClick: function(event){
			var self = this;
			event.preventDefault();
			self._stopAnimation();
			
			// Set the current item to be the one item
			var index = $j(self._listItemEls).index( event.currentTarget );
			self._setActiveItem(index);
			
			self._animate(self._settings.restartAnimationSpeed);
		},
		
		
		/*
		 * Sets the current active item
		 */
		_setActiveItem: function(index){
			var self = this;
			if (index < 0 || index >= self._listItemEls.length){
				index = 0;
			}
			self._currentActiveIndex = index;
			self._currentActiveItemEl = self._listItemEls[self._currentActiveIndex];
			$j(self._listItemEls).removeClass(self._settings.activeClass);
			$j(self._currentActiveItemEl).addClass(self._settings.activeClass);
			
			if (self._preloadedImages == null){
				return;
			}
			
			if (self._isCrossFading){
				self._currentImageJObj.attr('src', self._crossFadeImageJObj.attr('src'));
			}
			
			if (self._currentImageJObj.attr('src') == self._preloadedImages[self._currentActiveIndex].src){
				self._crossFadeImageJObj
					.stop()
					.css({ opacity: 1 })
					.hide();
				return;
			}
			
			self._isCrossFading = true;
			self._crossFadeImageJObj
				.stop()
				.css({ opacity: 1 })
				.hide()
				.attr('src', self._preloadedImages[self._currentActiveIndex].src)
				.fadeIn(
					self._settings.fadeInSpeed,
					function(){
						// Swap images over
						self._isCrossFading = false;
						self._currentImageJObj.attr('src', self._crossFadeImageJObj.attr('src'));
						if ( self._currentImageJObj.parent()[0].tagName == 'A' ){
							var relatedAnchor = $j('a', self._listItemEls[self._currentActiveIndex]);
							if (relatedAnchor.length > 0){
								self._currentImageJObj.parent().attr('href', relatedAnchor.attr('href'));
							}
						}
						self._crossFadeImageJObj.hide();
					}
				);
			
		},
		
		
		/*
		 * Kick starts off the animation
		 */
		_animate: function(animationSpeed){
			var self = this;
			
			if (typeof animationSpeed == "undefined"){
				animationSpeed = self._settings.animationSpeed;
			}
			
			self._animationTimeout = setTimeout(function(){
				self._currentActiveIndex++;
				self._setActiveItem(self._currentActiveIndex);
				self._animate();
			}, animationSpeed);
		},
		
		
		/*
		 * Stops the animation
		 */
		_stopAnimation: function(){
			var self = this;
			clearTimeout(self._animationTimeout);
		}
		
		
	};
	
	
})(jQuery);

