/*
 * bookSlider 0.1
 *
 * A slider that simulates the effect of passing pages as you would do
 * it in a book.
 *
 * Images must overlap few pixels in order to make the flip action more realistic,
 * this must be taken into account when using a landscape image splitted in two parts.
 *
 * ninthcircle.eu
 *
 */

(function($) {

	jQuery.fn.bookSlider = function(o) {
		
		return this.each(function() {
			new $bs(this, o);
        });
	};
	
	var defaults	= {
		pageWidth			: 550, // 283,
		pageHeight			: 690, // 425,
		turnPageDuration	: 150
	};
	
	jQuery.bookSlider = function(e, o) {
		this.options    	= $.extend({}, defaults, o || {});
		this.list			= null;
		this.numberOfPages	= 0;
		this.animating		= false;
		this.isCreated		= true;

		this.list = $(e).find('>ul,>ol,div>ul,div>ol');
				
		var self = this;
		var li = this.list.children('li');
		this.numberOfPages = li.size();
		
		if (this.numberOfPages > 0) {
			var i = 1;
			li.each(function() {
				self.format(this, i++);
			});
		};
		
		return this;
	};
	
	// Create shortcut for internal use
    var $bs = jQuery.bookSlider;

    $bs.fn = $bs.prototype = {
        bookSlider: '0.0.1'
    };

    $bs.fn.extend = $bs.extend = jQuery.extend;
    
    $bs.fn.extend({
        	
    	format				: function(e, i) {
			var $e = $(e);
			var $i = $e.find('img')

			/* Set the position depending where the page is even or odd */
			var _left = 0;
			var _esPar = !(i%2);
			
			if( _esPar ) _left = this.options.pageWidth;
			
			/* Set css attributes of the <li> element */
			$e.css({
				'position'	: 'absolute',
				'left'		: _left,
				'width'		: '0px',
				'height'	: '0px'
			});
			
			/* Inside the <li> there should be an image, set some attributes, otherwise
			   image is not displayed, À? */
			$i.css({
				'position'	: 'relative'
			});
			
			/* We will only see the first two pages */
			if ( i>2 ) {
				$i.css({
					'left'			: '0px',
					'width'			: '0px'
				});
			} else {
				$i.css({
					'width'			: this.options.pageWidth + 'px',
					'height'		: this.options.pageHeight + 'px'
				});
			};
			
			var self = this;
			
			/* Add a link wrapper to every image but the first one and the last one,
			   and bind a click event to allow navigation */
			if( i == 1) $i.wrap('<a></a>');
			if( i == this.numberOfPages ) $i.wrap('<a></a>');
			if( _esPar && i < this.numberOfPages ) {
				$e.bind("click", function() {
					self.next(this);
				});
				$i.wrap('<a href="javascript:void(0);"></a>');
			} else if( !_esPar && i>1 ) {
				$e.bind("click", function() {
					self.previous(this);
				});
				$i.wrap('<a href="javascript:void(0);"></a>');
			}
			
        	$e.attr('pageNumber', i);
			return $e;
        },
        
        /**
         * Go to the next page.
         *
         * @name next
         * @type undefined
         * @cat Plugins/bookSlider
         */
        next					: function(e) {
        	/* It is assumed the next func will always be called from a even (right) page,
        	   and only two images are visible at a time, that is, all have width=0 but two */
			if( this.animating ) return;

			/* Arrange and set every image visibility */
        	$(e).css('z-index',4);
        	this.nextEvenPage(e).css('z-index', 3);
        	this.nextEvenPage(e).find('img').css({
        		'left'	: '0px',
        		'width'			: this.options.pageWidth + 'px',
        		'height'		: this.options.pageHeight + 'px',
        		'opactiy'		: 1
        	});
        	
			this.previousOddPage(e).css('z-index',1);
			        	
			this.nextOddPage(e).find('img').css({
        		'left'			: this.options.pageWidth + 'px',
        		'width'			: '0px',
				'height'		: this.options.pageHeight + 'px',
				'opacity'		: 0
        	});
        	this.nextOddPage(e).css('z-index', 2);

        	
        	this.fadeOutRightPage(e);
        },

        /**
         * Go to the previous page.
         *
         * @name prev
         * @type undefined
         * @cat Plugins/bookSlider
         */
        previous				: function(e) {
			
			if( this.animating ) return;
			
        	$(e).css('z-index',2);
        	this.previousOddPage(e).css('z-index', 1);
        	this.previousOddPage(e).find('img').css({
        		'left'			: '0px',
        		'width'			: this.options.pageWidth + 'px',
        		'height'		: this.options.pageHeight + 'px',
        		'opacity'		: 1
        	});
        	
        	this.nextEvenPage(e).css('z-index', 3);
        	
			this.previousEvenPage(e).find('img').css({
        		'left'			: '0px',
        		'width'			: '0px',
				'height'		: this.options.pageHeight + 'px',
				'opactiy'		: 0
        	});
			this.previousEvenPage(e).css('z-index',4);
        	
        	this.fadeOutLeftPage(e);
        },
        
        fadeOutRightPage		: function(page) {
        	var rightPageDidFadeOut = null;
        	var self = this;
        	
            rightPageDidFadeOut = function() {
            	self.fadeInLeftPage(self.nextPage(page));
            };
            
			setTimeout(rightPageDidFadeOut, this.options.turnPageDuration/2);

            this.animating = true;
            
            $(page).find('img').animate({
            	width	: '0px',
                height	: this.options.pageHeight + 'px',
                opacity	: 0
            }, this.options.turnPageDuration);
        },
        
        fadeOutLeftPage			: function(page) {
        	var leftPageDidFadeOut = null;
        	var self = this;
        	
        	leftPageDidFadeOut = function() {
        		self.fadeInRightPage(self.previousPage(page));
        	};
        	
        	setTimeout(leftPageDidFadeOut, this.options.turnPageDuration/2);

			this.animating = true;
			
			$(page).find('img').animate({
            	left	: this.options.pageWidth + 'px',
            	width		: '0px',
                height		: this.options.pageHeight + 'px',
                opacity		: 0
            }, this.options.turnPageDuration);
        },
        
        fadeInLeftPage			: function(page) {
        	var self = this;
        	
        	page.find('img')
        		.animate({
        			width	: this.options.pageWidth + 'px',
        			opacity : 1
        		}, { queue: false, duration: this.options.turnPageDuration })
        		.animate( { left: '0px'}, this.options.turnPageDuration, function() {
        			/* Se the underneath's page to width=0 to make sure only two pages are
        			   visible at a time */
        			self.animating = false;
        			self.previousOddPage(page).find('img').css({
        				'left'			: self.options.pageWidth + 'px',
        				'width'			: '0px',
        				'height'		: self.options.pageHeight + 'px'
        			});
        		});
/*				
			page.find('img').animate({
				left	: '0px'
			}, (this.options.turnPageDuration*10)/(this.options.pageWidth));*/
        },
		fadeInRightPage		: function(page) {
			var self = this;
			page.find('img')
				.animate({
					left	: '0px',
					width	: this.options.pageWidth + 'px',
					height	: this.options.pageHeight + 'px',
					opacity : 1
				}, this.options.turnPageDuration, function() {
					self.animating = false;
					self.nextEvenPage(page).find('img').css({
						'left'			: '0px',
						'width'			: '0px',
						'height'		: self.options.pageHeight + 'px'
					});
				});
        },
        
        pageRelativeTo			: function(page, offset) {
        	return $(page).parent().find("li[pageNumber='" + (this.pageNumber(page)+offset) + "']");
        },
        nextPage				: function(page) {
        	return this.pageRelativeTo(page, 1);
        },
        nextOddPage				: function(page) {
        	return this.pageRelativeTo(page, 1+(this.pageNumber(page) %2 ) );
        },
        nextEvenPage			: function(page) {
        	return this.pageRelativeTo(page, 2-(this.pageNumber(page) %2 ) );
        },
        previousPage			: function(page) {
        	return this.pageRelativeTo(page, -1);
        },
        previousOddPage			: function(page) {
        	return this.pageRelativeTo(page, -1-(this.pageNumber(page) %2 ) );
        },
        previousEvenPage		: function(page) {
        	return this.pageRelativeTo(page, -2+(this.pageNumber(page) %2 ) );
        },
        pageNumber				: function(page) {
        	return parseInt($(page).attr('pageNumber'));
        },
        isCreated				: function() {
        	return this.isCreated;
        }
	});
	
	
})(jQuery);
