/**

 * jQuery bxSlider v3.0

 * http://bxslider.com

 *

 * Copyright 2010, Steven Wanderski

 * http://stevenwanderski.com

 *

 * Free to use and abuse under the MIT license.

 * http://www.opensource.org/licenses/mit-license.php

 * 

 */





(function($){

	

	$.fn.bxSlider = function(options){		

				

		var defaults = {

			mode: 'horizontal',									// 'horizontal', 'vertical', 'fade'

			infiniteLoop: true,									// true, false - display first slide after last

			hideControlOnEnd: false,						// true, false - if true, will hide 'next' control on last slide and 'prev' control on first

			controls: true,											// true, false - previous and next controls

			speed: 500,													// integer - in ms, duration of time slide transitions will occupy

			easing: 'swing',                    // used with jquery.easing.1.3.js - see http://gsgd.co.uk/sandbox/jquery/easing/ for available options

			pager: false,												// true / false - display a pager

			pagerSelector: null,								// jQuery selector - element to contain the pager. ex: '#pager'

			pagerType: 'full',									// 'full', 'short' - if 'full' pager displays 1,2,3... if 'short' pager displays 1 / 4

			pagerLocation: 'bottom',						// 'bottom', 'top' - location of pager

			pagerShortSeparator: '/',						// string - ex: 'of' pager would display 1 of 4

			pagerActiveClass: 'pager-active',		// string - classname attached to the active pager link

			nextText: 'next',										// string - text displayed for 'next' control

			nextImage: '',											// string - filepath of image used for 'next' control. ex: 'images/next.jpg'

			nextSelector: null,									// jQuery selector - element to contain the next control. ex: '#next'

			prevText: 'prev',										// string - text displayed for 'previous' control

			prevImage: '',											// string - filepath of image used for 'previous' control. ex: 'images/prev.jpg'

			prevSelector: null,									// jQuery selector - element to contain the previous control. ex: '#next'

			captions: false,										// true, false - display image captions (reads the image 'title' tag)

			captionsSelector: null,							// jQuery selector - element to contain the captions. ex: '#captions'

			auto: false,												// true, false - make slideshow change automatically

			autoDirection: 'next',							// 'next', 'prev' - direction in which auto show will traverse

			autoControls: false,								// true, false - show 'start' and 'stop' controls for auto show

			autoControlsSelector: null,					// jQuery selector - element to contain the auto controls. ex: '#auto-controls'

			autoStart: true,										// true, false - if false show will wait for 'start' control to activate

			autoHover: false,										// true, false - if true show will pause on mouseover

			autoDelay: 0,                       // integer - in ms, the amount of time before starting the auto show

			pause: 3000,												// integer - in ms, the duration between each slide transition

			startText: 'start',									// string - text displayed for 'start' control

			startImage: '',											// string - filepath of image used for 'start' control. ex: 'images/start.jpg'

			stopText: 'stop',										// string - text displayed for 'stop' control

			stopImage: '',											// string - filepath of image used for 'stop' control. ex: 'images/stop.jpg'

			ticker: false,											// true, false - continuous motion ticker mode (think news ticker)

																					// note: autoControls, autoControlsSelector, and autoHover apply to ticker!

			tickerSpeed: 5000,								  // float - use value between 1 and 5000 to determine ticker speed - the smaller the value the faster the ticker speed

			tickerDirection: 'next',						// 'next', 'prev' - direction in which ticker show will traverse

			tickerHover: false,                 // true, false - if true ticker will pause on mouseover

			wrapperClass: 'bx-wrapper',					// string - classname attached to the slider wraper

			startingSlide: 0, 									// integer - show will start on specified slide. note: slides are zero based!

			displaySlideQty: 1,									// integer - number of slides to display at once

			moveSlideQty: 1,										// integer - number of slides to move at once

			randomStart: false,									// true, false - if true show will start on a random slide

			onBeforeSlide: function(){},				// function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager

			onAfterSlide: function(){},					// function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager

			onLastSlide: function(){},					// function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager

			onFirstSlide: function(){},					// function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager

			onNextSlide: function(){},					// function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager

			onPrevSlide: function(){},					// function(currentSlideNumber, totalSlideQty, currentSlideHtmlObject) - advanced use only! see the tutorial here: http://bxslider.com/custom-pager

			buildPager: null										// function(slideIndex, slideHtmlObject){ return string; } - advanced use only! see the tutorial here: http://bxslider.com/custom-pager

		}

		

		var options = $.extend(defaults, options);

		

		// cache the base element

		var base = this;

		// initialize (and localize) all variables

		var $parent = '';

		var $origElement = '';

		var $children = '';

		var $outerWrapper = '';

		var $firstChild = '';

		var childrenWidth = '';

		var childrenOuterWidth = '';

		var wrapperWidth = '';

		var wrapperHeight = '';

		var $pager = '';	

		var interval = '';

		var $autoControls = '';

		var $stopHtml = '';

		var $startContent = '';

		var $stopContent = '';

		var autoPlaying = true;

		var loaded = false;

		var childrenMaxWidth = 0;

		var childrenMaxHeight = 0;

		var currentSlide = 0;	

		var origLeft = 0;

		var origTop = 0;

		var origShowWidth = 0;

		var origShowHeight = 0;

		var tickerLeft = 0;

		var tickerTop = 0;

		var isWorking = false;

    

		var firstSlide = 0;

		var lastSlide = $children.length - 1;

		

						

		// PUBLIC FUNCTIONS

						

		/**

		 * Go to specified slide

		 */		

		this.goToSlide = function(number, stopAuto){

			if(!isWorking){

				isWorking = true;

				// set current slide to argument

				currentSlide = number;

				options.onBeforeSlide(currentSlide, $children.length, $children.eq(currentSlide));

				// check if stopAuto argument is supplied

				if(typeof(stopAuto) == 'undefined'){

					var stopAuto = true;

				}

				if(stopAuto){

					// if show is auto playing, stop it

					if(options.auto){

						base.stopShow(true);

					}

				}			

				slide = number;

				// check for first slide callback

				if(slide == firstSlide){

					options.onFirstSlide(currentSlide, $children.length, $children.eq(currentSlide));

				}

				// check for last slide callback

				if(slide == lastSlide){

					options.onLastSlide(currentSlide, $children.length, $children.eq(currentSlide));

				}

				// horizontal

				if(options.mode == 'horizontal'){

					$parent.animate({'left': '-'+getSlidePosition(slide, 'left')+'px'}, options.speed, options.easing, function(){

						isWorking = false;

						// perform the callback function

						options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));

					});

				// vertical

				}else if(options.mode == 'vertical'){

					$parent.animate({'top': '-'+getSlidePosition(slide, 'top')+'px'}, options.speed, options.easing, function(){

						isWorking = false;

						// perform the callback function

						options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));

					});			

				// fade	

				}else if(options.mode == 'fade'){

					setChildrenFade();

				}

				// check to remove controls on last/first slide

				checkEndControls();

				// accomodate multi slides

				if(options.moveSlideQty > 1){

					number = Math.floor(number / options.moveSlideQty);

				}

				// make the current slide active

				makeSlideActive(number);

				// display the caption

				showCaptions();

			}

		}

		

		/**

		 * Go to next slide

		 */		

		this.goToNextSlide = function(stopAuto){

			// check if stopAuto argument is supplied

			if(typeof(stopAuto) == 'undefined'){

				var stopAuto = true;

			}

			if(stopAuto){

				// if show is auto playing, stop it

				if(options.auto){

					base.stopShow(true);

				}

			}			

			// makes slideshow finite

			if(!options.infiniteLoop){

				if(!isWorking){

					var slideLoop = false;

					// make current slide the old value plus moveSlideQty

					currentSlide = (currentSlide + (options.moveSlideQty));

					// if current slide has looped on itself

					if(currentSlide <= lastSlide){

						checkEndControls();

						// next slide callback

						options.onNextSlide(currentSlide, $children.length, $children.eq(currentSlide));

						// move to appropriate slide

						base.goToSlide(currentSlide);						

					}else{

						currentSlide -= options.moveSlideQty;

					}

				} // end if(!isWorking)		

			}else{ 

				if(!isWorking){

					isWorking = true;					

					var slideLoop = false;

					// make current slide the old value plus moveSlideQty

					currentSlide = (currentSlide + options.moveSlideQty);

					// if current slide has looped on itself

					if(currentSlide > lastSlide){

						currentSlide = currentSlide % $children.length;

						slideLoop = true;

					}

					// next slide callback

					options.onNextSlide(currentSlide, $children.length, $children.eq(currentSlide));

					// slide before callback

					options.onBeforeSlide(currentSlide, $children.length, $children.eq(currentSlide));

					if(options.mode == 'horizontal'){						

						// get the new 'left' property for $parent

						var parentLeft = (options.moveSlideQty * childrenOuterWidth);

						// animate to the new 'left'

						$parent.animate({'left': '-='+parentLeft+'px'}, options.speed, options.easing, function(){

							isWorking = false;

							// if its time to loop, reset the $parent

							if(slideLoop){

								$parent.css('left', '-'+getSlidePosition(currentSlide, 'left')+'px');

							}

							// perform the callback function

							options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));

						});

					}else if(options.mode == 'vertical'){

						// get the new 'left' property for $parent

						var parentTop = (options.moveSlideQty * childrenMaxHeight);

						// animate to the new 'left'

						$parent.animate({'top': '-='+parentTop+'px'}, options.speed, options.easing, function(){

							isWorking = false;

							// if its time to loop, reset the $parent

							if(slideLoop){

								$parent.css('top', '-'+getSlidePosition(currentSlide, 'top')+'px');

							}

							// perform the callback function

							options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));

						});

					}else if(options.mode == 'fade'){

						setChildrenFade();

					}					

					// make the current slide active

					if(options.moveSlideQty > 1){

						makeSlideActive(Math.ceil(currentSlide / options.moveSlideQty));

					}else{

						makeSlideActive(currentSlide);

					}

					// display the caption

					showCaptions();

				} // end if(!isWorking)

				

			}	

		} // end function

		

		/**

		 * Go to previous slide

		 */		

		this.goToPreviousSlide = function(stopAuto){

			// check if stopAuto argument is supplied

			if(typeof(stopAuto) == 'undefined'){

				var stopAuto = true;

			}

			if(stopAuto){

				// if show is auto playing, stop it

				if(options.auto){

					base.stopShow(true);

				}

			}			

			// makes slideshow finite

			if(!options.infiniteLoop){	

				if(!isWorking){

					var slideLoop = false;

					// make current slide the old value plus moveSlideQty

					currentSlide = currentSlide - options.moveSlideQty;

					// if current slide has looped on itself

					if(currentSlide < 0){

						currentSlide = 0;

						// if specified, hide the control on the last slide

						if(options.hideControlOnEnd){

							$('.bx-prev', $outerWrapper).hide();

						}

					}

					checkEndControls();

					// next slide callback

					options.onPrevSlide(currentSlide, $children.length, $children.eq(currentSlide));

					// move to appropriate slide

					base.goToSlide(currentSlide);

				}							

			}else{

				if(!isWorking){

					isWorking = true;			

					var slideLoop = false;

					// make current slide the old value plus moveSlideQty

					currentSlide = (currentSlide - (options.moveSlideQty));

					// if current slide has looped on itself

					if(currentSlide < 0){

						negativeOffset = (currentSlide % $children.length);

						if(negativeOffset == 0){

							currentSlide = 0;

						}else{

							currentSlide = ($children.length) + negativeOffset; 

						}

						slideLoop = true;

					}

					// next slide callback

					options.onPrevSlide(currentSlide, $children.length, $children.eq(currentSlide));

					// slide before callback

					options.onBeforeSlide(currentSlide, $children.length, $children.eq(currentSlide));

					if(options.mode == 'horizontal'){

						// get the new 'left' property for $parent

						var parentLeft = (options.moveSlideQty * childrenOuterWidth);

						// animate to the new 'left'

						$parent.animate({'left': '+='+parentLeft+'px'}, options.speed, options.easing, function(){

							isWorking = false;

							// if its time to loop, reset the $parent

							if(slideLoop){

								$parent.css('left', '-'+getSlidePosition(currentSlide, 'left')+'px');

							}

							// perform the callback function

							options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));

						});

					}else if(options.mode == 'vertical'){

						// get the new 'left' property for $parent

						var parentTop = (options.moveSlideQty * childrenMaxHeight);

						// animate to the new 'left'

						$parent.animate({'top': '+='+parentTop+'px'}, options.speed, options.easing, function(){

							isWorking = false;

							// if its time to loop, reset the $parent

							if(slideLoop){

								$parent.css('top', '-'+getSlidePosition(currentSlide, 'top')+'px');

							}

							// perform the callback function

							options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));

						});

					}else if(options.mode == 'fade'){

						setChildrenFade();

					}					

					// make the current slide active

					if(options.moveSlideQty > 1){

						makeSlideActive(Math.ceil(currentSlide / options.moveSlideQty));

					}else{

						makeSlideActive(currentSlide);

					}

					// display the caption

					showCaptions();

				} // end if(!isWorking)				

			}

		} // end function

		

		/**

		 * Go to first slide

		 */		

		this.goToFirstSlide = function(stopAuto){

			// check if stopAuto argument is supplied

			if(typeof(stopAuto) == 'undefined'){

				var stopAuto = true;

			}

			base.goToSlide(firstSlide, stopAuto);

		}

		

		/**

		 * Go to last slide

		 */		

		this.goToLastSlide = function(){

			// check if stopAuto argument is supplied

			if(typeof(stopAuto) == 'undefined'){

				var stopAuto = true;

			}

			base.goToSlide(lastSlide, stopAuto);

		}

		

		/**

		 * Get the current slide

		 */		

		this.getCurrentSlide = function(){

			return currentSlide;

		}

		

		/**

		 * Get the total slide count

		 */		

		this.getSlideCount = function(){

			return $children.length;

		}

		

		/**

		 * Stop the slideshow

		 */		

		this.stopShow = function(changeText){

			clearInterval(interval);

			// check if changeText argument is supplied

			if(typeof(changeText) == 'undefined'){

				var changeText = true;

			}

			if(changeText && options.autoControls){

				$autoControls.html($startContent).removeClass('stop').addClass('start');

				autoPlaying = false;

			}

		}

		

		/**

		 * Start the slideshow

		 */		

		this.startShow = function(changeText){

			// check if changeText argument is supplied

			if(typeof(changeText) == 'undefined'){

				var changeText = true;

			}

			setAutoInterval();

			if(changeText && options.autoControls){

				$autoControls.html($stopContent).removeClass('start').addClass('stop');

				autoPlaying = true;

			}

		}

		

		/**

		 * Stops the ticker

		 */		

		this.stopTicker = function(changeText){

			$parent.stop();

			// check if changeText argument is supplied

			if(typeof(changeText) == 'undefined'){

				var changeText = true;

			}

			if(changeText && options.ticker){

				$autoControls.html($startContent).removeClass('stop').addClass('start');

				autoPlaying = false;

			}			

		}

		

		/**

		 * Starts the ticker

		 */		

		this.startTicker = function(changeText){

			if(options.mode == 'horizontal'){

				if(options.tickerDirection == 'next'){

					// get the 'left' property where the ticker stopped

					var stoppedLeft = parseInt($parent.css('left'));

					// calculate the remaining distance the show must travel until the loop

					var remainingDistance = (origShowWidth + stoppedLeft) + $children.eq(0).width();			

				}else if(options.tickerDirection == 'prev'){

					// get the 'left' property where the ticker stopped

					var stoppedLeft = -parseInt($parent.css('left'));

					// calculate the remaining distance the show must travel until the loop

					var remainingDistance = (stoppedLeft) - $children.eq(0).width();

				}

				// calculate the speed ratio to seamlessly finish the loop

				var finishingSpeed = (remainingDistance * options.tickerSpeed) / origShowWidth;

				// call the show

				moveTheShow(tickerLeft, remainingDistance, finishingSpeed);					

			}else if(options.mode == 'vertical'){

				if(options.tickerDirection == 'next'){

					// get the 'top' property where the ticker stopped

					var stoppedTop = parseInt($parent.css('top'));

					// calculate the remaining distance the show must travel until the loop

					var remainingDistance = (origShowHeight + stoppedTop) + $children.eq(0).height();			

				}else if(options.tickerDirection == 'prev'){

					// get the 'left' property where the ticker stopped

					var stoppedTop = -parseInt($parent.css('top'));

					// calculate the remaining distance the show must travel until the loop

					var remainingDistance = (stoppedTop) - $children.eq(0).height();

				}

				// calculate the speed ratio to seamlessly finish the loop

				var finishingSpeed = (remainingDistance * options.tickerSpeed) / origShowHeight;

				// call the show

				moveTheShow(tickerTop, remainingDistance, finishingSpeed);

				// check if changeText argument is supplied

				if(typeof(changeText) == 'undefined'){

					var changeText = true;

				}

				if(changeText && options.ticker){

					$autoControls.html($stopContent).removeClass('start').addClass('stop');

					autoPlaying = true;

				}						

			}

		}

				

		/**

		 * Initialize a new slideshow

		 */		

		this.initShow = function(){

			

			// reinitialize all variables

			// base = this;

			$parent = $(this);

			$origElement = $parent.clone();

			$children = $parent.children();

			$outerWrapper = '';

			$firstChild = $parent.children(':first');

			childrenWidth = $firstChild.width();

			childrenMaxWidth = 0;

			childrenOuterWidth = $firstChild.outerWidth();

			childrenMaxHeight = 0;

			wrapperWidth = getWrapperWidth();

			wrapperHeight = getWrapperHeight();

			isWorking = false;

			$pager = '';	

			currentSlide = 0;	

			origLeft = 0;

			origTop = 0;

			interval = '';

			$autoControls = '';

			$stopHtml = '';

			$startContent = '';

			$stopContent = '';

			autoPlaying = true;

			loaded = false;

			origShowWidth = 0;

			origShowHeight = 0;

			tickerLeft = 0;

			tickerTop = 0;

      

			firstSlide = 0;

			lastSlide = $children.length - 1;

						

			// get the largest child's height and width

			$children.each(function(index) {

			  if($(this).outerHeight() > childrenMaxHeight){

					childrenMaxHeight = $(this).outerHeight();

				}

				if($(this).outerWidth() > childrenMaxWidth){

					childrenMaxWidth = $(this).outerWidth();

				}

			});



			// get random slide number

			if(options.randomStart){

				var randomNumber = Math.floor(Math.random() * $children.length);

				currentSlide = randomNumber;

				origLeft = childrenOuterWidth * (options.moveSlideQty + randomNumber);

				origTop = childrenMaxHeight * (options.moveSlideQty + randomNumber);

			// start show at specific slide

			}else{

				currentSlide = options.startingSlide;

				origLeft = childrenOuterWidth * (options.moveSlideQty + options.startingSlide);

				origTop = childrenMaxHeight * (options.moveSlideQty + options.startingSlide);

			}

						

			// set initial css

			initCss();

			

			// check to show pager

			if(options.pager && !options.ticker){

				if(options.pagerType == 'full'){

					showPager('full');

				}else if(options.pagerType == 'short'){

					showPager('short');

				}

			}

						

			// check to show controls

			if(options.controls && !options.ticker){

				setControlsVars();

			}

						

			// check if auto

			if(options.auto || options.ticker){

				// check if auto controls are displayed

				if(options.autoControls){

					setAutoControlsVars();

				}

				// check if show should auto start

				if(options.autoStart){

					// check if autostart should delay

					setTimeout(function(){

						base.startShow(true);

					}, options.autoDelay);

				}else{

					base.stopShow(true);

				}

				// check if show should pause on hover

				if(options.autoHover && !options.ticker){

					setAutoHover();

				}

			}						

			// make the starting slide active

			if(options.moveSlideQty > 1){

				makeSlideActive(Math.ceil(currentSlide / options.moveSlideQty));

			}else{			

				makeSlideActive(currentSlide);			

			}

			// check for finite show and if controls should be hidden

			checkEndControls();

			// show captions

			if(options.captions){

				showCaptions();

			}

			// perform the callback function

			options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));

		}

		

		/**

		 * Destroy the current slideshow

		 */		

		this.destroyShow = function(){			

			// stop the auto show

			clearInterval(interval);

			// remove any controls / pagers that have been appended

			$('.bx-next, .bx-prev, .bx-pager, .bx-auto', $outerWrapper).remove();

			// unwrap all bx-wrappers

			$parent.unwrap().unwrap().removeAttr('style');

			// remove any styles that were appended

			$parent.children().removeAttr('style').not('.pager').remove();

			// remove any childrent that were appended

			$children.removeClass('pager');

			

		}

		

		/**

		 * Reload the current slideshow

		 */		

		this.reloadShow = function(){

			base.destroyShow();

			base.initShow();

		}

		

		// PRIVATE FUNCTIONS

		

		/**

		 * Creates all neccessary styling for the slideshow

		 */		

		function initCss(){

			// layout the children

			setChildrenLayout(options.startingSlide);

			// CSS for horizontal mode

			if(options.mode == 'horizontal'){

				// wrap the <ul> in div that acts as a window and make the <ul> uber wide

				$parent

				.wrap('<div class="'+options.wrapperClass+'" style="width:'+wrapperWidth+'px; position:relative;"></div>')

				.wrap('<div class="bx-window" style="position:relative; overflow:hidden; width:'+wrapperWidth+'px;"></div>')

				.css({

				  width: '999999px',

				  position: 'relative',

					left: '-'+(origLeft)+'px'

				});

				$parent.children().css({

					width: childrenWidth,

				  'float': 'left',

				  listStyle: 'none'

				});					

				$outerWrapper = $parent.parent().parent();

				$children.addClass('pager');

			// CSS for vertical mode

			}else if(options.mode == 'vertical'){

				// wrap the <ul> in div that acts as a window and make the <ul> uber tall

				$parent

				.wrap('<div class="'+options.wrapperClass+'" style="width:'+childrenMaxWidth+'px; position:relative;"></div>')

				.wrap('<div class="bx-window" style="width:'+childrenMaxWidth+'px; height:'+wrapperHeight+'px; position:relative; overflow:hidden;"></div>')

				.css({

				  height: '999999px',

				  position: 'relative',

					top: '-'+(origTop)+'px'

				});

				$parent.children().css({

				  listStyle: 'none',

					height: childrenMaxHeight

				});					

				$outerWrapper = $parent.parent().parent();

				$children.addClass('pager');

			// CSS for fade mode

			}else if(options.mode == 'fade'){

				// wrap the <ul> in div that acts as a window

				$parent

				.wrap('<div class="'+options.wrapperClass+'" style="width:'+childrenMaxWidth+'px; position:relative;"></div>')

				.wrap('<div class="bx-window" style="height:'+childrenMaxHeight+'px; width:'+childrenMaxWidth+'px; position:relative; overflow:hidden;"></div>');

				$parent.children().css({

				  listStyle: 'none',

				  position: 'absolute',

					top: 0,

					left: 0,

					zIndex: 98

				});					

				$outerWrapper = $parent.parent().parent();

				$children.not(':eq('+currentSlide+')').fadeTo(0, 0);

				$children.eq(currentSlide).css('zIndex', 99);

			}

			// if captions = true setup a div placeholder

			if(options.captions && options.captionsSelector == null){

				$outerWrapper.append('<div class="bx-captions"></div>');

			}			

		}

		

		/**

		 * Depending on mode, lays out children in the proper setup

		 */		

		function setChildrenLayout(){			

			// lays out children for horizontal or vertical modes

			if(options.mode == 'horizontal' || options.mode == 'vertical'){

								

				// get the children behind

				var $prependedChildren = getArraySample($children, 0, options.moveSlideQty, 'backward');

				

				// add each prepended child to the back of the original element

				$.each($prependedChildren, function(index) {

					$parent.prepend($(this));

				});			

				

				// total number of slides to be hidden after the window

				var totalNumberAfterWindow = ($children.length + options.moveSlideQty) - 1;

				// number of original slides hidden after the window

				var pagerExcess = $children.length - options.displaySlideQty;

				// number of slides to append to the original hidden slides

				var numberToAppend = totalNumberAfterWindow - pagerExcess;

				// get the sample of extra slides to append

				var $appendedChildren = getArraySample($children, 0, numberToAppend, 'forward');

				

				if(options.infiniteLoop){

					// add each appended child to the front of the original element

					$.each($appendedChildren, function(index) {

						$parent.append($(this));

					});

				}

			}

		}

		

		/**

		 * Sets all variables associated with the controls

		 */		

		function setControlsVars(){

			// check if text or images should be used for controls

			// check "next"

			if(options.nextImage != ''){

				nextContent = options.nextImage;

				nextType = 'image';

			}else{

				nextContent = options.nextText;

				nextType = 'text';

			}

			// check "prev"

			if(options.prevImage != ''){

				prevContent = options.prevImage;

				prevType = 'image';

			}else{

				prevContent = options.prevText;

				prevType = 'text';

			}

			// show the controls

			showControls(nextType, nextContent, prevType, prevContent);

		}			

		

		/**

		 * Puts slideshow into auto mode

		 *

		 * @param int pause number of ms the slideshow will wait between slides 

		 * @param string direction 'forward', 'backward' sets the direction of the slideshow (forward/backward)

		 * @param bool controls determines if start/stop controls will be displayed

		 */		

		function setAutoInterval(){

			if(options.auto){

				// finite loop

				if(!options.infiniteLoop){

					if(options.autoDirection == 'next'){

						interval = setInterval(function(){

							currentSlide += options.moveSlideQty;

							// if currentSlide has exceeded total number

							if(currentSlide > lastSlide){

								currentSlide = currentSlide % $children.length;

							}

							base.goToSlide(currentSlide, false);

						}, options.pause);

					}else if(options.autoDirection == 'prev'){

						interval = setInterval(function(){

							currentSlide -= options.moveSlideQty;

							// if currentSlide is smaller than zero

							if(currentSlide < 0){

								negativeOffset = (currentSlide % $children.length);

								if(negativeOffset == 0){

									currentSlide = 0;

								}else{

									currentSlide = ($children.length) + negativeOffset; 

								}

							}

							base.goToSlide(currentSlide, false);

						}, options.pause);

					}

				// infinite loop

				}else{

					if(options.autoDirection == 'next'){

						interval = setInterval(function(){

							base.goToNextSlide(false);

						}, options.pause);

					}else if(options.autoDirection == 'prev'){

						interval = setInterval(function(){

							base.goToPreviousSlide(false);

						}, options.pause);

					}

				}

			

			}else if(options.ticker){

				

				options.tickerSpeed *= 10;

												

				// get the total width of the original show

				$('.pager', $outerWrapper).each(function(index) {

				  origShowWidth += $(this).width();

					origShowHeight += $(this).height();

				});

				

				// if prev start the show from the last slide

				if(options.tickerDirection == 'prev' && options.mode == 'horizontal'){

					$parent.css('left', '-'+(origShowWidth+origLeft)+'px');

				}else if(options.tickerDirection == 'prev' && options.mode == 'vertical'){

					$parent.css('top', '-'+(origShowHeight+origTop)+'px');

				}

				

				if(options.mode == 'horizontal'){

					// get the starting left position

					tickerLeft = parseInt($parent.css('left'));

					// start the ticker

					moveTheShow(tickerLeft, origShowWidth, options.tickerSpeed);

				}else if(options.mode == 'vertical'){

					// get the starting top position

					tickerTop = parseInt($parent.css('top'));

					// start the ticker

					moveTheShow(tickerTop, origShowHeight, options.tickerSpeed);

				}												

				

				// check it tickerHover applies

				if(options.tickerHover){

					setTickerHover();

				}					

			}			

		}

		

		function moveTheShow(leftCss, distance, speed){

			// if horizontal

			if(options.mode == 'horizontal'){

				// if next

				if(options.tickerDirection == 'next'){

					$parent.animate({'left': '-='+distance+'px'}, speed, 'linear', function(){

						$parent.css('left', leftCss);

						moveTheShow(leftCss, origShowWidth, options.tickerSpeed);

					});

				// if prev

				}else if(options.tickerDirection == 'prev'){

					$parent.animate({'left': '+='+distance+'px'}, speed, 'linear', function(){

						$parent.css('left', leftCss);

						moveTheShow(leftCss, origShowWidth, options.tickerSpeed);

					});

				}

			// if vertical		

			}else if(options.mode == 'vertical'){

				// if next

				if(options.tickerDirection == 'next'){

					$parent.animate({'top': '-='+distance+'px'}, speed, 'linear', function(){

						$parent.css('top', leftCss);

						moveTheShow(leftCss, origShowHeight, options.tickerSpeed);

					});

				// if prev

				}else if(options.tickerDirection == 'prev'){

					$parent.animate({'top': '+='+distance+'px'}, speed, 'linear', function(){

						$parent.css('top', leftCss);

						moveTheShow(leftCss, origShowHeight, options.tickerSpeed);

					});

				}

			}

		}		

		

		/**

		 * Sets all variables associated with the controls

		 */		

		function setAutoControlsVars(){

			// check if text or images should be used for controls

			// check "start"

			if(options.startImage != ''){

				startContent = options.startImage;

				startType = 'image';

			}else{

				startContent = options.startText;

				startType = 'text';

			}

			// check "stop"

			if(options.stopImage != ''){

				stopContent = options.stopImage;

				stopType = 'image';

			}else{

				stopContent = options.stopText;

				stopType = 'text';

			}

			// show the controls

			showAutoControls(startType, startContent, stopType, stopContent);

		}

		

		/**

		 * Handles hover events for auto shows

		 */		

		function setAutoHover(){

			// hover over the slider window

			$outerWrapper.find('.bx-window').hover(function() {

				if(autoPlaying){

					base.stopShow(false);

				}

			}, function() {

				if(autoPlaying){

					base.startShow(false);

				}

			});

		}

		

		/**

		 * Handles hover events for ticker mode

		 */		

		function setTickerHover(){

			// on hover stop the animation

			$parent.hover(function() {

				if(autoPlaying){

					base.stopTicker(false);

				}

			}, function() {

				if(autoPlaying){

					base.startTicker(false);

				}

			});

		}		

		

		/**

		 * Handles fade animation

		 */		

		function setChildrenFade(){

			// fade out any other child besides the current

			$children.not(':eq('+currentSlide+')').fadeTo(options.speed, 0).css('zIndex', 98);

			// fade in the current slide

			$children.eq(currentSlide).css('zIndex', 99).fadeTo(options.speed, 1, function(){

				isWorking = false;

				// ie fade fix

				if(jQuery.browser.msie){

					$children.eq(currentSlide).get(0).style.removeAttribute('filter');

				}

				// perform the callback function

				options.onAfterSlide(currentSlide, $children.length, $children.eq(currentSlide));

			});

		};

				

		/**

		 * Makes slide active

		 */		

		function makeSlideActive(number){

			if(options.pagerType == 'full' && options.pager){

				// remove all active classes

				$('a', $pager).removeClass(options.pagerActiveClass);

				// assign active class to appropriate slide

				$('a', $pager).eq(number).addClass(options.pagerActiveClass);

			}else if(options.pagerType == 'short' && options.pager){

				$('.bx-pager-current', $pager).html(currentSlide+1);

			}

		}

				

		/**

		 * Displays next/prev controls

		 *

		 * @param string nextType 'image', 'text'

		 * @param string nextContent if type='image', specify a filepath to the image. if type='text', specify text.

		 * @param string prevType 'image', 'text'

		 * @param string prevContent if type='image', specify a filepath to the image. if type='text', specify text.

		 */		

		function showControls(nextType, nextContent, prevType, prevContent){

			// create pager html elements

			var $nextHtml = $('<a href="" class="bx-next"></a>');

			var $prevHtml = $('<a href="" class="bx-prev"></a>');

			// check if next is 'text' or 'image'

			if(nextType == 'text'){

				$nextHtml.html(nextContent);

			}else{

				$nextHtml.html('<img src="../arquivos_arquivos/'+nextContent+'" />');

			}

			// check if prev is 'text' or 'image'

			if(prevType == 'text'){

				$prevHtml.html(prevContent);

			}else{

				$prevHtml.html('<img src="../arquivos_arquivos/'+prevContent+'" />');

			}

			// check if user supplied a selector to populate next control

			if(options.prevSelector){

				$(options.prevSelector).append($prevHtml);

			}else{

				$outerWrapper.append($prevHtml);

			}

			// check if user supplied a selector to populate next control

			if(options.nextSelector){

				$(options.nextSelector).append($nextHtml);

			}else{

				$outerWrapper.append($nextHtml);

			}

			// click next control

			$nextHtml.click(function() {

				base.goToNextSlide();

				return false;

			});

			// click prev control

			$prevHtml.click(function() {

				base.goToPreviousSlide();

				return false;

			});

		}

		

		/**

		 * Displays the pager

		 *

		 * @param string type 'full', 'short'

		 */		

		function showPager(type){

			// sets up logic for finite multi slide shows

			var pagerQty = $children.length;

			// if we are moving more than one at a time and we have a finite loop

			if(options.moveSlideQty > 1){

				// if slides create an odd number of pages

				if($children.length % options.moveSlideQty != 0){

					// pagerQty = $children.length / options.moveSlideQty + 1;

					pagerQty = Math.ceil($children.length / options.moveSlideQty);

				// if slides create an even number of pages

				}else{

					pagerQty = $children.length / options.moveSlideQty;

				}

			}

			var pagerString = '';

			// check if custom build function was supplied

			if(options.buildPager){

				for(var i=0; i<pagerQty; i++){

					pagerString += options.buildPager(i, $children.eq(i * options.moveSlideQty));

				}

				

			// if not, use default pager

			}else if(type == 'full'){

				// build the full pager

				for(var i=1; i<=pagerQty; i++){

					pagerString += '<a href="" class="pager-link pager-'+i+'">'+i+'</a>';

				}

			}else if(type == 'short') {

				// build the short pager

				pagerString = '<span class="bx-pager-current">'+(options.startingSlide+1)+'</span> '+options.pagerShortSeparator+' <span class="bx-pager-total">'+$children.length+'<span>';

			}	

			// check if user supplied a pager selector

			if(options.pagerSelector){

				$(options.pagerSelector).append(pagerString);

				$pager = $(options.pagerSelector);

			}else{

				var $pagerContainer = $('<div class="bx-pager"></div>');

				$pagerContainer.append(pagerString);

				// attach the pager to the DOM

				if(options.pagerLocation == 'top'){

					$outerWrapper.prepend($pagerContainer);

				}else if(options.pagerLocation == 'bottom'){

					$outerWrapper.append($pagerContainer);

				}

				// cache the pager element

				$pager = $('.bx-pager', $outerWrapper);

			}

			$pager.children().click(function() {

				// only if pager is full mode

				if(options.pagerType == 'full'){

					// get the index from the link

					var slideIndex = $pager.children().index(this);

					// accomodate moving more than one slide

					if(options.moveSlideQty > 1){

						slideIndex *= options.moveSlideQty;

					}

					base.goToSlide(slideIndex);

				}

				return false;

			});

		}

				

		/**

		 * Displays captions

		 */		

		function showCaptions(){

			// get the title from each image

		  var caption = $('img', $children.eq(currentSlide)).attr('title');

			// if the caption exists

			if(caption != ''){

				// if user supplied a selector

				if(options.captionsSelector){

					$(options.captionsSelector).html(caption);

				}else{

					$('.bx-captions', $outerWrapper).html(caption);

				}

			}else{

				// if user supplied a selector

				if(options.captionsSelector){

					$(options.captionsSelector).html(' ');

				}else{

					$('.bx-captions', $outerWrapper).html(' ');

				}				

			}

		}

		

		/**

		 * Displays start/stop controls for auto and ticker mode

		 *

		 * @param string type 'image', 'text'

		 * @param string next [optional] if type='image', specify a filepath to the image. if type='text', specify text.

		 * @param string prev [optional] if type='image', specify a filepath to the image. if type='text', specify text.

		 */

		function showAutoControls(startType, startContent, stopType, stopContent){

			// create pager html elements

			$autoControls = $('<a href="" class="bx-start"></a>');

			// check if start is 'text' or 'image'

			if(startType == 'text'){

				$startContent = startContent;

			}else{

				$startContent = '<img src="../arquivos_arquivos/'+startContent+'" />';

			}

			// check if stop is 'text' or 'image'

			if(stopType == 'text'){

				$stopContent = stopContent;

			}else{

				$stopContent = '<img src="../arquivos_arquivos/'+stopContent+'" />';

			}

			// check if user supplied a selector to populate next control

			if(options.autoControlsSelector){

				$(options.autoControlsSelector).append($autoControls);

			}else{

				$outerWrapper.append('<div class="bx-auto"></div>');

				$('.bx-auto', $outerWrapper).html($autoControls);

			}

						

			// click start control

			$autoControls.click(function() {

				if(options.ticker){

					if($(this).hasClass('stop')){

						base.stopTicker();

					}else if($(this).hasClass('start')){

						base.startTicker();

					}

				}else{

					if($(this).hasClass('stop')){

						base.stopShow(true);

					}else if($(this).hasClass('start')){

						base.startShow(true);

					}

				}

				return false;

			});

			

		}

		

		/**

		 * Checks if show is in finite mode, and if slide is either first or last, then hides the respective control

		 */		

		function checkEndControls(){

			if(!options.infiniteLoop && options.hideControlOnEnd){

				// check previous

				if(currentSlide == firstSlide){

					$('.bx-prev', $outerWrapper).hide();				

				}else{

					$('.bx-prev', $outerWrapper).show();

				}

				// check next

				if(currentSlide == lastSlide){

					$('.bx-next', $outerWrapper).hide();

				}else{

					$('.bx-next', $outerWrapper).show();

				}

			}

		}

		

		/**

		 * Returns the left offset of the slide from the parent container

		 */		

		function getSlidePosition(number, side){			

			if(side == 'left'){

				var position = $('.pager', $outerWrapper).eq(number).position().left;

			}else if(side == 'top'){

				var position = $('.pager', $outerWrapper).eq(number).position().top;

			}

			return position;

		}

		

		/**

		 * Returns the width of the wrapper

		 */		

		function getWrapperWidth(){

			var wrapperWidth = $firstChild.outerWidth() * options.displaySlideQty;

			return wrapperWidth;

		}

		

		/**

		 * Returns the height of the wrapper

		 */		

		function getWrapperHeight(){

			// if displaying multiple slides, multiple wrapper width by number of slides to display

			var wrapperHeight = $firstChild.outerHeight() * options.displaySlideQty;

			return wrapperHeight;

		}

		

		/**

		 * Returns a sample of an arry and loops back on itself if the end of the array is reached

		 *

		 * @param array array original array the sample is derived from

		 * @param int start array index sample will start

		 * @param int length number of items in the sample

		 * @param string direction 'forward', 'backward' direction the loop should travel in the array

		 */		

		function getArraySample(array, start, length, direction){

			// initialize empty array

			var sample = [];

			// clone the length argument

			var loopLength = length;

			// determines when the empty array should start being populated

			var startPopulatingArray = false;

			// reverse the array if direction = 'backward'

			if(direction == 'backward'){

				array = $.makeArray(array);

				array.reverse();

			}

			// loop through original array until the length argument is met

			while(loopLength > 0){				

				// loop through original array

				$.each(array, function(index, val) {

					// check if length has been met

					if(loopLength > 0){

						// don't do anything unless first index has been reached

					  if(!startPopulatingArray){

							// start populating empty array

							if(index == start){

								startPopulatingArray = true;

								// add element to array

								sample.push($(this).clone());

								// decrease the length clone variable

								loopLength--;

							}

						}else{

							// add element to array

							sample.push($(this).clone());

							// decrease the length clone variable

							loopLength--;

						}

					// if length has been met, break loose

					}else{

						return false;

					}			

				});				

			}

			return sample;

		}

												

		this.each(function(){			

			base.initShow();

		});

				

		return this;						

	}

	

	jQuery.fx.prototype.cur = function(){

		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {

			return this.elem[ this.prop ];

		}



		var r = parseFloat( jQuery.css( this.elem, this.prop ) );

		// return r && r > -10000 ? r : 0;

		return r;

	}



		

})(jQuery);




