(
	function ($) 
	{
		var methods = 
		{
			init : function(options) 
			{	
			  	
				requestDataCallback = (options) && (options.requestDataCallback) ? options.requestDataCallback : null;

				selectPageCallback = (options) && (options.selectPageCallback) ? options.selectPageCallback : null;
				
				container = this;
			  	
			  	this.prepend('<div></div>');
			  	this.prepend('<div></div>');
			  	this.prepend('<div></div>');
				
			  	page1 = $(this.children('div')[0]);
			  	page1.css('display', 'block');
			  	page1.css('position', 'relative');
			  	page1.css('overflow', 'hidden');
			  	page1.css('width', this.width()/2 + 'px');
			  	page1.css('height', this.height() + 'px');
			  	
			  	page2 = $(this.children('div')[1]);
			  	page2.css('display', 'block');
			  	page2.css('position', 'relative');
			  	page2.css('overflow', 'hidden');
			  	page2.css('width', this.width()/2 + 'px');
			  	page2.css('height', this.height() + 'px');
			  	page2.css('margin-top', (-1 * this.height()) + 'px');
			  	page2.css('margin-left', this.width()/2 + 'px');
			  	
			  	cover = $(this.children('div')[2]);
			  	cover.css('display', 'none');
			  	cover.css('position', 'relative');
			  	cover.css('overflow', 'hidden');
			  	cover.css('width', this.width()/2 + 'px');
			  	cover.css('height', this.height() + 'px');
			  	cover.css('margin-top', (-1 * this.height()) + 'px');
			  	cover.css('margin-left', '0px');
			  	
			  	this.click(
						function(e) {
							$(this).simpleBooklet('_handleClick', e, requestDataCallback, selectPageCallback);
						}
				);
				
			}

			,
			getImage : function(index)
			{
				objectImage = null;
				
				if (index >= 0)
				{
					objectImage = $(this.children('div')[3]).children()[index];
				}
				
				return objectImage ? $(objectImage) : null ;				
			}

			,
			
			getVisibleImage : function()
			{
				return this.simpleBooklet('getImage', this.simpleBooklet('getVisiblePageIndex'));
			}

			,
			
			getVisiblePageIndex : function()
			{
				if ($(this.children('div')[3]).children('.bookletVisible__').length > 0)
				{
					children = $(this.children('div')[3]).children('img');
					for (i = 0; i < children.length; i++)
						{
							if ($(children[i]).hasClass('bookletVisible__'))
								{
									return i;
								}
						}
				}
				
				return -1;
			}
			
			,
			
			getPageCount: function()
			{
				return $(this.children('div')[3]).children('img').length;
			}
			
			,
			
			selectPage : function (index, requestDataCallback, selectPageCallback)
			{
				// check index
				if ((index < 0) || (index > (this.simpleBooklet('getPageCount') - 1)))
				{
					return;
				}
				
				// get visible image
				container = this;

				// display the visible image
				var targetImage = $($(this.children('div')[3]).children('img')[index]);
				
				// request more data if needed
				if ((typeof(targetImage.attr('src')) == 'undefined')&&(requestDataCallback))
				{
					requestDataCallback(index);
					return;
				}
				
				// remove visible marker
				visibleImageIndex = this.simpleBooklet('getVisiblePageIndex');
				visibleImage = this.simpleBooklet('getVisibleImage');
				
				isLTR = (visibleImageIndex < index);

				if (visibleImage)
				{
					$(visibleImage).removeClass('bookletVisible__');
				}
				targetImage.addClass('bookletVisible__');
				
				// reload images
				if (isLTR)
				{
					this.simpleBooklet('flipRTL', $(visibleImage), $(targetImage));
				}
				else
				{	
					this.simpleBooklet('flipLTR', $(visibleImage), $(targetImage));
				}
				
				// invoke selectPageCallback
				if (selectPageCallback)
				{
					selectPageCallback.apply( this, [index] );
				}
			}
			
			,
			
			_handleClick : function (e, requestDataCallback, selectPageCallback)
			{
				
				// check busy
				if (this.hasClass('bookletBusy__'))
				{
					return;
				}

				// proceed
				_rangeMin = this.offset().left;
				_rangeMax = this.offset().left + this.width();
				pageIndex = this.simpleBooklet('getVisiblePageIndex');
				
				if (e.pageX > (_rangeMin + _rangeMax)/2)
				{
					if (this.simpleBooklet('getVisiblePageIndex') + 1 <= this.simpleBooklet('getPageCount') - 1)
					{
						this.simpleBooklet('selectPage', pageIndex + 1, requestDataCallback, selectPageCallback);
					}
				}
				else
				{
					if (this.simpleBooklet('getVisiblePageIndex') - 1 >= 0)
					{
						this.simpleBooklet('selectPage', pageIndex - 1, requestDataCallback, selectPageCallback);
					}
				}
				
				return;
			}
			
			,

			_refreshLeft : function (targetImage)
			{
				// get right page
				pageLeft = $(this.children('div')[0]);
				pageLeft.empty();
				
				// perform display
				imageLeft = targetImage.clone();
				imageLeft.appendTo(pageLeft);
				imageLeft.css('position', 'relative');
				pageLeft.css('display', 'block');

				if (imageLeft.width() == 0)
				{
					imageLeft.width(targetImage[0].naturalWidth);
					imageLeft.height(targetImage[0].naturalHeight);
				}					
				fillAndCenter(imageLeft[0], this[0]);

				imageLeft.css('display', 'block');
				
				if (this.simpleBooklet('getVisiblePageIndex') > 0)
				{
					imageLeft.css('cursor', 'pointer');
				}
			}

			,

			_refreshRight : function (targetImage)
			{
				// get right page
				pageRight = $(this.children('div')[1]);
				pageRight.empty();
				
				// perform display
				imageRight = targetImage.clone();
				imageRight.appendTo(pageRight);
				imageRight.css('position', 'relative');
				pageRight.css('display', 'block');

				if (imageRight.width() == 0)
				{
					imageRight.width(targetImage[0].naturalWidth);
					imageRight.height(targetImage[0].naturalHeight);
				}				
				fillAndCenter(imageRight[0], this[0]);

				imageRight.css('left', (0 - imageRight.width()/2) + 'px');
				imageRight.css('display', 'block');
				
				if (this.simpleBooklet('getVisiblePageIndex') < this.simpleBooklet('getPageCount') - 1)
				{
					imageRight.css('cursor', 'pointer');
				}
			}
			
			,
			
			flipRTL : function (oldImage, targetImage)
			{
				this.simpleBooklet('_easeRightRTL', oldImage, targetImage);
			}
			
			,
			
			_easeRightRTL : function (oldImage, targetImage)
			{
				// block clicks
				this.addClass('bookletBusy__');
				
				this.simpleBooklet('_refreshRight', targetImage);
				pageRight = $(this.children('div')[1]);
				container.simpleBooklet('_refreshRight', targetImage);
				
				if (oldImage.length > 0)
				{
					// initialize cover
					cover = $(this.children('div')[2]);
					coverImage = oldImage.clone();
					coverImage.appendTo(cover);
					cover.css('width', pageRight.width() + 'px');
					cover.css('left', pageRight.width() + 'px');
					
					cover.css('display', 'block');
					coverImage.css('position', 'relative');
					coverImage.css('display', 'block');
					fillAndCenter(coverImage[0], this[0]);
					coverImage.css('left', (0 - coverImage.width()/2) + 'px');
					
					// flip cover
					container = this;
					cover.fadeOut(150);
					coverImage.animate
					(
						{
							left: [0 - coverImage.width(), 'easeOutCubic']
						},
						{
							duration: 150, 
							queue: false,
							complete: function() {
								coverImage.remove();
								cover.css('display', 'none');
								container.simpleBooklet('_easeLeftRTL', oldImage, targetImage);
							}
						}
					);
				}
				else
				{
					this.simpleBooklet('_refreshRight', targetImage);
					container.simpleBooklet('_easeLeftRTL', oldImage, targetImage);
				}
			}
			
			,
			
			_easeLeftRTL : function (oldImage, targetImage)
			{
				pageLeft = $(this.children('div')[0]);
				pageLeft.empty();
				
				if (oldImage.length > 0)
				{
					// initialize cover
					cover = $(this.children('div')[2]);
					coverImage = targetImage.clone();
					coverImage.appendTo(cover);
					cover.css('width', pageLeft.width() + 'px');
					cover.css('left', 0);
					
					cover.css('display', 'block');
					coverImage.css('position', 'relative');
					coverImage.css('display', 'block');
					fillAndCenter(coverImage[0], this[0]);
					coverImage.css('left', pageLeft.width() + 'px');
					
					
					// flip cover
					container = this;
					cover.fadeOut(1);
					cover.fadeIn(150);
					pageLeft.fadeOut(
						{
						   duration: 150,
						   queue: false
						}
					);
					coverImage.animate
					(
						{
							left: [pageLeft.width() - (coverImage.width()/2), 'easeOutCubic']
						},
						{
							duration: 150, 
							queue: false,
							complete: function() {
								coverImage.remove();
								cover.css('display', 'none');
								container.simpleBooklet('_refreshLeft', targetImage);
								container.removeClass('bookletBusy__');
							}
						}
					);
				}
				else
				{
					container.simpleBooklet('_refreshLeft', targetImage);
					container.removeClass('bookletBusy__');
				}
			}

			,
			
			flipLTR : function (oldImage, targetImage)
			{
				this.simpleBooklet('_easeLeftLTR', oldImage, targetImage);
			}
			,
			
			_easeLeftLTR : function (oldImage, targetImage)
			{
				// block clicks
				this.addClass('bookletBusy__');
				
				
				this.simpleBooklet('_refreshLeft', targetImage);
				pageLeft = $(this.children('div')[0]);
				container.simpleBooklet('_refreshLeft', targetImage);
				
				if (oldImage.length > 0)
				{
					// initialize cover
					cover = $(this.children('div')[2]);
					coverImage = oldImage.clone();
					coverImage.appendTo(cover);
					cover.css('width', pageLeft.width() + 'px');
					cover.css('left', 0);
					
					cover.css('display', 'block');
					coverImage.css('position', 'relative');
					coverImage.css('display', 'block');
					
					fillAndCenter(coverImage[0], this[0]);
					coverImage.css('left', pageLeft.width() - coverImage.width()/2 );
					
					// flip cover
					container = this;
					
					cover.fadeOut(150);
					coverImage.animate
					(
						{
							left: [pageLeft.width(), 'easeOutCubic']
						},
						{
							duration: 150, 
							queue: false,
							complete: function() {
								coverImage.remove();
								cover.css('display', 'none');
								container.simpleBooklet('_easeRightLTR', oldImage, targetImage);
							}
						}
					);
				}
				else
				{
					this.simpleBooklet('_refreshRight', targetImage);
					container.simpleBooklet('_easeRightLTR', oldImage, targetImage);
				}
			}
			
			,

			_easeRightLTR : function (oldImage, targetImage)
			{
				pageRight = $(this.children('div')[1]);
				pageRight.empty();
				if (oldImage.length > 0)
				{
					// initialize cover
					cover = $(this.children('div')[2]);
					coverImage = targetImage.clone();
					coverImage.appendTo(cover);
					cover.css('width', pageRight.width() + 'px');
					cover.css('left', pageRight.width() + 'px' );
					
					cover.css('display', 'block');
					coverImage.css('position', 'relative');
					coverImage.css('display', 'block');
					
					fillAndCenter(coverImage[0], this[0]);
					coverImage.css('left', (0 - coverImage.width()) + 'px');
					cover.css('display', 'block');
					coverImage.css('display', 'block');
					
					// flip cover
					container = this;
					cover.fadeOut(1);
					cover.fadeIn(150);
					pageRight.fadeOut(
							{
							   duration: 150,
							   queue: false
							}
						);
					coverImage.animate
					(
						{
							left: [0 - coverImage.width()/2, 'easeOutCubic']
						},
						{
							duration: 150, 
							queue: false,
							complete: function() {
								coverImage.remove();
								cover.css('display', 'none');
								container.simpleBooklet('_refreshRight', targetImage);
								container.removeClass('bookletBusy__');
							}
						}
					);
				}
				else
				{
					container.simpleBooklet('_refreshRight', targetImage);
					container.removeClass('bookletBusy__');
				}
			}
		};
	
		$.fn.simpleBooklet = function( method ) {
		    if ( methods[method] ) 
		    {
		    	return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
		    } 
		    else if (typeof method === 'object' || ! method ) 
		    {
		    	return methods.init.apply( this, arguments );
		    } 
		    else 
		    {
		    	throw new Exception( 'Method ' +  method + ' does not exist on jQuery.simpleBooklet' );
		    }    
		};
	}
)(jQuery);
