/**
 * jQuery bxSlider v3.0
 * http://bxslider.com
 *
 * Copyright 2011, Steven Wanderski
 * http://bxcreative.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: 1000,													// 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: '',										// 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: '',										// 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: 5000,												// 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="' + nextContent + '" />');
		    }
		    // check if prev is 'text' or 'image'
		    if (prevType == 'text') {
		        $prevHtml.html(prevContent);
		    } else {
		        $prevHtml.html('<img src="' + 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=""  style="padding-left:30px; letter-spacing:12px;  font-family:bebasregular;" 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('&nbsp;');
		        } else {
		            $('.bx-captions', $outerWrapper).html('&nbsp;');
		        }
		    }
		}

		/**
		* 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="' + startContent + '" />';
		    }
		    // check if stop is 'text' or 'image'
		    if (stopType == 'text') {
		        $stopContent = stopContent;
		    } else {
		        $stopContent = '<img src="' + 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 () {
		    // make sure the element has children
		    if ($(this).children().length > 0) {
		        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);


