var manualCarouselNS = {};

(function($){
	
	$.fn.extend({
		
		manualCarousel: function(options){
			
			var defaults = {
				width: 400,					//width of image
				height: 300,				//height of image
				animationSpeed: 1000		//speed of animation (fading)	(millisecond)
			};
			
			var options = $.extend(defaults, options);
			
			return this.each(function(){
				var obj = $(this);
				
				manualCarouselNS.activeIndex = 0;								//initial active index. Note: changing this index will not affect the first image to display but will affect the next or prev button				
				manualCarouselNS.images = $('div.image-container a img', obj);
				
				var prev = $('img.left-arrow', obj);
				var next = $('img.right-arrow', obj);
				var imageTitles = $('div.image-title > span', obj);
				var comments = $('div.comment > div', obj);
				$('div.comment div.comment-text:first-child').css('display','block');
				var imageAnchors = $('div.image-container > a', obj);
				
				
				imageAnchors.addClass('show');		//have to show all the anchors; otherwise, there'll be problem when resizing the images
				
				resizeImages(options);
				fillImagesWithSpace(options);
				
				imageAnchors.removeClass('show');	//remove class 'show' but it doesn't affect the first image (see css for more info)
				
				
				$('.image-container').css({
					width: options.width,
					height: options.height
				});
				
				
				//add z-index to each image so that they will appear on top of each other
				imageAnchors.each(function(index){
					$(this).css({
						'z-index' : index
					});
				});
				
				//add z-index to each image title so that they will appear on top of each other
				imageTitles.each(function(index){
					$(this).css({
						'z-index' : index + 2
					});
				});
				
				//add z-index to each comment so that it will appear on top of each other
				comments.each(function(index){
					$(this).css({
						'z-index' : index
					});
				});
				
				
				//align next button to be vertically middle of image-container
				next.css({
					top: (options.height - next.height()) / 2
				});
				
				//align prev button to be vertically middle of image-container
				prev.css({
					top: (options.height - prev.height()) / 2
				});
				
				
				//when click on next button ....
				next.click(function(){
					$('.loupe').css('display','none');
					var activeIndex = manualCarouselNS.activeIndex;
					
					if (imageAnchors.eq(activeIndex + 1).length == 1){	//if there's still image after current active image...
						activeIndex++;									//set active index to that image
					}
					else{												//otherwise....			
						activeIndex = 0;								//set active index to the first image
					}
					
					imageAnchors.fadeOut(options.animationSpeed);		//fade out image
					imageTitles.fadeOut(options.animationSpeed);		//fade out title
					comments.fadeOut(options.animationSpeed);			//fade out comment
					
					imageAnchors.eq(activeIndex).fadeIn(options.animationSpeed);	//fade in image
					imageTitles.eq(activeIndex).fadeIn(options.animationSpeed);		//fade in title
					comments.eq(activeIndex).fadeIn(options.animationSpeed);		//fade in comment
					
					manualCarouselNS.activeIndex = activeIndex;
				});
				
				
				//when click on prev button
				prev.click(function(){
					$('.loupe').css('display','none');
					var activeIndex = manualCarouselNS.activeIndex;
					
					if (activeIndex - 1 < 0){							//if it reaches the first image...
						activeIndex = imageAnchors.length - 1;			//set active index to the last image
					}
					else{												//otherwise...
						activeIndex--;									//set active index to the previous image
					}
					
					imageAnchors.fadeOut(options.animationSpeed);		//fade out image
					imageTitles.fadeOut(options.animationSpeed);		//fade out title
					comments.fadeOut(options.animationSpeed);			//fade out comment
					
					imageAnchors.eq(activeIndex).fadeIn(options.animationSpeed);	//fade in image
					imageTitles.eq(activeIndex).fadeIn(options.animationSpeed);		//fade in title
					comments.eq(activeIndex).fadeIn(options.animationSpeed);		//fade in comment
					
					manualCarouselNS.activeIndex = activeIndex;
				});
				
				obj.css({
					left: 134
				});
				
			});
			
		}
		
	});
	
	/*
	 * resize images so that it will fit inside image-container if bigger, and keep default size if smaller.
	 * this will maintain the aspect ratio of the image when resizing.
	 */
	var resizeImages = function(options){
		//get from namespace
		var images = manualCarouselNS.images;
		
		//get width & height of image
		var maxWidth = options.width;
		var maxHeight = options.height;

		
		images.each(function(index){
			
			if ($(this).width() > maxWidth){													//if image width > image-container width...
				$(this).css({'width': maxWidth});												//set image width = image-container width
				$(this).css({'height': 'auto'});												//resize image height by keeping image ratio
			}
			
			if ($(this).height() > maxHeight){													//if image height > image-container height...
			
				//note: if we resize the height of image and maintain image ratio,
				//the width of image can be in decimal value which will cause problem
				//when we call function fillImagesWithSpace() to add white space;
				//so this calculation will get the biggest INTEGER width of the image
				//to resize to when the height is bigger than the panel height.
				//We don't care if height is decimal or not because we only want the width
				//of each image to be EXACTLY THE SAME so that to fit perfectly inside
				//panel width.
				var intWidth = Math.floor(maxHeight * $(this).width() / $(this).height());		
				
				$(this).css({'width': intWidth});												//set image width = biggest INTEGER width that fit in the image-container
				$(this).css({'height': 'auto'});												//resize image height by keeping image ratio. We don't care if it's decimal or not.
			}
			
		});
	};



	/*
	 * fill images with white space (padding) so that all of the images appear as the same size.
	 * it add space (padding) so that the width and height of each image are exactly the same as those of image-container
	 */
	var fillImagesWithSpace = function(options){
		//get from namespace
		var images = manualCarouselNS.images;
		
		//get width & height of image from options
		var maxWidth = options.width;
		var maxHeight = options.height;;
		
		
		images
			.each(function(index){
			
				//calculate the space to add to image width
				var hSpace = maxWidth - $(this).width();
				
				if (hSpace > 0){									//if width of image and image-container is not the same...
				
					$(this).css({
						'padding-left': Math.floor(hSpace / 2),		//add padding-left to image
						'padding-right': Math.ceil(hSpace / 2)		//add padding-right to image
					});
				}
				
				
				//calculate the space to add to image height
				var vSpace = maxHeight - $(this).height();
				
				if (vSpace > 0){									//if height of image and image-container is not the same...
				
					$(this).css({
						'padding-top': Math.floor(vSpace / 2),		//add padding-top to image
						'padding-bottom': Math.ceil(vSpace / 2)		//add padding-right to image
					});
				}
				
			});
	};
	
})(jQuery);
