﻿/**
 * This is the rotation image slider with reflections.
 * 
 * @author Pexeto
 * http://pexeto.com/
 */

(function($) {
	
	 $.fn.slider = function(options) {
		 
		 var options = $.extend({
		 animationSpeed : 400, //this is the animation speed
		 wrapperWidth:1000,  //this is the width of the div that contains all the images
		 imageWidth:400,   //this is the width of a single image
		 widthToReduce:60,
		 smallTop:55,
		 originalTop:40
		 }, options);
		 
		 var values={
				// DO NOT CHANGE THESE VALUES:
				 currentLeft:0,
				 previousLeft:0,
				 nextLeft:0,
				 smallWidth:0,
				 divNumber:0,
				 imageHolders:[],
				 images:[],
				 reflections:[],
				 reflectionImages:[],
				 marginLeft:-60
		 };
		  
		 return this.each(function(settings) {
			 
			 var divArray=$.makeArray($(this).find('.image_holder'));
			 values.divNumber=divArray.length;
			 
			//do the initial calculations for positioning images
			 values.currentLeft=options.wrapperWidth/2-options.imageWidth/2;
			 
			 values.previousLeft=values.currentLeft-((options.imageWidth-options.widthToReduce)/2)+30;
			 values.nextLeft=values.currentLeft+options.imageWidth-(options.imageWidth-options.widthToReduce)/2-30;
			 values.smallWidth=options.imageWidth-options.widthToReduce;
			 values.imageHolders=$(this).find(('div.image_holder'));
			 values.images=$(this).find(('div.image_holder img.slider_img'));
			 
			 var currentImage=1;
			 
			 //append the transparent hovers to all the images:
			 $('<div class="reflect"><div class="reflect_gradient"></div></div>').insertAfter($(this).find('div.image_holder img'));
			 values.reflections=$(this).find(('div.image_holder div.reflect'));
			 
			//set the reflections
			 values.imageHolders.each(function(i){				 
				 var img = new Image();
				 img.onload = function() {
				 	Pixastic.process(img, "flipv");
				 	values.reflectionImages[i]=img;
					if(i==values.imageHolders.length-1){
						$.fn.slider.positionImages($(this),values, options,currentImage);
				 	}

				 };
				 $(values.reflections[i]).append(img);
				 img.src = $(values.images[i]).attr('src');
			 });
			
			 
		 });	 
	 };
	 
	 /**
	  * Initially position the images.
	  */
	 $.fn.slider.positionImages = function(wrapper,values,options,current) {
		 
		 //position all the images on the place of the central one
		 values.imageHolders.css({left:values.currentLeft, top:options.smallTop, zIndex:1}).hide();
		 values.images.css({width:values.smallWidth+'px', opacity:'hide'});
		 values.images.mouseover(function(){
			$(this).css({cursor:'pointer'}); 
		 });
		 
		 //position the top images
		 values.imageHolders.each(function(i){	
			 		 
			 switch(i){
			 case(current-1):
				 $(this).css({left:values.previousLeft, zIndex:10}).show().bind('click', {options:options, values:values, wrapper:wrapper},$.fn.slider.clickLeft);
			     $(values.images[i]).animate({opacity:0.5},0);
				 break;
			 case(current):
				 $(this).css({left:values.currentLeft, zIndex:20, top:options.originalTop}).show().find('img').css({width:options.imageWidth,opacity:1});
			     $(values.images[i]).mouseover(function(){
					$(this).css({cursor:'default'}); 
				 });
			 	break;
			 case(current+1):
				 $(this).css({left:values.nextLeft, zIndex:10}).show().bind('click', {options:options, values:values, wrapper:wrapper}, $.fn.slider.clickRight);
			     $(values.images[i]).animate({opacity:0.5},0);
			     $(values.reflections[i]).css({marginLeft:values.marginLeft});
			 break;
			 case(current-2):
				 $(this).css({left:values.previousLeft-20});
			 	 $(values.reflections[i]).css({marginLeft:values.marginLeft});
			 break;
			 case(current+2):
				 $(this).css({left:values.nextLeft+20});
			 break;
			 }
		 });
		 
		 $('#rotation_slider').css({visibility:'visible'});
		 
	};
	
	/**
	 * Gets the next image. If it reaches the end of the images, returns the first one
	 */
	$.fn.slider.getNextImage = function(current, step, divNumber) {
		if ((step + current) <= (divNumber - 1)) {
			return step + current;
		} else {
			var res = divNumber - (step + current);
			if (res >= 0) {
				return res;
			} else {
				return (res * (-1));
			}
		}

	};
	
	/**
	 * Gets the next image. If it reaches the end of the images, returns the first one
	 */
	$.fn.slider.getPreviousImage = function(current, step, divNumber) {
		if (current-step>=0) {
			return current-step;
		} else {
			return divNumber+current-step;
		}
	};
	
	/**
	 * This is the function which is executed after clicking on an image from the right
	 */
	$.fn.slider.clickRight = function(event){
		
		var options=event.data.options,
		 values=event.data.values,
		 divNumber=values.divNumber,
		 currentClicked=Number($('#'+$(this).parent().attr('id')+' .image_holder').index(this)),
		 currentImage=$.fn.slider.getPreviousImage(currentClicked,1,divNumber);
		
		//hide the most left image
		var img_index=$.fn.slider.getPreviousImage(currentImage,1,divNumber);
		$(values.imageHolders[img_index]).animate({opacity:'hide'},100);
		$(values.imageHolders[img_index]).animate({left:values.previousLeft+20},1000);
	//	$(values.reflections[img_index]).css({marginLeft:0});
		
		//show the image which will be in the right
		img_index=$.fn.slider.getNextImage(currentImage,2,divNumber);
		$.fn.slider.showNextImage(values, options, values.nextLeft, img_index, values.marginLeft);
		
		//move the old current image to the left
		$.fn.slider.removeCurrentImage(values, options, values.previousLeft, currentImage, 0);
		
		//move the right image to the center- now this is the current image
		img_index=$.fn.slider.getNextImage(currentImage,1,divNumber);
		$.fn.slider.showCurrentImage(values, options, img_index, values.marginLeft);	
		
		//prepare the next image to be shown on the right side for the next click
		img_index=$.fn.slider.getNextImage(currentImage,3,divNumber);
		$(values.imageHolders[img_index]).css({left:values.nextLeft-20, top:options.smallTop, zIndex:1});
		
		//unbind the click handlers for the old left and right images and bind the click handlers for the new ones
		$(this).unbind();
		img_index=$.fn.slider.getNextImage(currentImage,2,divNumber);
		$(values.imageHolders[img_index]).bind('click', {options:options, values:values}, $.fn.slider.clickRight);
		
		img_index=$.fn.slider.getPreviousImage(currentImage,1,divNumber);
		$(values.imageHolders[img_index]).unbind();
		$(values.imageHolders[currentImage]).bind('click', {options:options, values:values}, $.fn.slider.clickLeft);
	
	};
	
	/**
	 * This is the function which is executed after clicking on an image from the left.
	 */
	$.fn.slider.clickLeft = function(event){
	
		var options=event.data.options,
		 values=event.data.values,
		 divNumber=values.divNumber,
		 currentClicked=Number($('#'+$(this).parent().attr('id')+' .image_holder').index(this)),
		 currentImage=$.fn.slider.getNextImage(currentClicked,1,divNumber);
		
		//move the left image to the center, now this is the current image
		var img_index=$.fn.slider.getPreviousImage(currentImage,1,divNumber);
		$.fn.slider.showCurrentImage(values, options, img_index,0);
		
		//hide the most right image
		img_index=$.fn.slider.getNextImage(currentImage,1,divNumber);
		$(values.imageHolders[img_index]).animate({opacity:'hide'},100);
		$(values.imageHolders[img_index]).animate({left:values.nextLeft-30},1000);
		
		
		//move the old current image to the right
		$.fn.slider.removeCurrentImage(values, options, values.nextLeft, currentImage, values.marginLeft);
		
		//show the new left image
		img_index=$.fn.slider.getPreviousImage(currentImage,2,divNumber);
		$.fn.slider.showNextImage(values, options, values.previousLeft, img_index, 0);
		
		
		//prepare the next left image to be shown
		img_index=$.fn.slider.getPreviousImage(currentImage,3,divNumber);
		$(values.imageHolders[img_index]).css({left:values.previousLeft+30, top:options.smallTop, zIndex:1});
		
		
		//unbind the click handlers for the old left and right images and bind the click handlers for the new ones
		$(values.imageHolders[currentImage]).bind('click', {options:options, values:values}, $.fn.slider.clickRight);
		img_index=$.fn.slider.getNextImage(currentImage,1,divNumber);
		$(values.imageHolders[img_index]).unbind('click');
		
		$(this).unbind();
		img_index=$.fn.slider.getPreviousImage(currentImage,2,divNumber);
		$(values.imageHolders[img_index]).bind('click', {options:options, values:values}, $.fn.slider.clickLeft);
		
	};
	
	/**
	 * Shows the new current image.
	 */
	$.fn.slider.showCurrentImage=function(values, options, img_index, margin){
		//$(values.images[img_index]).css({width:options.imageWidth+'px', marginLeft:margin});
		$(values.images[img_index]).animate({opacity:1, marginLeft:0,width:options.imageWidth},options.animationSpeed);
		$(values.imageHolders[img_index]).animate({left:values.currentLeft, top:options.originalTop}, options.animationSpeed).css({zIndex:20});
		$(values.images[img_index]).animate({opacity:1},200);
		var reflectionSpeed=(options.imageWidth+20)*options.animationSpeed/options.imageWidth;
		$(values.reflections[img_index]).animate({marginLeft:0});
		$(values.images[img_index]).mouseover(function(){
			$(this).css({cursor:'default'}); 
		 });
	};
	
	/**
	 * Removes the old current image and places it to the lefr/right.
	 */
	$.fn.slider.removeCurrentImage=function(values, options, left, currentImage, margin){
		$(values.imageHolders[currentImage]).animate({left:left, top:options.smallTop},options.animationSpeed-50).css({zIndex:10});
		$(values.images[currentImage]).animate({opacity:0.5,width:values.smallWidth+'px'}, options.animationSpeed);
		$(values.reflections[currentImage]).animate({marginLeft:margin});
		$(values.images[currentImage]).mouseover(function(){
			$(this).css({cursor:'pointer'}); 
		 });
	};
	
	/**
	 * Shows the next image.
	 */
	$.fn.slider.showNextImage=function(values, options, left, img_index, margin){
		$(values.imageHolders[img_index]).animate({opacity:'show'},0);
		//$(values.images[img_index]).animate({opacity:0.4});
		$(values.imageHolders[img_index]).animate({left:left, top:options.smallTop},options.animationSpeed).css({zIndex:10});
		$(values.images[img_index]).css({width:values.smallWidth+'px'});
		$(values.images[img_index]).animate({opacity:0.5});
		$(values.reflections[img_index]).css({marginLeft:margin});
	};
	
	
})(jQuery);





