﻿(function ($) {
    function wsSliderInstance() {
        this.config = {
            loop: false,
            pauseTime: 0,
            transitionTime: 1500,
            transitionFx: 'fade',
            transitionEasing: 'easeInOutBounce',
            direction: 'left',
            counterdirection: 'up',
            outgoing: 'outside',
            handlersAreRegistered: false,
            segments: 1
        },
        this.slider = {
            el: null,
            currentIndex: null,
            currentBackwardIndex: null,
            currentForwardIndex: null,
            startIndex: 0,
            oldPTime: null,
            oldTTime: null,
            goToIndex: null,
            goToIndexPreceding: null,
            beingStopped: false,
            executingAnimation: false
        }
    };
    var wsSlider = function () {
        var 
            instances = [],
            getLoopProps = function (_handler) {

                var _animProps = {};

                switch (instances[_handler].config.transitionFx) {

                    case 'slide':
                    case 'slidefade':

                        switch (instances[_handler].config.direction) {

                            case 'top':
                                _animProps.a = {
                                    top: '-=' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).height() + 'px'
                                };
                                _animProps.b = {
                                    //top: '0px'
                                    top: '-=' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).height() + 'px'
                                };
                                _animProps.restprop = 'top';
                                _animProps.restvalue = $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).parent().height() + 'px';
                                break;

                            case 'bottom':
                                _animProps.a = {
                                    top: '+=' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).height() + 'px'
                                }
                                _animProps.b = {
                                    //top: '0px'
                                    top: '+=' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).height() + 'px'
                                }
                                _animProps.restprop = 'top';
                                _animProps.restvalue = '-' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).parent().height() + 'px';
                                break;

                            case 'left':
                                _animProps.a = {
                                    left: '-=' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).width() + 'px'
                                }
                                _animProps.b = {
                                    //left: '0px'
                                    left: '-=' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).width() + 'px'
                                }
                                _animProps.restprop = 'left';
                                _animProps.restvalue = $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).parent().width() + 'px';
                                break;

                            case 'right':
                                _animProps.a = {
                                    left: '+=' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).width() + 'px'
                                }
                                _animProps.b = {
                                    //left: '0px'
                                    left: '+=' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).width() + 'px'
                                }
                                _animProps.restprop = 'left';
                                _animProps.restvalue = '-' + $($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).parent().width() + 'px';
                                break;

                        }


                        if (instances[_handler].config.transitionFx == 'slidefade') {
                            _animProps.a.opacity = 0;
                            _animProps.b.opacity = 1;
                        }

                        break;

                    case 'fade':

                        _animProps.a = {
                            opacity: 0
                        }

                        _animProps.b = {
                            opacity: 1
                        }

                        _animProps.restprop = 'opacity';
                        _animProps.restvalue = 0;

                        break;

                }



                return _animProps;

            },
            runLoop = function (_handler, _mode, _loops) {

                instances[_handler].slider.executingAnimation = true;

                resetHiddens(_handler);
                _animProps = getLoopProps(_handler);

                var _precedings = [];
                var _follower;

                if (instances[_handler].config.segments > 1) {

                    for (i = 0; i < instances[_handler].config.segments; i++) {

                        switch (instances[_handler].config.counterdirection) {

                            case 'up':
                                _precedings[i] = (instances[_handler].slider.currentIndex + i) < ($(instances[_handler].slider.el).children('.slidersection').length) ? (instances[_handler].slider.currentIndex + i) : ((instances[_handler].slider.currentIndex + i) - ($(instances[_handler].slider.el).children('.slidersection').length));
                                break;

                            case 'down':
                                _precedings[i] = (instances[_handler].slider.currentIndex - i) >= 0 ? (instances[_handler].slider.currentIndex - i) : ((i - instances[_handler].config.segments) + ($(instances[_handler].slider.el).children('.slidersection').length));
                                break;

                        }

                    }

                    switch (instances[_handler].config.counterdirection) {

                        case 'up':
                            _follower = (instances[_handler].slider.currentIndex + instances[_handler].config.segments) <= ($(instances[_handler].slider.el).children('.slidersection').length - 1) ? (instances[_handler].slider.currentIndex + instances[_handler].config.segments) : ((instances[_handler].slider.currentIndex + instances[_handler].config.segments) - ($(instances[_handler].slider.el).children('.slidersection').length));
                            break;

                        case 'down':
                            _follower = (instances[_handler].slider.currentIndex - instances[_handler].config.segments) >= 0 ? (instances[_handler].slider.currentIndex - instances[_handler].config.segments) : ((instances[_handler].slider.currentIndex - instances[_handler].config.segments) + ($(instances[_handler].slider.el).children('.slidersection').length));
                            break;

                    }

                } else {

                    _precedings[0] = instances[_handler].slider.currentIndex;

                    switch (instances[_handler].config.counterdirection) {

                        case 'up':
                            _follower = (instances[_handler].slider.currentIndex + 1) <= ($(instances[_handler].slider.el).children('.slidersection').length - 1) ? (instances[_handler].slider.currentIndex + 1) : 0;
                            break;

                        case 'down':
                            _follower = (instances[_handler].slider.currentIndex - 1) >= 0 ? (instances[_handler].slider.currentIndex - 1) : ($(instances[_handler].slider.el).children('.slidersection').length - 1);
                            break;

                    }

                }

                switch (instances[_handler].config.counterdirection) {

                    case 'up':
                        instances[_handler].slider.currentBackwardIndex = _precedings[0];
                        instances[_handler].slider.currentForwardIndex = _follower;
                        break;

                    case 'down':
                        instances[_handler].slider.currentBackwardIndex = _follower;
                        instances[_handler].slider.currentForwardIndex = _precedings[0];
                        break;

                }

                //$($(instances[_handler].slider.el).children('.slidersection')[instances[_handler].slider.currentIndex]).removeClass('hiddensection');
                //$($(instances[_handler].slider.el).children('.slidersection')[_follower]).removeClass('hiddensection');

                var _skipAnimA = false;
                var _skipAnimB = false;
                var _skipReposA = false;
                var _skipReposB = false;

                if (_mode == 'goto' && instances[_handler].config.segments == 1) {

                    if (instances[_handler].slider.goToIndexPreceding == _precedings[0] && !(instances[_handler].slider.goToIndex == _precedings[0])) {
                        _skipAnimA = true;
                        _skipReposA = true;
                    } else if (instances[_handler].slider.goToIndex == _precedings[0]) {
                        _skipAnimA = false;
                        _skipReposA = false;
                    } else {
                        _skipAnimA = true;
                        _skipReposA = false;
                    }

                    if (instances[_handler].slider.goToIndex == _precedings[0]) {
                        _skipAnimB = false;
                        _skipReposB = false;

                        if (_precedings[0] != instances[_handler].slider.goToIndexPreceding)
                            resetPreceding(_handler, _precedings[0]);
                        _precedings[0] = instances[_handler].slider.goToIndexPreceding;
                    } else {
                        _skipAnimB = true;
                        _skipReposB = false;
                    }

                }

                switch (instances[_handler].config.outgoing) {

                    case 'inside':
                        if (instances[_handler].config.transitionFx == 'fade') {

                            $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).css('top', '0px');
                            $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).css('left', '0px');
                            $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).css('z-index', 1);

                            $($(instances[_handler].slider.el).children('.slidersection')[_follower]).css('top', '0px');
                            $($(instances[_handler].slider.el).children('.slidersection')[_follower]).css('left', '0px');
                            $($(instances[_handler].slider.el).children('.slidersection')[_follower]).css('z-index', 0);

                            if (!_skipAnimA) {

                                $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).delay(instances[_handler].config.pauseTime).animate(
                                    _animProps.a,
                                    instances[_handler].config.transitionTime,
                                    instances[_handler].config.transitionEasing,
                                    function () { callBackAMany(_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB) }
                                );

                            } else {
                                callBackAMany(_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB)

                            }

                        } else if (instances[_handler].config.transitionFx == 'slidefade') {

                            $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).css('opacity', 1);
                            $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).css('z-index', 0);

                            $($(instances[_handler].slider.el).children('.slidersection')[_follower]).css('opacity', 0);
                            $($(instances[_handler].slider.el).children('.slidersection')[_follower]).css('z-index', 1);

                        } else {
                            $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).css('z-index', 0);
                            $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).addClass('hiddensection');

                        }
                        break;

                    case 'outside':

                        if (instances[_handler].config.segments > 1) {

                            $(instances[_handler].slider.el).children('.slidersection').removeClass('shown');

                            for (_preceding in _precedings) {

                                $($(instances[_handler].slider.el).children('.slidersection')[_precedings[_preceding]]).addClass('shown');

                                if (!_skipAnimA) {

                                    $($(instances[_handler].slider.el).children('.slidersection')[_precedings[_preceding]]).delay(instances[_handler].config.pauseTime).animate(
                                        _animProps.a,
                                        instances[_handler].config.transitionTime,
                                        instances[_handler].config.transitionEasing,
                                        function () { callBackAOne(_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB) }
                                    );

                                } else {
                                    callBackAOne(_handler, _mode, _loops, _precedings, _follower, skipReposA, skipReposB)

                                }

                            }

                        } else {

                            if (!_skipAnimA) {

                                $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).delay(instances[_handler].config.pauseTime).animate(
                                    _animProps.a,
                                    instances[_handler].config.transitionTime,
                                    instances[_handler].config.transitionEasing,
                                    function () { callBackAMany(_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB) }
                                );

                            } else {
                                callBackAMany(_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB);

                            }

                        }
                        break;

                }

                if (!_skipAnimB) {

                    $($(instances[_handler].slider.el).children('.slidersection')[_follower]).delay(instances[_handler].config.pauseTime).animate(
                        _animProps.b,
                        instances[_handler].config.transitionTime,
                        instances[_handler].config.transitionEasing,
                        function () {
                            //if( instances[_handler].slider.goToIndex == _precedings[0] ) { resetPreceding( _handler, instances[_handler].slider.goToIndexPreceding ); } 
                            callBackB(_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB);

                        }
                    );

                } else {

                    //if( instances[_handler].slider.goToIndex == _precedings[0] ) { resetPreceding( _handler, instances[_handler].slider.goToIndexPreceding ); }
                    callBackB(_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB);

                }
            },
            callBackAOne = function (_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB) {
                $($(instances[_handler].slider.el).children('.slidersection')[_precedings[_preceding]]).addClass('hidesection');
            },
            callBackAMany = function (_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB) {
                $($(instances[_handler].slider.el).children('.slidersection')[_precedings[0]]).addClass('hidesection');
            },
            resetPreceding = function (_handler, _indexPreceding) {

                $($(instances[_handler].slider.el).children('.slidersection')[_indexPreceding]).addClass('hiddensection');
                $($(instances[_handler].slider.el).children('.slidersection')[_indexPreceding]).removeClass('shown');

                if (instances[_handler].config.transitionFx == 'fade') {
                    $($(instances[_handler].slider.el).children('.slidersection')[_indexPreceding]).css('top', $(this).height() + 'px');
                    $($(instances[_handler].slider.el).children('.slidersection')[_indexPreceding]).css('left', $(this).width() + 'px');
                }

                if (_animProps.restprop == 'opacity') {
                    $($(instances[_handler].slider.el).children('.slidersection')[_indexPreceding]).css(_animProps.restprop, 0);

                } else {
                    $($(instances[_handler].slider.el).children('.slidersection')[_indexPreceding]).css(_animProps.restprop, _animProps.restvalue);
                }

                $($(instances[_handler].slider.el).children('.slidersection')[_indexPreceding]).css('z-index', 0);
            },
            resetFollower = function (_handler, _indexFollower) {

                $($(instances[_handler].slider.el).children('.slidersection')[_indexFollower]).removeClass('hiddensection');

                if (_animProps.restprop == 'opacity') {
                    $($(instances[_handler].slider.el).children('.slidersection')[_indexFollower]).css(_animProps.restprop, 1);
                }
            },
            callBackB = function (_handler, _mode, _loops, _precedings, _follower, _skipReposA, _skipReposB) {

                if (!_skipReposA) {
                    resetPreceding(_handler, _precedings[0]);
                    resetFollower(_handler, _follower);

                    for (i = 0; i < $(instances[_handler].slider.el).children('.hiddensection').length; i++) {
                        $($(instances[_handler].slider.el).children('.hiddensection')[i]).css('z-index', parseInt($($(instances[_handler].slider.el).children('.hiddensection')[i]).css('z-index')) + 1);
                    }
                }



                if (instances[_handler].slider.beingStopped) {
                    instances[_handler].slider.beingStopped = false;
                    instances[_handler].slider.executingAnimation = false;
                    return false;
                }

                switch (_mode) {
                    case 'once':

                        switch (instances[_handler].config.counterdirection) {
                            case 'up':
                                if (instances[_handler].slider.currentIndex == ($(instances[_handler].slider.el).children('.slidersection').length - 1) && _loops == 0) {
                                    instances[_handler].slider.currentIndex = 0;
                                    instances[_handler].slider.executingAnimation = false;
                                    return false;
                                } else {
                                    instances[_handler].slider.currentIndex++;
                                    runLoop(_handler, _mode, _loops);
                                }
                                break;

                            case 'down':
                                if (instances[_handler].slider.currentIndex == 0 && _loops == 0) {
                                    instances[_handler].slider.currentIndex = 0;
                                    instances[_handler].slider.executingAnimation = false;
                                    return false;
                                } else {
                                    instances[_handler].slider.currentIndex--;
                                    runLoop(_handler, _mode, _loops);
                                }
                                break;

                        }

                        break;

                    case 'alwaysrun':

                        switch (instances[_handler].config.counterdirection) {
                            case 'up':
                                if (instances[_handler].slider.currentIndex == ($(instances[_handler].slider.el).children('.slidersection').length - 1)) {
                                    instances[_handler].slider.currentIndex = 0;
                                    runLoop(_handler, _mode, (_loops + 1));
                                } else {
                                    instances[_handler].slider.currentIndex++;
                                    runLoop(_handler, _mode, _loops);
                                }
                                break;

                            case 'down':
                                if (instances[_handler].slider.currentIndex == 0) {
                                    instances[_handler].slider.currentIndex = ($(instances[_handler].slider.el).children('.slidersection').length - 1);
                                    runLoop(_handler, _mode, (_loops + 1));
                                } else {
                                    instances[_handler].slider.currentIndex--;
                                    runLoop(_handler, _mode, _loops);
                                }
                                break;

                        }

                        break;

                    case 'singlestep':

                        switch (instances[_handler].config.counterdirection) {
                            case 'up':
                                if (instances[_handler].slider.currentIndex == ($(instances[_handler].slider.el).children('.slidersection').length - 1)) {
                                    instances[_handler].slider.currentIndex = 0;
                                } else {
                                    instances[_handler].slider.currentIndex++;
                                }
                                break;

                            case 'down':
                                if (instances[_handler].slider.currentIndex == 0) {
                                    instances[_handler].slider.currentIndex = ($(instances[_handler].slider.el).children('.slidersection').length - 1);
                                } else {
                                    instances[_handler].slider.currentIndex--;
                                }
                                break;

                        }

                        instances[_handler].slider.executingAnimation = false;
                        return false;
                        break;

                    case 'goto':

                        switch (instances[_handler].config.counterdirection) {

                            case 'up':
                                if (instances[_handler].slider.currentIndex == instances[_handler].slider.goToIndex) {
                                    //instances[_handler].slider.currentIndex = 0;
                                    instances[_handler].slider.goToIndex = null;
                                    instances[_handler].slider.executingAnimation = false;
                                    instances[_handler].config.pauseTime = instances[_handler].slider.oldPTime;
                                    instances[_handler].config.transitionTime = instances[_handler].slider.oldTTime;

                                    instances[_handler].slider.currentIndex = ((instances[_handler].slider.currentIndex + 1) > ($(instances[_handler].slider.el).children('.slidersection').length - 1)) ? 0 : instances[_handler].slider.currentIndex + 1;
                                    return false;
                                } else {
                                    if (instances[_handler].slider.currentIndex == ($(instances[_handler].slider.el).children('.slidersection').length - 1)) {
                                        instances[_handler].slider.currentIndex = 0;
                                        runLoop(_handler, _mode, (_loops + 1));
                                    } else {
                                        instances[_handler].slider.currentIndex++;
                                        runLoop(_handler, _mode, _loops);
                                    }
                                }

                                break;

                            case 'down':

                                if (instances[_handler].slider.currentIndex == instances[_handler].slider.goToIndex) {
                                    instances[_handler].slider.goToIndex = null;
                                    instances[_handler].slider.executingAnimation = false;
                                    instances[_handler].config.pauseTime = instances[_handler].slider.oldPTime;
                                    instances[_handler].config.transitionTime = instances[_handler].slider.oldTTime;

                                    instances[_handler].slider.currentIndex = ((instances[_handler].slider.currentIndex + 1) > ($(instances[_handler].slider.el).children('.slidersection').length - 1)) ? 0 : instances[_handler].slider.currentIndex + 1;
                                    return false;
                                } else {
                                    if (instances[_handler].slider.currentIndex == 0) {
                                        instances[_handler].slider.currentIndex = ($(instances[_handler].slider.el).children('.slidersection').length - 1);
                                        runLoop(_handler, _mode, (_loops + 1));
                                    } else {
                                        instances[_handler].slider.currentIndex--;
                                        runLoop(_handler, _mode, _loops);
                                    }
                                }

                                break;

                        }

                        break;
                }
            },
            resetVisible = function (_handler) {

                if (instances[_handler].config.direction == 'right') {
                    var _currPos = $(instances[_handler].slider.el).width();
                } else if (instances[_handler].config.direction == 'bottom') {
                    var _currPos = $(instances[_handler].slider.el).height();
                } else {
                    var _currPos = 0;
                }

                if (instances[_handler].config.segments > 1) {

                    $(instances[_handler].slider.el).children('.slidersection').removeClass('shown');
                    $(instances[_handler].slider.el).children('.slidersection').addClass('hiddensection');

                    for (i = 0; i < instances[_handler].config.segments; i++) {

                        var c = (instances[_handler].config.counterdirection == 'up' ? i : ($(instances[_handler].slider.el).children('.slidersection').length - i - 1));

                        switch (instances[_handler].config.direction) {

                            case 'top':
                                $($(instances[_handler].slider.el).children('.slidersection')[c]).css('top', _currPos + 'px');
                                $($(instances[_handler].slider.el).children('.slidersection')[c]).addClass('shown');
                                _currPos += $($(instances[_handler].slider.el).children('.slidersection')[c]).height();

                                break;

                            case 'bottom':
                                _currPos -= $($(instances[_handler].slider.el).children('.slidersection')[i]).height();
                                $($(instances[_handler].slider.el).children('.slidersection')[c]).css('top', _currPos + 'px');
                                $($(instances[_handler].slider.el).children('.slidersection')[c]).addClass('shown');

                                break;

                            case 'left':
                                $($(instances[_handler].slider.el).children('.slidersection')[c]).css('left', _currPos + 'px');
                                $($(instances[_handler].slider.el).children('.slidersection')[c]).addClass('shown');
                                _currPos += $($(instances[_handler].slider.el).children('.slidersection')[c]).width();

                                break;

                            case 'right':
                                _currPos -= $($(instances[_handler].slider.el).children('.slidersection')[c]).width();
                                $($(instances[_handler].slider.el).children('.slidersection')[c]).css('left', _currPos + 'px');
                                $($(instances[_handler].slider.el).children('.slidersection')[c]).addClass('shown');

                                break;

                        }
                    }
                }
            },
            resetHiddens = function (_handler) {

                $(instances[_handler].slider.el).children('.hidesection').removeClass('hidesection');

                switch (instances[_handler].config.transitionFx) {

                    case 'slide':
                    case 'slidefade':

                        switch (instances[_handler].config.direction) {
                            case 'top':
                                $(instances[_handler].slider.el).children('.hiddensection:not(.shown)').each(function () {
                                    if ($(this).css('top') != '0px' || $(this).css('left') != '0px') {
                                        $(this).css('top', $(this).parent().height() + 'px');
                                        $(this).css('left', '0px');
                                        $(this).css('opacity', 1);
                                    }
                                });
                                break;

                            case 'bottom':
                                $(instances[_handler].slider.el).children('.hiddensection:not(.shown)').each(function () {
                                    if ($(this).css('top') != '0px' || $(this).css('left') != '0px') {
                                        $(this).css('top', '-' + $(this).height() + 'px');
                                        $(this).css('left', '0px');
                                        $(this).css('opacity', 1);
                                    }
                                });
                                break;

                            case 'left':
                                $(instances[_handler].slider.el).children('.hiddensection:not(.shown)').each(function () {
                                    if ($(this).css('top') != '0px' || $(this).css('left') != '0px') {
                                        $(this).css('top', '0px');
                                        $(this).css('left', $(this).parent().width() + 'px');
                                        $(this).css('opacity', 1);
                                    }
                                });
                                break;

                            case 'right':
                                $(instances[_handler].slider.el).children('.hiddensection:not(.shown)').each(function () {
                                    if ($(this).css('top') != '0px' || $(this).css('left') != '0px') {
                                        $(this).css('top', '0px');
                                        $(this).css('left', '-' + $(this).width() + 'px');
                                        $(this).css('opacity', 1);
                                    }
                                });
                                break;
                        }

                        break;

                    case 'fade':
                        $(instances[_handler].slider.el).children('.hiddensection').each(function () {
                            $(this).css('top', $(this).parent().height() + 'px');
                            $(this).css('left', $(this).parent().width() + 'px');
                            $(this).css('opacity', 0);
                        });
                        break;

                }


            },
            resetStartIndex = function (_handler) {
                switch (instances[_handler].config.counterdirection) {

                    case 'up':
                        instances[_handler].slider.startIndex = 0;
                        break;

                    case 'down':
                        instances[_handler].slider.startIndex = ($(instances[_handler].slider.el).children('.slidersection').length - 1);
                        break;

                }
            },
            resetLoop = function (_handler, _direction, _changed) {

                var _directionChanged = false;

                if (instances[_handler].config.direction != _direction) {
                    instances[_handler].config.direction = _direction;
                    _directionChanged = true;
                }

                if (instances[_handler].slider.currentForwardIndex != null &&
                    instances[_handler].slider.currentBackwardIndex != null) {

                    switch (instances[_handler].config.counterdirection) {
                        case 'down':
                            instances[_handler].slider.currentIndex = instances[_handler].slider.currentForwardIndex;
                            break;
                        case 'up':
                            instances[_handler].slider.currentIndex = instances[_handler].slider.currentBackwardIndex;
                            break;
                    }

                    if (!(_changed || _directionChanged)) {

                        switch (instances[_handler].config.counterdirection) {

                            case 'up':
                                instances[_handler].slider.currentIndex = (instances[_handler].slider.currentIndex + 1) > ($(instances[_handler].slider.el).children('.slidersection').length - 1) ? 0 : (instances[_handler].slider.currentIndex + 1);
                                break;

                            case 'down':
                                instances[_handler].slider.currentIndex = (instances[_handler].slider.currentIndex - 1) < 0 ? ($(instances[_handler].slider.el).children('.slidersection').length - 1) : (instances[_handler].slider.currentIndex - 1);
                                break;
                        }

                    }

                } else {

                    switch (instances[_handler].config.counterdirection) {
                        case 'down':
                            instances[_handler].slider.currentIndex = instances[_handler].config.segments - 1;
                            break;
                        case 'up':
                            instances[_handler].slider.currentIndex = 0;
                            break;
                    }

                }

            },
            runSingleStep = function (_handler, _direction, _changed) {
                resetLoop(_handler, _direction, _changed);

                runLoop(_handler, 'singlestep', 0);
            },
            runLoopOnce = function (_handler) {
                resetLoop(_handler, instances[_handler].config.direction, false);
                runLoop(_handler, 'once', 0);
            },
            runLoopAlways = function (_handler) {
                resetLoop(_handler, instances[_handler].config.direction, false);
                runLoop(_handler, 'alwaysrun', 0);
            },
            goToN = function (_handler, _direction, _changed) {
                resetLoop(_handler, _direction, _changed);
                runLoop(_handler, 'goto', 0);
            },
            stopLoop = function (_handler) {
                instances[_handler].slider.beingStopped = true;
            },
            setDirection = function (_handler, _direction) {
                if (instances[_handler].config.direction != _direction) {
                    instances[_handler].config.direction = _direction;
                }
            },
            setCounterDirection = function (_handler, _counterdirection) {
                if (instances[_handler].config.counterdirection != _counterdirection) {
                    instances[_handler].config.counterdirection = _counterdirection;
                    resetStartIndex(_handler);
                    return true;
                } else {
                    return false;
                }
            },
            checkIfExecutingAnimation = function (_handler) {
                if (instances[_handler].slider.executingAnimation) {
                    return false;
                } else {
                    return true;
                }
            }
        return {
            reInitialize: function (settings) {
                var _handler = $(this).attr('id');
                instances[_handler] = undefined;
                initialize(settings);
            },
            initialize: function (settings) {

                var _handler = $(this).attr('id');

                if (instances[_handler] != undefined) {
                    _handlersHaveBeenRegistered = instances[_handler].config.handlersAreRegistered;
                    instances[_handler] = undefined;

                } else {
                    _handlersHaveBeenRegistered = false;
                }

                instances[_handler] = new wsSliderInstance();

                instances[_handler].slider.el = $(this);

                if (settings.loop != undefined) {
                    instances[_handler].config.loop = settings.loop;
                }

                if (settings.pauseTime != undefined) {
                    instances[_handler].config.pauseTime = settings.pauseTime;
                }

                instances[_handler].config.transitionTime = ((settings.transitionTime != undefined) ? settings.transitionTime : instances[_handler].config.transitionTime);
                instances[_handler].config.transitionFx = ((settings.transitionFx != undefined) ? settings.transitionFx : instances[_handler].config.transitionFx);

                switch (instances[_handler].config.transitionFx) {
                    case 'slidein':
                        instances[_handler].config.transitionFx = 'slide';
                        instances[_handler].config.outgoing = 'inside';
                        break;

                    case 'slide':
                    case 'slideout':
                        instances[_handler].config.transitionFx = 'slide';
                        instances[_handler].config.outgoing = 'outside';
                        break;

                    case 'slidefade':
                        instances[_handler].config.outgoing = 'inside';
                        break;

                    case 'fade':
                        instances[_handler].config.outgoing = 'inside';
                        break;

                }

                instances[_handler].config.transitionEasing = ((settings.transitionEasing != undefined) ? settings.transitionEasing : instances[_handler].config.transitionEasing);

                instances[_handler].config.direction = ((settings.direction != undefined) ? settings.direction : instances[_handler].config.direction);
                instances[_handler].config.segments = ((settings.segments != undefined) ? settings.segments : instances[_handler].config.segments);

                instances[_handler].config.counterdirection = ((settings.counterdirection != undefined) ? settings.counterdirection : instances[_handler].config.counterdirection);
                instances[_handler].config.segments = ((settings.segments != undefined) ? settings.segments : instances[_handler].config.segments);

                resetVisible(_handler);
                resetHiddens(_handler);
                resetStartIndex(_handler);

                instances[_handler].slider.currentIndex = instances[_handler].slider.startIndex;

                if (instances[_handler].config.loop) {
                    runLoopAlways(_handler);
                }

            },
            runSingleStep: function (_direction) {
                var _handler = $(this).attr('id');
                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }
                runSingleStep(_handler, _direction);
            },
            runLoopOnce: function () {
                var _handler = $(this).attr('id');
                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }
                runLoopOnce(_handler);
            },
            runLoopAlways: function () {
                var _handler = $(this).attr('id');
                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }
                runLoopAlways(_handler);
            },
            moveForward: function () {
                var _handler = $(this).attr('id');
                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }
                var _changed = setCounterDirection(_handler, 'up');
                runSingleStep(_handler, 'left', _changed);
            },
            moveBackward: function () {
                var _handler = $(this).attr('id');
                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }
                var _changed = setCounterDirection(_handler, 'down');
                runSingleStep(_handler, 'right', _changed);
            },
            moveUp: function () {
                var _handler = $(this).attr('id');
                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }
                var _changed = setCounterDirection(_handler, 'up');
                runSingleStep(_handler, 'top', _changed);
            },
            moveDown: function () {
                var _handler = $(this).attr('id');
                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }
                var _changed = setCounterDirection(_handler, 'down');
                runSingleStep(_handler, 'bottom', _changed);
            },
            nextSlide: function () {
                var _handler = $(this).attr('id');

                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }

                if (instances[_handler].config.direction == 'top' ||
                    instances[_handler].config.direction == 'bottom') {
                    var _changed = setCounterDirection(_handler, 'up');
                    runSingleStep(_handler, 'top', _changed);
                } else if (instances[_handler].config.direction == 'left' ||
                    instances[_handler].config.direction == 'right') {
                    var _changed = setCounterDirection(_handler, 'up');
                    runSingleStep(_handler, 'left', _changed);
                }

            },
            prevSlide: function () {
                var _handler = $(this).attr('id');

                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }

                if (instances[_handler].config.direction == 'top' ||
                    instances[_handler].config.direction == 'bottom') {
                    var _changed = setCounterDirection(_handler, 'down');
                    runSingleStep(_handler, 'bottom', _changed);
                } else if (instances[_handler].config.direction == 'left' ||
                    instances[_handler].config.direction == 'right') {
                    var _changed = setCounterDirection(_handler, 'down');
                    runSingleStep(_handler, 'right', _changed);
                }
            },
            goToN: function (_n) {
                var _handler = $(this).attr('id');
                if (!checkIfExecutingAnimation(_handler)) {
                    return false;
                }

                if ((_n - 1) == instances[_handler].slider.currentIndex)
                    return false;

                instances[_handler].slider.oldPTime = instances[_handler].config.pauseTime;
                instances[_handler].slider.oldTTime = instances[_handler].config.transitionTime;

                instances[_handler].config.pauseTime = 0;
                instances[_handler].config.transitionTime = 1000;

                if (instances[_handler].config.counterdirection == 'up') {
                    instances[_handler].slider.goToIndexPreceding = instances[_handler].slider.currentIndex;
                    instances[_handler].slider.goToIndex = ((_n - 2) < 0 ? ($(instances[_handler].slider.el).children('.slidersection').length + (_n - 2)) : _n - 2);
                } else {
                    instances[_handler].slider.goToIndexPreceding = instances[_handler].slider.currentIndex;
                    instances[_handler].slider.goToIndex = _n;
                }

                goToN(_handler, instances[_handler].config.direction);
            },
            stopLoop: function () {
                var _handler = $(this).attr('id');
                stopLoop(_handler);
            },
            setDirection: function (_direction) {
                var _handler = $(this).attr('id');
                setDirection(_handler, _direction);
            },
            setCounterDirection: function (_counterdirection) {
                var _handler = $(this).attr('id');
                setCounterDirection(_handler, _counterdirection);
            }
        }
    } ();
    $.fn.extend({
        wsSlider: wsSlider.initialize,
        reInitialize: wsSlider.reInitialize,
        runSingleStep: wsSlider.runSingleStep,
        runLoopOnce: wsSlider.runLoopOnce,
        runLoopAlways: wsSlider.runLoopAlways,
        moveForward: wsSlider.moveForward,
        moveBackward: wsSlider.moveBackward,
        moveUp: wsSlider.moveUp,
        moveDown: wsSlider.moveDown,
        nextSlide: wsSlider.nextSlide,
        prevSlide: wsSlider.prevSlide,
        goToN: wsSlider.goToN,
        stopLoop: wsSlider.stopLoop,
        setDirection: wsSlider.setDirection,
        setCounterDirection: wsSlider.setCounterDirection
    });
})(jQuery);
