( function( $, settings ) {
	'use strict';

	if ( 'function' !== typeof window.wpexSliderPro ) {
		window.wpexSliderPro = function( $context ) {

			if ( 'undefined' === typeof $.fn.sliderPro ) {
				return;
			}

			function dataValue( name, fallback ) {
				return ( 'undefined' !== typeof name ) ? name : fallback;
			}

			function getTallestEl( el ) {
				var tallest;
				var first = 1;
				el.each( function() {
					var $this = $( this );
					if ( first == 1 ) {
						tallest = $this;
						first = 0;
					} else {
						if ( tallest.height() < $this.height()) {
							tallest = $this;
						}
					}
				} );
				return tallest;
			}

			// Loop through each slider.
			$( '.wpex-slider', $context ).each( function() {

				// Declare vars.
				var $slider = $( this );
				var $data   = $slider.data();
				var $slides = $slider.find( '.sp-slide' );

				// Lets show things that were hidden to prevent flash.
				$slider.find( '.wpex-slider-slide, .wpex-slider-thumbnails.sp-thumbnails,.wpex-slider-thumbnails.sp-nc-thumbnails' ).css( {
					'opacity': 1,
					'display': 'block'
				} );

				// Main checks.
				var $autoHeight = dataValue( $data.autoHeight, true );
				var $preloader = $slider.prev( '.wpex-slider-preloaderimg' );
				var $height = ( $preloader.length && $autoHeight ) ? $preloader.outerHeight() : null;
				var $heightAnimationDuration = dataValue( $data.heightAnimationDuration, 600 );
				var $loop = dataValue( $data.loop, false );
				var $autoplay = dataValue( $data.autoPlay, true );
				var $counter = dataValue( $data.counter, false );

				// Get height based on tallest item if autoHeight is disabled.
				if ( ! $autoHeight && $slides.length ) {
					var $tallest = getTallestEl( $slides );
					$height = $tallest.height();
				}

				// TouchSwipe.
				var $touchSwipe = true;

				if ( 'undefined' !== typeof $data.touchSwipeDesktop && ! /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ) {
					$touchSwipe = false;
				}

				// Run slider.
				$slider.sliderPro( {
					width                   : '100%',
					height                  : $height,
					responsive              : true,
					fade                    : dataValue( $data.fade, false ),
					fadeDuration            : dataValue( $data.animationSpeed, 600 ),
					slideAnimationDuration  : dataValue( $data.animationSpeed, 600 ),
					autoHeight              : $autoHeight,
					heightAnimationDuration : parseInt( $heightAnimationDuration ),
					arrows                  : dataValue( $data.arrows, true ),
					previousArrow           : settings.previousArrow,
					nextArrow               : settings.nextArrow,
					fadeArrows              : dataValue( $data.fadeArrows, true ),
					autoplay                : $autoplay,
					autoplayDelay           : dataValue( $data.autoPlayDelay, 5000 ),
					buttons                 : dataValue( $data.buttons, true ),
					shuffle                 : dataValue( $data.shuffle, false ),
					orientation             : dataValue( $data.direction, 'horizontal' ),
					loop                    : $loop,
					keyboard                : dataValue( $data.keyboard, false ),
					fullScreen              : dataValue( $data.fullscreen, false ),
					slideDistance           : dataValue( $data.slideDistance, 0 ),
					thumbnailsPosition      : 'bottom',
					thumbnailHeight         : dataValue( $data.thumbnailHeight, 70 ),
					thumbnailWidth          : dataValue( $data.thumbnailWidth, 70 ),
					thumbnailPointer        : dataValue( $data.thumbnailPointer, false ),
					updateHash              : dataValue( $data.updateHash, false ),
					touchSwipe              : $touchSwipe,
					thumbnailArrows         : false,
					fadeThumbnailArrows     : false,
					thumbnailTouchSwipe     : true,
					fadeCaption             : dataValue( $data.fadeCaption, true ),
					captionFadeDuration     : 600,
					waitForLayers           : true,
					autoScaleLayers         : true,
					forceSize               : dataValue( $data.forceSize, 'false' ),
					reachVideoAction        : dataValue( $data.reachVideoAction, 'playVideo' ),
					leaveVideoAction        : dataValue( $data.leaveVideoAction, 'pauseVideo' ),
					endVideoAction          : dataValue( $data.leaveVideoAction, 'nextSlide' ),
					fadeOutPreviousSlide    : true, // If disabled testimonial/content slides are bad.
					autoplayOnHover         : dataValue( $data.autoplayOnHover, 'pause' ),
					init: function( e ) {

						// Remove preloader image.
						$slider.prev( '.wpex-slider-preloaderimg' ).remove();

						// Add tab index and role attribute to slider arrows and buttons.
						var $navItems = $slider.find( '.sp-button, .sp-nc-thumbnail-container, .sp-thumbnail-container' );

						$navItems.attr( 'tabindex', '0' );
						$navItems.attr( 'role', 'button' );

						// Add aria-label to bullets and thumbnails.
						var $bullets = $slider.find( '.sp-button, .sp-thumbnail-container, .sp-nc-thumbnail-container' );
						$bullets.each( function( index, val ) {
							var slideN = parseInt( index + 1 );
							$( this ).attr( 'aria-label', settings.i18n.GOTO + ' ' + slideN );
						} );

						// Add label to next arrow.
					//	$slider.find( '.sp-previous-arrow' ).attr( 'aria-label', settings.i18n.PREV );

						// Add label to prev arrow.
					//	$slider.find( '.sp-next-arrow' ).attr( 'aria-label', settings.i18n.NEXT );

					},
					gotoSlide: function( e ) {

						// Stop autoplay when loop is disabled and we've reached the last slide.
						if ( ! $loop && $autoplay && e.index === $slider.find( '.sp-slide' ).length - 1 ) {
							$slider.data( 'sliderPro' ).stopAutoplay();
						}

						// Update counter.
						if ( $counter ) {
							$slider.find( '.sp-counter .sp-active' ).text( e.index + 1 );
						}

					}

				} ); // end sliderPro.

				// Get slider Data.
				var slider = jQuery( this ).data( 'sliderPro' );

				// Add counter pagination.
				if ( $counter ) {
					$( '.sp-slides-container', $slider ).append( '<div class="sp-counter"><span class="sp-active">' + ( parseInt( slider.getSelectedSlide() ) + 1 ) + '</span>/' + slider.getTotalSlides() + '</div>' );
				}

				// Accessability click events for bullets, arrows and no carousel thumbs.
				var $navItems = $slider.find( '.sp-arrow, .sp-button, .sp-nc-thumbnail-container, .sp-thumbnail-container' );
				$navItems.keypress( function( e ) {
					if ( e.keyCode == 13 ) {
						$( this ).trigger( 'click' );
					}
				} );

				// Accessability click events for thumbnails.
				var $thumbs = $( '.sp-thumbnail-container' );
				$thumbs.keypress( function( e ) {
					if ( e.keyCode == 13 ) {
						$( this ).closest( '.wpex-slider' ).sliderPro( 'gotoSlide', $( this ).index() );
					}
				} );

			} ); // End each.

			// WooCommerce: Prevent clicking on Woo entry slider.
			$( '.woo-product-entry-slider' ).click( function() {
				return false;
			} );

		};
	} // end typeof check

	// Start slider on load (must run on this event).
	$( window ).on( 'load', function() {
		wpexSliderPro();
	} );

	// Update sliders when opening modal windows.
	$( document ).on( 'wpex-modal-loaded', function() {
		$( '.fancybox-slide' ).find( '.wpex-slider' ).each( function() {
			var $this = $( this );
			if ( $this.data( 'sliderPro' ) ) {
				$this.sliderPro( 'update' );
			}
		} );
	} );

	// Refresh slider on WPBakery stretch row.
	$( document ).on( 'vc-full-width-row', function( $elements ) {
		if ( 'function' === typeof $.fn.sliderPro && 'function' === typeof window.wpexSliderPro ) {
			$( '[data-vc-full-width="true"] .wpex-slider' ).each( function() {
				if ( $( this ).data( 'sliderPro' ) ) {
					$( this ).sliderPro( 'resize' );
				}
			} );
		}
	} );

} )( jQuery, wpex_slider_pro_params );



/*
 * noCarouselThumbnails module for Slider Pro.
 *
 * Custom module for the Total WordPress Theme.
 */
;(function( window, $ ) {

    "use strict";

    var NS = 'ThumbnailsNc.' + $.SliderPro.namespace;

    var ThumbnailsNc = {

        // Reference to the thumbnail scroller
        $thumbnailsNc: null,

        // Reference to the container of the thumbnail scroller
        $thumbnailsNcContainer: null,

        // List of Thumbnail objects
        thumbnailsNc: null,

        // Index of the selected thumbnail
        selectedThumbnailNcIndex: 0,

        // Indicates the 'left' or 'top' position based on the orientation of the thumbnailsNc
        thumbnailsNcPositionProperty: null,

        initThumbnailsNc: function() {
            var that = this;

            // Only needed when sp-nc-thumbnails class exists
            if ( ! this.$slider.children( '.sp-nc-thumbnails' ).length ) {
                return;
            }

            this.thumbnailsNc = [];
            this.on( 'update.' + NS, $.proxy( this._thumbnailsOnUpdateNc, this ) );
            this.on( 'gotoSlide.' + NS, function( event ) {
                that._gotoThumbnailNc( event.index );
            });
        },

        // Called when the slider is updated
        _thumbnailsOnUpdateNc: function() {
            var that = this;

            // Create the container of the thumbnail scroller, if it wasn't created yet
            if ( this.$thumbnailsNcContainer === null ) {
                this.$thumbnailsNcContainer = $( '<div class="sp-nc-thumbnails-container"></div>' ).insertAfter( this.$slidesContainer );
            }

            // If the thumbnailsNc' main container doesn't exist, create it, and get a reference to it
            if ( this.$thumbnailsNc === null ) {
                if ( this.$slider.find( '.sp-nc-thumbnails' ).length !== 0 ) {
                    this.$thumbnailsNc = this.$slider.find( '.sp-nc-thumbnails' ).appendTo( this.$thumbnailsNcContainer );

                    // Shuffle/randomize the thumbnailsNc
                    if ( this.settings.shuffle === true ) {
                        var thumbnailsNc = this.$thumbnailsNc.find( '.sp-nc-thumbnail' ),
                            shuffledThumbnails = [];

                        // Reposition the thumbnailsNc based on the order of the indexes in the
                        // 'shuffledIndexes' array
                        $.each( this.shuffledIndexes, function( index, element ) {
                            var $thumbnail = $( thumbnailsNc[ element ] );

                            if ( $thumbnail.parent( 'a' ).length !== 0 ) {
                                $thumbnail = $thumbnail.parent( 'a' );
                            }

                            shuffledThumbnails.push( $thumbnail );
                        });

                        // Append the sorted thumbnailsNc to the thumbnail scroller
                        this.$thumbnailsNc.empty().append( shuffledThumbnails ) ;
                    }
                } else {
                    this.$thumbnailsNc = $( '<div class="sp-nc-thumbnails"></div>' ).appendTo( this.$thumbnailsNcContainer );
                }
            }

            // Check if there are thumbnailsNc inside the slides and move them in the thumbnailsNc container
            this.$slides.find( '.sp-nc-thumbnail' ).each( function( index ) {
                var $thumbnail = $( this ),
                    thumbnailIndex = $thumbnail.parents( '.sp-slide' ).index(),
                    lastThumbnailIndex = that.$thumbnailsNc.find( '.sp-nc-thumbnail' ).length - 1;

                if ( $thumbnail.parent( 'a' ).length !== 0 ) {
                    $thumbnail = $thumbnail.parent( 'a' );
                }

                // If the index of the slide that contains the thumbnail is greater than the total number
                // of thumbnailsNc from the thumbnailsNc container, position the thumbnail at the end.
                // Otherwise, add the thumbnailsNc at the corresponding position.
                if ( thumbnailIndex > lastThumbnailIndex ) {
                    $thumbnail.appendTo( that.$thumbnailsNc );
                } else {
                    $thumbnail.insertBefore( that.$thumbnailsNc.find( '.sp-nc-thumbnail' ).eq( thumbnailIndex ) );
                }
            });

            // Loop through the Thumbnail objects and if a corresponding element is not found in the DOM,
            // it means that the thumbnail might have been removed. In this case, destroy that Thumbnail instance.
            for ( var i = this.thumbnailsNc.length - 1; i >= 0; i-- ) {
                if ( this.$thumbnailsNc.find( '.sp-nc-thumbnail[data-index="' + i + '"]' ).length === 0 ) {
                    var thumbnail = this.thumbnailsNc[ i ];

                    thumbnail.destroy();
                    this.thumbnailsNc.splice( i, 1 );
                }
            }

            // Loop through the thumbnailsNc and if there is any uninitialized thumbnail,
            // initialize it, else update the thumbnail's index.
            this.$thumbnailsNc.find( '.sp-nc-thumbnail' ).each(function( index ) {
                var $thumbnail = $( this );

                if ( typeof $thumbnail.attr( 'data-init' ) === 'undefined' ) {
                    that._createThumbnailNc( $thumbnail, index );
                } else {
                    that.thumbnailsNc[ index ].setIndexNc( index );
                }
            });

            // Check if the pointer needs to be created
            if ( this.settings.thumbnailPointer === true ) {
                this.$thumbnailsNcContainer.addClass( 'sp-has-pointer' );
            } else {
                this.$thumbnailsNcContainer.removeClass( 'sp-has-pointer' );
            }

            // Mark the thumbnail that corresponds to the selected slide
            this.selectedThumbnailNcIndex = this.selectedSlideIndex;
            this.$thumbnailsNc.find( '.sp-nc-thumbnail-container' ).eq( this.selectedThumbnailNcIndex ).addClass( 'sp-nc-selected-thumbnail' );

        },

        // Create an individual thumbnail
        _createThumbnailNc: function( element, index ) {
            var that = this,
                thumbnail = new ThumbnailNc( element, this.$thumbnailsNc, index );

            // When the thumbnail is clicked, navigate to the corresponding slide
            thumbnail.on( 'thumbnailClick.' + NS, function( event ) {
                that.gotoSlide( event.index );
            });

            // Add the thumbnail at the specified index
            this.thumbnailsNc.splice( index, 0, thumbnail );
        },

        // Selects the thumbnail at the indicated index and moves the thumbnail scroller
        _gotoThumbnailNc: function( index ) {

            var previousIndex = this.selectedThumbnailNcIndex;

            this.selectedThumbnailNcIndex = index;

            // Set the 'selected' class to the appropriate thumbnail
            this.$thumbnailsNc.find( '.sp-nc-selected-thumbnail' ).removeClass( 'sp-nc-selected-thumbnail' );
            this.$thumbnailsNc.find( '.sp-nc-thumbnail-container' ).eq( this.selectedThumbnailNcIndex ).addClass( 'sp-nc-selected-thumbnail' );

            // Fire the 'gotoThumbnail' event
            this.trigger({ type: 'gotoThumbnail' });
            if ( 'function' === typeof this.settings.gotoThumbnail ) {
                this.settings.gotoThumbnail.call( this, { type: 'gotoThumbnail' });
            }

        },

        thumbnailsNcDefaults: {

            // Sets the width of the thumbnail
            thumbnailWidth: 100,

            // Sets the height of the thumbnail
            thumbnailHeight: 80,

            // Indicates if a pointer will be displayed for the selected thumbnail
            thumbnailPointer: false,

            // Called when a new thumbnail is selected
            gotoThumbnail: function() {},

        }
    };

    var ThumbnailNc = function( thumbnail, thumbnailsNc, index ) {

        // Reference to the thumbnail jQuery element
        this.$thumbnail = thumbnail;

        // Reference to the thumbnail scroller
        this.$thumbnailsNc = thumbnailsNc;

        // Reference to the thumbnail's container, which will be 
        // created dynamically.
        this.$thumbnailContainer = null;

        // The width and height of the thumbnail
        this.width = 0;
        this.height = 0;

        // Indicates whether the thumbnail's image is loaded
        this.isImageLoaded = false;

        // Set the index of the slide
        this.setIndexNc( index );

        // Initialize the thumbnail
        this._init();
    };

    ThumbnailNc.prototype = {

        _init: function() {
            var that = this;

            // Mark the thumbnail as initialized
            this.$thumbnail.attr( 'data-init', true );

            // Create a container for the thumbnail and add the original thumbnail to this container.
            // Having a container will help crop the thumbnail image if it's too large.
            this.$thumbnailContainer = $( '<div class="sp-nc-thumbnail-container"></div>' ).appendTo( this.$thumbnailsNc );

            this.$thumbnail.appendTo( this.$thumbnailContainer );

            // When the thumbnail container is clicked, fire an event
            this.$thumbnailContainer.on( 'click.' + NS, function() {
                that.trigger({ type: 'thumbnailClick.' + NS, index: that.index });
            });
        },

        // Set the index of the thumbnail
        setIndexNc: function( index ) {
            this.index = index;
            this.$thumbnail.attr( 'data-index', this.index );
        },

        // Attach an event handler to the slide
        on: function( type, callback ) {
            return this.$thumbnailContainer.on( type, callback );
        },

        // Detach an event handler to the slide
        off: function( type ) {
            return this.$thumbnailContainer.off( type );
        },

        // Trigger an event on the slide
        trigger: function( data ) {
            return this.$thumbnailContainer.triggerHandler( data );
        }
    };

    $.SliderPro.addModule( 'ThumbnailsNc', ThumbnailsNc );

})( window, jQuery );