/*
 * jQuery slideShow
 * 
 * @ Version -> 0.1a 
 * @ Version description -> Initial draft version for June PR. Key focuspoints are extensibility, flexibility, and reusability. 
 * 
 * 
 * Key focus points for minor version 0.2
 * -> Speed optimizations and more 'user' flexibility
 * 
 * 
 * Key focus points for major version 1.0
 * -> Animation engine selection. This will enhance the experience on newer browser versions by using CSS transformations instead of jQuery for animating elements. Best available option can be added and the plugin should use feature detection to select the best available animation engine.
 */

(function ( $, undefined ) {
	
	var oModule = {
		
		init : function( oUserSettings ) {
			
			return this.each(function(index, element){
				
				var $this = $(element),
				
				oSettings = {
					
					isNavigationEnabled : true,
					isPaginationEnabled : false,
					
					slideDuration  : 500,
					slideEasing : 'linear',
					
					slideDirection : 'ltr',
					
					selectors : {
						
						selectorDeck : '.chapterDeck',
						selectorClip : '.chaptersClip',
						selectorSlides : '.chapter'
					},
					
					elements : {
						
						clipElement : {
							
							domElement : '<div />',
							
							domID : 'js-chaptersClip',
							domClass : 'chaptersClip',
							
							styles : {}
						},
						
						navButtonPrevious : {
							
							domElement : '<a href="#">Vorige</a>',
							
							domID : 'js-chaptersPrev',
							domClass : 'slideBookNavBtn chaptersPrev',
							
							styles : {}
						},
						
						navButtonNext : {
							
							domElement : '<a href="#">Volgende</a>',
							
							domID : 'js-chaptersNext',
							domClass : 'slideBookNavBtn chaptersNext',
							
							styles : {}
						},

						navPaginationWrap : {
							
							domElement : '<div />',
							
							domID : 'js-slidePagination',
							domClass : 'slidePagination',
							
							styles : {}
						},

						navPaginationAnchor : {
							
							domElement : '<a href="#"></a>',
							
							domID : '',
							domClass : 'slidePager',

							domClassActive : 'active',
							
							styles : {}
						}
					},
					
					hooks : {
						
						onInit : null,
						onSlideComplete : null
					}
				};

				if( oUserSettings ) {
					$.extend( true, oSettings, oUserSettings );
				}
				
				$this.data('settings', oSettings);
				
				var $deck = $(oSettings.selectors.selectorDeck, element), 
				$slides = $(oSettings.selectors.selectorSlides, element),
				
				iTotalSlides = $slides.length,
				iSlideWidth = $slides.outerWidth(),
				iSlideHeight = $slides.outerHeight(),
				iDeckTotalWidth = iSlideWidth * iTotalSlides,
				iDeckTotalHeight = iSlideHeight * iTotalSlides,
				iActiveSlide = 0;
				
				$this.data('activeSlide', iActiveSlide);
				
				if( iTotalSlides > 1 ) {
					
					$deck.css({'position' : 'relative'});
					
					if( oSettings.slideDirection === 'ttb' ) {
						
						$deck.height(iDeckTotalHeight);
						
					} else {
						$deck.width(iDeckTotalWidth);
						$slides.css({'float' : 'left'});
					}
					
					if( oSettings.isNavigationEnabled ) {
						
						var $navBtnPrev = $(oSettings.elements.navButtonPrevious.domElement),
						$navBtnNext = $(oSettings.elements.navButtonNext.domElement);
						
						$navBtnPrev.attr('id', oSettings.elements.navButtonPrevious.domID)
							.addClass(oSettings.elements.navButtonPrevious.domClass)
								.css(oSettings.elements.navButtonPrevious.styles)
									.bind('click.previousslide', function() {
										
										if( $this.data('activeSlide') === 0 ) {
											oModule.publicMethods.slideTo.call($this, (iTotalSlides - 1))
										} else {
											oModule.publicMethods.slideTo.call($this, ($this.data('activeSlide') - 1));
										}
										
										return false;
									}).prependTo($this);
								
						$navBtnNext.attr('id', oSettings.elements.navButtonNext.domID)
							.addClass(oSettings.elements.navButtonNext.domClass)
								.css(oSettings.elements.navButtonNext.styles)
									.bind('click.nextslide', function() {
										
										if( $this.data('activeSlide') === (iTotalSlides - 1) ) {
											oModule.publicMethods.slideTo.call($this, 0)
										} else {
											oModule.publicMethods.slideTo.call($this, ($this.data('activeSlide') + 1));
										}
										return false;
									}).appendTo($this);
					}

					if( oSettings.isPaginationEnabled ) {
						
						var $pager = $(oSettings.elements.navPaginationWrap.domElement);
						
						$pager.attr('id', oSettings.elements.navPaginationWrap.domID)
							.addClass(oSettings.elements.navPaginationWrap.domClass)
								.css(oSettings.elements.navPaginationWrap.styles);

						$slides.each(function(index, element) {
							
							var $pagerLink = $(oSettings.elements.navPaginationAnchor.domElement);

							$pagerLink.attr('id', oSettings.elements.navPaginationAnchor.domID)
								.addClass(oSettings.elements.navPaginationAnchor.domClass)
									.css(oSettings.elements.navPaginationAnchor.styles)
										.bind('click.slideto', function(){
											
											var $currentPagerLink = $(this), $test = $currentPagerLink.parent().find('.'+oSettings.elements.navPaginationAnchor.domClassActive);

											if( $test.length > 0 ) {
												$test.removeClass(oSettings.elements.navPaginationAnchor.domClassActive);
											}

											$currentPagerLink.addClass(oSettings.elements.navPaginationAnchor.domClassActive);

											oModule.publicMethods.slideTo.call($this, index)
											return false;
										});

							$pager.append($pagerLink);
						});

						$pager.appendTo($this);
					}
				}
				
				if( typeof oSettings.hooks.onInit === 'function' ) {
					oSettings.hooks.onInit.call($this);
				}
			});
		},
		
		publicMethods : {
			
			slideTo : function( iRequestedSlide ) {

				var $this = this, 
				
				oSettings = this.data('settings'), 
				
				$deck = $(oSettings.selectors.selectorDeck, this),
				$requestedSlide = $(oSettings.selectors.selectorSlides, this).eq(iRequestedSlide),
				
				iActiveSlide = this.data('activeSlide');

				if( typeof oSettings.slideDirection === 'string' && oSettings.slideDirection == 'ttb' ) {
					
					var iSlideOffset = $requestedSlide.position().top, 
					iNewXpos = iSlideOffset;

					$deck.animate({
						top : - iNewXpos
					}, {
						duration : oSettings.slideDuration,
						easing : oSettings.slideEasing,
						complete : function() { 

							iActiveSlide = iRequestedSlide;

							$this.data('activeSlide', iActiveSlide);

							if( typeof oSettings.hooks.onSlideComplete === 'function' ) {
								oSettings.hooks.onSlideComplete.call($this);
							}
						}
					});

				} else if( typeof oSettings.slideDirection === 'string' && oSettings.slideDirection == 'ltr' ) {
					
					var iSlideOffset = $requestedSlide.position().left,
					iNewXpos = iSlideOffset;

					$deck.animate({
						left : - iNewXpos
					}, {
						duration : oSettings.slideDuration,
						easing : oSettings.slideEasing,
						complete : function() { 

							iActiveSlide = iRequestedSlide;

							$this.data('activeSlide', iActiveSlide);

							if( typeof oSettings.hooks.onSlideComplete === 'function' ) {
								oSettings.hooks.onSlideComplete.call($this);
							}
						}
					});
				} else { 
					alert('Unknown slideDirection property specified. Did you supplied a string datatype?'); 
				}
			}
		}
	};
	
	$.fn.slideShow = function( sMethodName ) {
		
		if( oModule.publicMethods[sMethodName] ) {
			return oModule.publicMethods[sMethodName].apply( this, Array.prototype.slice.call(arguments, 1) );
		} 
		else if( typeof sMethodName === 'object' || ! sMethodName ) { 
			return oModule.init.apply( this, arguments );
		}
		else { 
			alert('Unknown method passed. Does this method exist!?');
		}
	};
	
}( jQuery ));
