/*
 *        jQuery carouFredSel 4.2.3
 *        Demo's and documentation:
 *        caroufredsel.frebsite.nl
 *
 *        Copyright (c) 2010 Fred Heusschen
 *        www.frebsite.nl
 *
 *        Dual licensed under the MIT and GPL licenses.
 *        http://en.wikipedia.org/wiki/MIT_License
 *        http://en.wikipedia.org/wiki/GNU_General_Public_License
 */


(function($) {
        if ($.fn.carouFredSel) return;

        $.fn.carouFredSel = function(o) {
                if (this.length == 0) return log('No element selected.');
                if (this.length > 1) {
                        return this.each(function() {
                                $(this).carouFredSel(o);
                        });
                }
                var $ttt = this,
                        $tt0 = $ttt[0],
                        $cfs = $(this);

                $ttt.init = function(o, setOrig) {
                        var obs = ['items', 'scroll', 'auto', 'prev', 'next', 'pagination'];
                        o = getObject(o);
                        for (var a = 0; a < obs.length; a++) {
                                o[obs[a]] = getObject(o[obs[a]]);
                        }
                        if (typeof o.scroll == 'number') {
                                if (o.scroll <= 50)                                        o.scroll        = { items                : o.scroll         };
                                else                                                                o.scroll        = { duration        : o.scroll         };
                        } else {
                                if (typeof o.scroll == 'string')        o.scroll        = { easing                : o.scroll         };
                        }
                                 if (typeof o.items == 'number')        o.items                = { visible                : o.items         };
                        else if (typeof o.items == 'string')        o.items                = { visible                : o.items,
                                                                                                                                        width                : o.items,
                                                                                                                                        height                : o.items        };

                        if (setOrig) {
                                opts_orig = $.extend(true, {}, $.fn.carouFredSel.defaults, o);
                        }

                        opts = $.extend(true, {}, $.fn.carouFredSel.defaults, o);
                        opts.variableVisible = false;

                        direction = (opts.direction == 'up' || opts.direction == 'left') ? 'next' : 'prev';

                        if (opts.direction == 'right' || opts.direction == 'left') {
                                opts.dimensions = ['width', 'innerWidth', 'outerWidth', 'height', 'innerHeight', 'outerHeight', 'left', 'top', 'marginRight', 0, 1, 2, 3];
                        } else {
                                opts.dimensions = ['height', 'innerHeight', 'outerHeight', 'width', 'innerWidth', 'outerWidth', 'top', 'left', 'marginBottom', 3, 2, 1, 0];
                        }

                        var all_itm = getItems($cfs);
                        var lrgst_b = getTrueLargestSize(all_itm, opts, 5, false);


                        //        secondairy size set to auto -> measure largest size and set it
                        if (opts[opts.dimensions[3]] == 'auto') {
                                opts[opts.dimensions[3]] = lrgst_b;
                                opts.items[opts.dimensions[3]] = lrgst_b;
                        }

                        //        primairy item-size not set -> measure it or set to "variable"
                        if (!opts.items[opts.dimensions[0]]) {
                                opts.items[opts.dimensions[0]] = (hasVariableSizes(all_itm, opts, 2))
                                        ? 'variable'
                                        : all_itm[opts.dimensions[2]](true);
                        }

                        //        secondairy item-size not set -> measure it or set to "variable"
                        if (!opts.items[opts.dimensions[3]]) {
                                opts.items[opts.dimensions[3]] = (hasVariableSizes(all_itm, opts, 5))
                                        ? 'variable'
                                        : all_itm[opts.dimensions[5]](true);
                        }

                        //        secondairy size not set -> set to secondairy item-size
                        if (!opts[opts.dimensions[3]]) {
                                opts[opts.dimensions[3]] = opts.items[opts.dimensions[3]];
                        }

                        //        visible-items not set
                        if (!opts.items.visible) {
                                //        primairy item-size variable -> set visible items variable
                                if (opts.items[opts.dimensions[0]] == 'variable') {
                                        opts.items.visible = 'variable';
                                } else {
                                        //        primairy size is number -> calculate visible-items
                                        if (typeof opts[opts.dimensions[0]] == 'number') {
                                                opts.items.visible = Math.floor(opts[opts.dimensions[0]] / opts.items[opts.dimensions[0]]);
                                        } else {
                                                //        measure and calculate primairy size and visible-items
                                                var maxS = getTrueInnerSize($wrp.parent(), opts, 1);
                                                opts.items.visible = Math.floor(maxS / opts.items[opts.dimensions[0]]);
                                                opts[opts.dimensions[0]] = opts.items.visible * opts.items[opts.dimensions[0]];
                                                if (typeof opts.padding == 'undefined') {
                                                        opts.padding = 0;
                                                }
                                        }
                                }
                        }

                        //        primairy size not set -> calculate it or set to "variable"
                        if (!opts[opts.dimensions[0]]) {
                                if (opts.items.visible != 'variable' && opts.items[opts.dimensions[0]] != 'variable') {
                                        opts[opts.dimensions[0]] = opts.items.visible * opts.items[opts.dimensions[0]];
                                        if (typeof opts.padding == 'undefined') {
                                                opts.padding = 0;
                                        }
                                } else {
                                        opts[opts.dimensions[0]] = 'variable';
                                }
                        }

                        //        variable primairy item-sizes with variabe visible-items
                        if (opts.items.visible == 'variable') {
                                opts.variableVisible = true;
                                opts.maxDimention = (opts[opts.dimensions[0]] == 'variable')
                                        ? getTrueInnerSize($wrp.parent(), opts, 1)
                                        : opts[opts.dimensions[0]];
                                if (opts.padding === false || opts.padding === 0) {
                                        opts[opts.dimensions[0]] = 'variable';
                                }
                                opts.items.visible = getVisibleItemsNext($cfs, opts, 0);
                        } else {
                                if (opts.padding === false) {
                                        opts.padding = 0;
                                }
                        }

                        //        padding not set -> set to auto if primairy size is number
                        if (typeof opts.padding == 'undefined') {
                                opts.padding = (opts[opts.dimensions[0]] == 'variable')
                                        ? 0
                                        : 'auto';
                        }

                        opts.items.oldVisible = opts.items.visible;
                        opts.usePadding = false;

                        //        auto-padding, only on fixed sizes
                        if (opts.padding == 'auto') {
                                opts.padding = [0,0,0,0];
                                //         for primairy size
                                if (opts[opts.dimensions[0]] != 'variable') {
                                        opts.usePadding = 'auto';
                                        var p = getAutoPadding(getCurrentItems($cfs, opts), opts);
                                        opts.padding[opts.dimensions[10]] = p[0];
                                        opts.padding[opts.dimensions[12]] = p[0];
                                }
                                //        for secondairy size
                                if (opts[opts.dimensions[3]] != 'variable') {
                                        var p = (opts[opts.dimensions[3]] - lrgst_b) / 2;
                                        if ( p < 0 ) p = 0;
                                        opts.padding[opts.dimensions[9]]  = p;
                                        opts.padding[opts.dimensions[11]] = p;
                                }
                        //        default-padding
                        } else {
                                opts.padding = getPadding(opts.padding);
                                opts.usePadding = (
                                        opts.padding[0] == 0 &&
                                        opts.padding[1] == 0 &&
                                        opts.padding[2] == 0 &&
                                        opts.padding[3] == 0
                                ) ? false : true;
                        }

                        if (typeof opts.items.minimum        != 'number')        opts.items.minimum                = (opts.variableVisible) ? 1 : opts.items.visible;
                        if (typeof opts.scroll.items        != 'number')        opts.scroll.items                = (opts.variableVisible) ? 'variable' : opts.items.visible;
                        if (typeof opts.scroll.duration        != 'number')        opts.scroll.duration        = 500;

                        opts.auto                = getNaviObject(opts.auto, false, true);
                        opts.prev                = getNaviObject(opts.prev);
                        opts.next                = getNaviObject(opts.next);
                        opts.pagination        = getNaviObject(opts.pagination, true);

                        opts.auto                = $.extend(true, {}, opts.scroll, opts.auto);
                        opts.prev                = $.extend(true, {}, opts.scroll, opts.prev);
                        opts.next                = $.extend(true, {}, opts.scroll, opts.next);
                        opts.pagination        = $.extend(true, {}, opts.scroll, opts.pagination);

                        if (typeof opts.pagination.keys                                != 'boolean')        opts.pagination.keys                         = false;
                        if (typeof opts.pagination.anchorBuilder        != 'function')        opts.pagination.anchorBuilder        = $.fn.carouFredSel.pageAnchorBuilder;
                        if (typeof opts.auto.play                                        != 'boolean')        opts.auto.play                                        = true;
                        if (typeof opts.auto.nap                                        != 'boolean')        opts.auto.nap                                        = true;
                        if (typeof opts.auto.delay                                        != 'number')        opts.auto.delay                                        = 0;
                        if (typeof opts.auto.pauseDuration                        != 'number')        opts.auto.pauseDuration                        = (opts.auto.duration < 10) ? 2500 : opts.auto.duration * 5;

                };        //        /init

                $ttt.build = function() {
                        if ($cfs.css('position') == 'absolute' || $cfs.css('position') == 'fixed') {
                                log('Carousels CSS-attribute "position" should be "static" or "relative".');
                        }
                        $wrp.css({
                                position        : 'relative',
                                overflow        : 'hidden',
                                marginTop        : $cfs.css('marginTop'),
                                marginRight        : $cfs.css('marginRight'),
                                marginBottom: $cfs.css('marginBottom'),
                                marginLeft        : $cfs.css('marginLeft')
                        });
                        $cfs.data('cfs_origCss', {
                                width                : $cfs.css('width'),
                                height                : $cfs.css('height'),
                                marginTop        : $cfs.css('marginTop'),
                                marginRight        : $cfs.css('marginRight'),
                                marginBottom: $cfs.css('marginBottom'),
                                marginLeft        : $cfs.css('marginLeft'),
                                'float'                : $cfs.css('float'),
                                position        : $cfs.css('position'),
                                top                        : $cfs.css('top'),
                                left                : $cfs.css('left')
                        }).css({
                                marginTop        : 0,
                                marginRight        : 0,
                                marginBottom: 0,
                                marginLeft        : 0,
                                'float'                : 'none',
                                position        : 'absolute'
                        });
                        if (opts.usePadding) {
                                getItems($cfs).each(function() {
                                        var m = parseInt($(this).css(opts.dimensions[8]));
                                        if (isNaN(m)) m = 0;
                                        $(this).data('cfs_origCssMargin', m);
                                });
                        }
                };        //        /build

                $ttt.bind_events = function() {
                        $ttt.unbind_events();
                        $cfs.bind('pause', function(e, g) {
                                if (typeof g != 'boolean') g = false;
                                if (g) pausedGlobal = true;
                                if (autoTimeout != null)        clearTimeout(autoTimeout);
                                if (autoInterval != null)        clearInterval(autoInterval);
                                if (timerInterval != null)        clearInterval(timerInterval);

                                var dur1 = opts.auto.pauseDuration - pauseTimePassed,
                                        perc = 100 - Math.ceil( dur1 * 100 / opts.auto.pauseDuration );

                                if (perc != 0) {
                                        if (opts.auto.onPausePause) opts.auto.onPausePause.call($tt0, perc, dur1);
                                }
                        });

                        $cfs.bind('play', function(e, d, f, g) {
                                $cfs.trigger('pause');
                                if (!opts.auto.play) return;

                                if (typeof g != 'boolean') {
                                        if (typeof f == 'boolean')                 g = f;
                                        else if (typeof d == 'boolean')        g = d;
                                        else                                                         g = false;
                                }
                                if (typeof f != 'number') {
                                        if (typeof d == 'number')                f = d;
                                        else                                                        f = 0;
                                }
                                if (d != 'prev' && d != 'next')                d = direction;

                                if (g) pausedGlobal = false;
                                if (pausedGlobal) return;

                                var dur1 = opts.auto.pauseDuration - pauseTimePassed,
                                        dur2 = dur1 + f;
                                        perc = 100 - Math.ceil(dur1 * 100 / opts.auto.pauseDuration);

                                autoTimeout = setTimeout(function() {
                                        if ($cfs.is(':animated')) {
                                                $cfs.trigger('play', d);
                                        } else {
                                                pauseTimePassed = 0;
                                                $cfs.trigger(d, opts.auto);
                                        }
                                }, dur2);

                                if (opts.auto.pauseOnHover === 'resume') {
                                        autoInterval = setInterval(function() {
                                                pauseTimePassed += 50;
                                        }, 50);
                                }
                                if (opts.auto.onPauseEnd && perc == 0) {
                                        opts.auto.onPauseEnd.call($tt0, perc, dur1);
                                }
                                if (opts.auto.onPauseStart) {
                                        timerInterval = setTimeout(function() {
                                                opts.auto.onPauseStart.call($tt0, perc, dur1);
                                        }, f);
                                }
                        });

                        $cfs.bind('prev next', function(e) {
                                if (pausedGlobal || $cfs.is(':animated') || $cfs.is(':hidden')) {
                                        e.stopImmediatePropagation();
                                        return;
                                }
                                if (opts.items.minimum >= totalItems) {
                                        log('Not enough items: not scrolling');
                                        e.stopImmediatePropagation();
                                        return;
                                }
                                pauseTimePassed = 0;
                        });

                        if (opts.variableVisible) {
                                $cfs.bind('prev', function(e, sO, nI) {
                                        if (typeof sO == 'number') nI = sO;
                                        if (typeof sO != 'object') sO = opts.prev;
                                        if (typeof nI != 'number') nI = (typeof sO.items == 'number') ? sO.items : opts.items.visible;

                                        oI = nI;
                                        opts.items.oldVisible = opts.items.visible;

                                        var itm = getItems($cfs);
                                        if (opts.usePadding) {
                                                resetMargin(itm, opts);
                                        }
                                        opts.items.visible = getVisibleItemsPrev($cfs, opts, oI);
                                        nI = opts.items.visible - opts.items.oldVisible + oI;

                                        if (nI <= 0) {
                                                opts.items.visible = getVisibleItemsNext($cfs, opts, totalItems-oI);
                                                nI = oI;
                                        }
                                        if (opts.usePadding) {
                                                resetMargin(itm, opts, true);
                                        }

                                        $cfs.trigger('slidePrev', [sO, nI]);
                                });
                                $cfs.bind('next', function(e, sO, nI) {
                                        if (typeof sO == 'number') nI = sO;
                                        if (typeof sO != 'object') sO = opts.next;
                                        if (typeof nI != 'number') nI = (typeof sO.items == 'number') ? sO.items : opts.items.visible;

                                        opts.items.oldVisible = opts.items.visible;

                                        var itm = getItems($cfs);
                                        if (opts.usePadding) {
                                                resetMargin(itm, opts);
                                        }
                                        opts.items.visible = getVisibleItemsNext($cfs, opts, nI);

                                        if (opts.items.oldVisible - nI >= opts.items.visible) {
                                                opts.items.visible = getVisibleItemsNext($cfs, opts, ++nI);
                                        }
                                        if (opts.usePadding) {
                                                resetMargin(itm, opts, true);
                                        }
                                        $cfs.trigger('slideNext', [sO, nI]);
                                });
                        } else {
                                $cfs.bind('prev', function(e, sO, nI) {
                                        $cfs.trigger('slidePrev', [sO, nI]);
                                });
                                $cfs.bind('next', function(e, sO, nI) {
                                        $cfs.trigger('slideNext', [sO, nI]);
                                });
                        }

                        $cfs.bind('slidePrev', function(e, sO, nI) {
                                if (typeof sO == 'number') nI = sO;
                                if (typeof sO != 'object') sO = opts.prev;
                                if (typeof nI != 'number') nI = (typeof sO.items == 'number') ? sO.items : opts.items.visible;
                                if (typeof nI != 'number') return log('Not a valid number: not scrolling');

                                if (sO.conditions && !sO.conditions.call($tt0)) return;

                                if (!opts.circular) {
                                        var nulItem = totalItems - firstItem;
                                        if (nulItem - nI < 0) {
                                                nI = nulItem;
                                        }
                                        if (firstItem == 0) {
                                                nI = 0;
                                        }
                                }

                                firstItem += nI;
                                if (firstItem >= totalItems) firstItem -= totalItems;

                                if (!opts.circular) {
                                        if (firstItem == 0 && nI != 0 && sO.onEnd) sO.onEnd.call($tt0);
                                        if (opts.infinite) {
                                                if (nI == 0) {
                                                        $cfs.trigger('next', totalItems-opts.items.visible);
                                                        return;
                                                }
                                        } else enableNavi(opts, firstItem);
                                }

                                if (nI == 0) return;

                                getItems($cfs, ':gt('+(totalItems-nI-1)+')').prependTo($cfs);

                                if (totalItems < opts.items.visible + nI) {
                                        getItems($cfs, ':lt('+((opts.items.visible+nI)-totalItems)+')').clone(true).appendTo($cfs);
                                }

                                var c_old = getOldItemsPrev($cfs, opts, nI),
                                        c_new = getNewItemsPrev($cfs, opts),
                                        l_cur = getItems($cfs, ':eq('+(nI-1)+')'),
                                        l_old = c_old.filter(':last'),
                                        l_new = c_new.filter(':last');

                                if (opts.usePadding) {
                                        resetMargin(l_old, opts);
                                        resetMargin(c_new, opts);
                                }
                                if (opts.usePadding == 'auto') {
                                        var p = getAutoPadding(getNewItemsPrev($cfs, opts, nI), opts);
                                }

                                var i_siz = getTotalSize(getItems($cfs, ':lt('+nI+')'), opts, 0),
                                        w_siz = mapWrapperSizes(getSizes(c_new, opts, true), opts, !opts.usePadding);

                                if (opts.usePadding) {
                                        resetMargin(l_old, opts, opts.padding[opts.dimensions[10]]);
                                        resetMargin(l_cur, opts, opts.padding[opts.dimensions[12]]);
                                }

                                if (opts.usePadding == 'auto') {
                                        opts.padding[opts.dimensions[9]]  = p[1];
                                        opts.padding[opts.dimensions[10]] = p[0];
                                        opts.padding[opts.dimensions[11]] = p[1];
                                        opts.padding[opts.dimensions[12]] = p[0];
                                }

                                var a_cfs = {},
                                        a_new = {},
                                        a_cur = {},
                                        a_old = {},
                                        a_dur = sO.duration;

                                         if (sO.fx == 'none')        a_dur = 0;
                                else if (a_dur == 'auto')        a_dur = opts.scroll.duration / opts.scroll.items * nI;
                                else if (a_dur <= 0)                a_dur = 0;
                                else if (a_dur < 10)                a_dur = i_siz / a_dur;

                                var a_conf = {
                                        duration: a_dur,
                                        easing        : sO.easing
                                };
                                if (sO.onBefore) sO.onBefore.call($tt0, c_old, c_new, w_siz, a_dur);
                                if (opts.usePadding) {
                                        var new_m = opts.padding[opts.dimensions[12]];
                                        a_cur[opts.dimensions[8]] = l_cur.data('cfs_origCssMargin');
                                        a_new[opts.dimensions[8]] = l_new.data('cfs_origCssMargin') + opts.padding[opts.dimensions[10]];
                                        a_old[opts.dimensions[8]] = l_old.data('cfs_origCssMargin');

                                        l_cur.stop().animate(a_cur, a_conf);
                                        l_new.stop().animate(a_new, a_conf);
                                        l_old.stop().animate(a_old, a_conf);

                                } else {
                                        var new_m = 0;
                                }
                                a_cfs[opts.dimensions[6]] = new_m;

                                if (opts[opts.dimensions[0]] == 'variable' || opts[opts.dimensions[3]] == 'variable') {
                                        $wrp.stop().animate(w_siz, a_conf);
                                }

                                //        alternative effects
                                switch(sO.fx) {
                                        case 'crossfade':
                                        case 'cover':
                                        case 'uncover':
                                                var $cf2 = $cfs.clone().appendTo($wrp);
                                                break;
                                }
                                switch(sO.fx) {
                                        case 'uncover':
                                                getItems($cf2, ':lt('+nI+')').remove();
                                        case 'crossfade':
                                        case 'cover':
                                                getItems($cf2, ':gt('+(opts.items.oldVisible-1)+')').remove();
                                                break;
                                }
                                switch(sO.fx) {
                                        case 'fade':
                                                fx_fade(sO, $cfs, 0, a_dur);
                                                break;
                                        case 'crossfade':
                                                $cf2.css({ opacity: 0 });
                                                fx_fade(sO, $cf2, 1, a_dur);
                                                fx_fade(sO, $cfs, 1, a_dur, function() { $cf2.remove(); });
                                                break;
                                        case 'cover':
                                                fx_cover(sO, $cfs, $cf2, opts, a_dur, true);
                                                break;
                                        case 'uncover':
                                                fx_uncover(sO, $cf2, opts, a_dur, true);
                                                break;
                                }
                                switch(sO.fx) {
                                        case 'fade':
                                        case 'crossfade':
                                        case 'cover':
                                        case 'uncover':
                                                f_dur = a_dur;
                                                a_dur = 0;
                                                break;
                                }
                                //        /alternative effects

                                var c_nI = nI;
                                $cfs.css(opts.dimensions[6], -i_siz);
                                $cfs.animate(a_cfs, {
                                        duration: a_dur,
                                        easing        : sO.easing,
                                        complete: function() {
                                                var overFill = opts.items.visible+c_nI-totalItems;
                                                if (overFill > 0) {
                                                        getItems($cfs, ':gt('+(totalItems-1)+')').remove();
                                                        c_old = getItems($cfs, ':gt('+(totalItems-(c_nI-overFill)-1)+')').get().concat( getItems($cfs, ':lt('+overFill+')').get() );
                                                }
                                                if (opts.usePadding) {
                                                        var l_itm = getItems($cfs, ':eq('+(opts.items.visible+nI-1)+')');
                                                        l_itm.css(opts.dimensions[8], l_itm.data('cfs_origCssMargin'));
                                                }

                                                var fn = (sO.onAfter) ? function() { sO.onAfter.call($tt0, c_old, c_new, w_siz); } : false;
                                                switch(sO.fx) {
                                                        case 'fade':
                                                                fx_fade(sO, $cfs, 1, f_dur, fn);
                                                                break;
                                                        case 'uncover':
                                                                $cfs.animate({ opacity: '+=0' }, {
                                                                        duration: f_dur,
                                                                        complete: fn
                                                                });
                                                                break;
                                                        default:
                                                                if (fn) fn();
                                                                break;
                                                }
                                        }
                                });
                                $cfs.trigger('updatePageStatus').trigger('play', a_dur);
                        });

                        $cfs.bind('slideNext', function(e, sO, nI) {
                                if (typeof sO == 'number') nI = sO;
                                if (typeof sO != 'object') sO = opts.next;
                                if (typeof nI != 'number') nI = (typeof sO.items == 'number') ? sO.items : opts.items.visible;
                                if (typeof nI != 'number') return log('Not a valid number: not scrolling');

                                if (sO.conditions && !sO.conditions.call($tt0)) return;

                                if (!opts.circular) {
                                        if (firstItem == 0) {
                                                if (nI > totalItems - opts.items.visible) {
                                                        nI = totalItems - opts.items.visible;
                                                }
                                        } else {
                                                if (firstItem - nI < opts.items.visible) {
                                                        nI = firstItem - opts.items.visible;
                                                }
                                        }
                                }

                                firstItem -= nI;
                                if (firstItem < 0) firstItem += totalItems;

                                if (!opts.circular) {
                                        if (firstItem == opts.items.visible && nI != 0 && sO.onEnd) sO.onEnd.call($tt0);
                                        if (opts.infinite) {
                                                if (nI == 0) {
                                                        $cfs.trigger('prev', totalItems-opts.items.visible);
                                                        return;
                                                }
                                        } else enableNavi(opts, firstItem);
                                }

                                if (nI == 0) return;
                                if (totalItems < opts.items.visible + nI) getItems($cfs, ':lt('+((opts.items.visible+nI)-totalItems)+')').clone(true).appendTo($cfs);

                                var c_old = getOldItemsNext($cfs, opts),
                                        c_new = getNewItemsNext($cfs, opts, nI),
                                        l_cur = c_old.filter(':eq('+(nI-1)+')'),
                                        l_old = c_old.filter(':last'),
                                        l_new = c_new.filter(':last');

                                if (opts.usePadding) {
                                        resetMargin(l_old, opts);
                                        resetMargin(l_new, opts);
                                }

                                if (opts.usePadding == 'auto') {
                                        var p = getAutoPadding(getNewItemsNext($cfs, opts, nI), opts);
                                }

                                var i_siz = getTotalSize(getItems($cfs, ':lt('+nI+')'), opts, 0),
                                        w_siz = mapWrapperSizes(getSizes(c_new, opts, true), opts, !opts.usePadding);

                                if (opts.usePadding) {
                                        resetMargin(l_old, opts, opts.padding[opts.dimensions[10]]);
                                        resetMargin(l_new, opts, opts.padding[opts.dimensions[10]]);
                                }
                                if (opts.usePadding == 'auto') {
                                        opts.padding[opts.dimensions[9]]  = p[1];
                                        opts.padding[opts.dimensions[10]] = p[0];
                                        opts.padding[opts.dimensions[11]] = p[1];
                                        opts.padding[opts.dimensions[12]] = p[0];
                                }

                                var a_cfs = {},
                                        a_old = {},
                                        a_cur = {},
                                        a_dur = sO.duration;

                                         if (sO.fx == 'none')        a_dur = 0;
                                else if (a_dur == 'auto')        a_dur = opts.scroll.duration / opts.scroll.items * nI;
                                else if (a_dur <= 0)                a_dur = 0;
                                else if (a_dur < 10)                a_dur = i_siz / a_dur;

                                var a_conf = {
                                        duration: a_dur,
                                        easing        : sO.easing
                                };
                                if (sO.onBefore) sO.onBefore.call($tt0, c_old, c_new, w_siz, a_dur);
                                if (opts.usePadding) {
                                        a_old[opts.dimensions[8]] = l_old.data('cfs_origCssMargin');
                                        a_cur[opts.dimensions[8]] = l_cur.data('cfs_origCssMargin') + opts.padding[opts.dimensions[12]];
                                        l_new.css(opts.dimensions[8], l_new.data('cfs_origCssMargin') + opts.padding[opts.dimensions[10]]);
                                        l_old.stop().animate(a_old, a_conf);
                                        l_cur.stop().animate(a_cur, a_conf);
                                }
                                a_cfs[opts.dimensions[6]] = -i_siz;

                                if (opts[opts.dimensions[0]] == 'variable' || opts[opts.dimensions[3]] == 'variable') {
                                        $wrp.stop().animate(w_siz, a_conf);
                                }

                                //        alternative effects
                                switch(sO.fx) {
                                        case 'crossfade':
                                        case 'cover':
                                        case 'uncover':
                                                var $cf2 = $cfs.clone().appendTo($wrp);
                                                break;
                                }
                                switch(sO.fx) {
                                        case 'crossfade':
                                        case 'cover':
                                                getItems($cf2, ':lt('+nI+')').remove();
                                        case 'uncover':
                                                getItems($cf2, ':gt('+(opts.items.visible-1)+')').remove();
                                                break;
                                }
                                switch(sO.fx) {
                                        case 'fade':
                                                fx_fade(sO, $cfs, 0, a_dur);
                                                break;
                                        case 'crossfade':
                                                $cf2.css({ opacity: 0 });
                                                fx_fade(sO, $cf2, 1, a_dur);
                                                fx_fade(sO, $cfs, 1, a_dur, function() { $cf2.remove(); });
                                                break;
                                        case 'cover':
                                                fx_cover(sO, $cfs, $cf2, opts, a_dur, false);
                                                break;
                                        case 'uncover':
                                                fx_uncover(sO, $cf2, opts, a_dur, false);
                                                break;
                                }
                                switch(sO.fx) {
                                        case 'fade':
                                        case 'crossfade':
                                        case 'cover':
                                        case 'uncover':
                                                f_dur = a_dur;
                                                a_dur = 0;
                                                break;
                                }
                                //        /alternative effects

                                var c_nI = nI;
                                $cfs.animate(a_cfs, {
                                        duration: a_dur,
                                        easing        : sO.easing,
                                        complete: function() {
                                                var overFill = opts.items.visible+c_nI-totalItems;
                                                $cfs.css(opts.dimensions[6], opts.padding[opts.dimensions[12]]);
                                                if (overFill > 0) {
                                                        getItems($cfs, ':gt('+(totalItems-1)+')').remove();
                                                }
                                                var l_itm = getItems($cfs, ':lt('+c_nI+')').appendTo($cfs).filter(':last');
                                                if (overFill > 0) {
                                                        c_new = getCurrentItems($cfs, opts);
                                                }
                                                if (opts.usePadding) {
                                                        if (totalItems < opts.items.visible+c_nI) {
                                                                var l_cur = getItems($cfs, ':eq('+(opts.items.visible-1)+')');
                                                                l_cur.css(opts.dimensions[8], l_cur.data('cfs_origCssMargin') + opts.padding[opts.dimensions[12]]);
                                                        }
                                                        l_itm.css(opts.dimensions[8], l_itm.data('cfs_origCssMargin'));
                                                }

                                                var fn = (sO.onAfter) ? function() { sO.onAfter.call($tt0, c_old, c_new, w_siz); } : false;
                                                switch(sO.fx) {
                                                        case 'fade':
                                                                fx_fade(sO, $cfs, 1, f_dur, fn);
                                                                break;
                                                        case 'uncover':
                                                                $cfs.animate({ opacity: '+=0' }, {
                                                                        duration: f_dur,
                                                                        complete: fn
                                                                });
                                                                break;
                                                        default:
                                                                if (fn) fn();
                                                                break;
                                                }
                                        }
                                });
                                $cfs.trigger('updatePageStatus').trigger('play', a_dur);
                        });

                        $cfs.bind('slideTo', function(e, num, dev, org, obj) {
                                if ($cfs.is(':animated')) return;

                                num = getItemIndex(num, dev, org, firstItem, totalItems, $cfs);
                                if (num == 0) return;
                                if (typeof obj != 'object') obj = false;

                                if (opts.circular) {
                                        if (num < totalItems / 2)         $cfs.trigger('next', [obj, num]);
                                        else                                                 $cfs.trigger('prev', [obj, totalItems-num]);
                                } else {
                                        if (firstItem == 0 ||
                                                firstItem > num)                $cfs.trigger('next', [obj, num]);
                                        else                                                $cfs.trigger('prev', [obj, totalItems-num]);
                                }
                        });

                        $cfs.bind('insertItem', function(e, itm, num, org, dev) {
                                if (typeof itm == 'object' &&
                                        typeof itm.jquery == 'undefined')        itm = $(itm);
                                if (typeof itm == 'string')                         itm = $(itm);
                                if (typeof itm != 'object' ||
                                        typeof itm.jquery == 'undefined' ||
                                        itm.length == 0) return log('Not a valid object.');

                                if (typeof num == 'undefined' || num == 'end') {
                                        $cfs.append(itm);
                                } else {
                                        num = getItemIndex(num, dev, org, firstItem, totalItems, $cfs);
                                        var $cit = getItems($cfs, ':eq('+num+')');
                                        if (opts.usePadding) {
                                                itm.each(function() {
                                                        var m = parseInt($(this).css(opts.dimensions[8]));
                                                        if (isNaN(m)) m = 0;
                                                        $(this).data('cfs_origCssMargin', m);
                                                });
                                        }
                                        if ($cit.length) {
                                                if (num < firstItem) firstItem += itm.length;
                                                if (firstItem >= totalItems) firstItem -= totalItems;
                                                $cit.before(itm);
                                        } else {
                                                $cfs.append(itm);
                                        }
                                }
                                totalItems = getItems($cfs).length;
                                $cfs.trigger('linkAnchors');
                                setSizes($cfs, opts);
                                showNavi(opts, totalItems);
                                enableNavi(opts, firstItem);
                                $cfs.trigger('updatePageStatus', true);
                        });

                        $cfs.bind('removeItem', function(e, num, org, dev) {
                                if (typeof num == 'undefined' || num == 'end') {
                                        getItems($cfs, ':last').remove();
                                } else {
                                        num = getItemIndex(num, dev, org, firstItem, totalItems, $cfs);
                                        var $cit = getItems($cfs, ':eq('+num+')');
                                        if ($cit.length){
                                                if (num < firstItem) firstItem -= $cit.length;
                                                $cit.remove();
                                        }
                                }
                                totalItems = getItems($cfs).length;
                                setSizes($cfs, opts);
                                showNavi(opts, totalItems);
                                enableNavi(opts, firstItem);
                                $cfs.trigger('updatePageStatus', true);
                        });

                        $cfs.bind('linkAnchors', function(e, $con, sel) {
                                if (typeof $con == 'undefined' || $con.length == 0) $con = $('body');
                                else if (typeof $con == 'string') $con = $($con);
                                if (typeof $con != 'object') return log('Not a valid object.');
                                if (typeof sel != 'string' || sel.length == 0) sel = 'a.caroufredsel';
                                $con.find(sel).each(function() {
                                        var h = this.hash || '';
                                        if (h.length > 0 && getItems($cfs).index($(h)) != -1) {
                                                $(this).unbind('click').click(function(e) {
                                                        e.preventDefault();
                                                        $cfs.trigger('slideTo', h);
                                                });
                                        }
                                });
                        });

                        $cfs.bind('currentPosition', function(e, fn) {
                                if (firstItem == 0) var val = 0;
                                else var val = totalItems - firstItem;
                                if (typeof fn == 'function') fn.call($tt0, val);
                        });

                        $cfs.bind('configuration', function(e, a, b, reInit) {
                                if ($cfs.is(':animated')) {
                                        var configTimer = setInterval(function() {
                                                $cfs.trigger('configuration', [a, b, reInit]);
                                                clearInterval(configTimer);
                                        }, 100);
                                        return;
                                }
                                if (typeof reInit != 'boolean') reInit = true;
                                if (typeof a == 'function') {
                                        a.call($tt0, opts);
                                } else if (typeof b == 'function') {
                                        var val = eval('opts.'+a);
                                        if (typeof val == 'undefined') val = '';
                                        b.call($tt0, val);
                                } else if (typeof a != 'undefined' && typeof b != 'undefined') {
                                        eval('opts_orig.'+a+' = b');
                                        if (reInit) {
                                                resetMargin(getItems($cfs), opts);
                                                $ttt.init(opts_orig);
                                                setSizes($cfs, opts);
                                        } else {
                                                eval('opts.'+a+' = b');
                                        }
                                }
                        });

                        $cfs.bind('destroy', function(e, orgOrder) {
                                if (orgOrder) {
                                        $cfs.trigger('slideTo', [0, 0, true, { duration: 0 }]);
                                }
                                if (opts.usePadding) {
                                        resetMargin(getItems($cfs), opts);
                                }
                                $cfs.trigger('pause').css($cfs.data('cfs_origCss'));
                                $ttt.unbind_events();
                                $ttt.unbind_buttons();
                                $wrp.replaceWith($cfs);
                        });

                        $cfs.bind('updatePageStatus', function(e, build) {
                                if (!opts.pagination.container) return;
                                if (typeof build == 'boolean' && build) {
                                        getItems(opts.pagination.container).remove();
                                        for (var a = 0; a < Math.ceil(totalItems/opts.items.visible); a++) {
                                                var i = getItems($cfs, ':eq(' + getItemIndex(a*opts.items.visible, 0, true, firstItem, totalItems, $cfs) + ')');
                                                opts.pagination.container.append(opts.pagination.anchorBuilder(a+1, i));
                                        }
                                        getItems(opts.pagination.container).unbind('click').each(function(a) {
                                                $(this).click(function(e) {
                                                        e.preventDefault();
                                                        $cfs.trigger('slideTo', [a * opts.items.visible, 0, true, opts.pagination]);
                                                });
                                        });
                                }
                                var max = Math.ceil(totalItems/opts.items.visible-1);
                                if (firstItem == 0) var nr = 0;
                                else if (firstItem < totalItems % opts.items.visible) var nr = 0;
                                else if (firstItem == opts.items.visible && !opts.circular) var nr = max;
                                else var nr = Math.round((totalItems-firstItem)/opts.items.visible);
                                if (nr < 0) nr = 0;
                                if (nr > max) nr = max;
                                getItems(opts.pagination.container).removeClass('selected').filter(':eq('+nr+')').addClass('selected');
                        });
                };        //        /bind_events

                $ttt.unbind_events = function() {
                        $cfs.unbind('pause')
                                .unbind('play')
                                .unbind('prev')
                                .unbind('next')
                                .unbind('slidePrev')
                                .unbind('slideNext')
                                .unbind('slideTo')
                                .unbind('insertItem')
                                .unbind('removeItem')
                                .unbind('linkAnchors')
                                .unbind('destroy')
                                .unbind('updatePageStatus')
                                .unbind('currentPosition')
                                .unbind('configuration');
                };        //        /unbind_events

                $ttt.bind_buttons = function() {
                        showNavi(opts, 'show');
                        enableNavi(opts, firstItem);
                        if (opts.auto.pauseOnHover && opts.auto.play) {
                                $wrp.hover(
                                        function() { $cfs.trigger('pause'); },
                                        function() { $cfs.trigger('play');        }
                                );
                        }
                        if (opts.prev.button) {
                                opts.prev.button.click(function(e) {
                                        e.preventDefault();
                                        $cfs.trigger('prev');
                                });
                                if (opts.prev.pauseOnHover && opts.auto.play) {
                                        opts.prev.button.hover(
                                                function() { $cfs.trigger('pause');        },
                                                function() { $cfs.trigger('play');        }
                                        );
                                }
                        }
                        if (opts.next.button) {
                                opts.next.button.click(function(e) {
                                        e.preventDefault();
                                        $cfs.trigger('next');
                                });
                                if (opts.next.pauseOnHover && opts.auto.play) {
                                        opts.next.button.hover(
                                                function() { $cfs.trigger('pause');        },
                                                function() { $cfs.trigger('play');        }
                                        )
                                }
                        }
                        if ($.fn.mousewheel) {
                                if (opts.prev.mousewheel) {
                                        $wrp.mousewheel(function(e, delta) {
                                                if (delta > 0) {
                                                        e.preventDefault();
                                                        num = (typeof opts.prev.mousewheel == 'number') ? opts.prev.mousewheel : '';
                                                        $cfs.trigger('prev', num);
                                                }
                                        });
                                }
                                if (opts.next.mousewheel) {
                                        $wrp.mousewheel(function(e, delta) {
                                                if (delta < 0) {
                                                        e.preventDefault();
                                                        num = (typeof opts.next.mousewheel == 'number') ? opts.next.mousewheel : '';
                                                        $cfs.trigger('next', num);
                                                }
                                        });
                                }
                        }
                        if (opts.pagination.container) {
                                $cfs.trigger('updatePageStatus', true);
                                if (opts.pagination.pauseOnHover && opts.auto.play) {
                                        opts.pagination.container.hover(
                                                function() { $cfs.trigger('pause');        },
                                                function() { $cfs.trigger('play');        }
                                        );
                                }
                        }
                        if (opts.next.key || opts.prev.key) {
                                $(document).keyup(function(e) {
                                        var k = e.keyCode;
                                        if (k == opts.next.key)        {
                                                e.preventDefault();
                                                $cfs.trigger('next');
                                        }
                                        if (k == opts.prev.key) {
                                                e.preventDefault();
                                                $cfs.trigger('prev');
                                        }
                                });
                        }
                        if (opts.pagination.keys) {
                                $(document).keyup(function(e) {
                                        var k = e.keyCode;
                                        if (k >= 49 && k < 58) {
                                                k = (k-49) * opts.items.visible;
                                                if (k <= totalItems) {
                                                        e.preventDefault();
                                                        $cfs.trigger('slideTo', [k, 0, true, opts.pagination]);
                                                }
                                        }
                                });
                        }
                        if (opts.auto.play) {
                                $cfs.trigger('play', opts.auto.delay);
                                if ($.fn.nap && opts.auto.nap) {
                                        $cfs.nap('pause', 'play');
                                }
                        }
                };        //        /bind_buttons

                $ttt.unbind_buttons = function() {
                        showNavi(opts, 'hide');
                        enableNavi(opts, 'removeClass');
                        if (opts.pagination.container) {
                                getItems(opts.pagination.container).remove();
                        }
                };



                //        DEPRECATED
                $ttt.configuration = function(a, b) {
                        log('The "configuration" public method is deprecated, use the "configuration" custom event.');
                        var cr = false;
                        var fn = function(val) { cr = val; };
                        if (!a) a = fn;
                        if (!b) b = fn;
                        $cfs.trigger('configuration', [a, b]);
                        return cr;
                };
                $ttt.current_position = function() {
                        log('The "current_position" public method is deprecated, use the "currentPosition" custom event.');
                        var cp = false;
                        $cfs.trigger('currentPosition', function(val) { cp = val; });
                        return cp;
                };
                $ttt.destroy = function() {
                        log('The "destroy" public method is deprecated, use the "destroy" custom event.');
                        $cfs.trigger('destroy');
                        return $ttt;
                };
                $ttt.link_anchors = function($c, se) {
                        log('The "link_anchors" public method is deprecated, use the "linkAnchors" custom event.');
                        $cfs.trigger('linkAnchors', [$c, se]);
                        return $ttt;
                };
                //        /DEPRECATED




                if ($cfs.parent().is('.caroufredsel_wrapper')) {
                        var $wrp = $cfs.parent();
                        $cfs.trigger('destroy');
                }
                var $wrp                        = $cfs.wrap('<div class="caroufredsel_wrapper" />').parent(),
                        opts                         = {},
                        opts_orig                = o,
                        totalItems                = getItems($cfs).length,
                        firstItem                 = 0,
                        autoTimeout                = null,
                        autoInterval        = null,
                        timerInterval        = null,
                        pauseTimePassed        = 0,
                        pausedGlobal        = false,
                        direction                = 'next';

                $ttt.init(opts_orig, true);
                $ttt.build();
                $ttt.bind_events();
                $ttt.bind_buttons();

                $cfs.trigger('linkAnchors');
                setSizes($cfs, opts, false);

                if (opts.items.start !== 0 && opts.items.start !== false) {
                        var s = opts.items.start;
                        if (s === true) {
                                s = window.location.hash;
                                if (!s.length) s = 0;
                        }
                        if (s === 'random') {
                                s = Math.floor(Math.random() * totalItems);
                        }
                        $cfs.trigger('slideTo', [s, 0, true, { duration: 0 }]);
                }
                return this;
        };


        //        public
        $.fn.carouFredSel.defaults = {
                infinite: true,
                circular: true,
                direction: 'left',
                items: {
                        start: 0
                },
                scroll: {
                        easing: 'swing',
                        pauseOnHover: false,
                        mousewheel: false
                }
        };

        $.fn.carouFredSel.pageAnchorBuilder = function(nr, itm) {
                return '<a href="#"><span>'+nr+'</span></a>';
        };


        //        private
        function fx_fade(sO, c, x, d, f) {
                var o = {
                        duration: d,
                        easing: sO.easing
                };
                if (typeof f == 'function') o.complete = f;
                c.animate({
                        opacity: x
                }, o);
        }
        function fx_cover(sO, c1, c2, o, d, prev) {
                var cur_w = getSizes(getItems(c2), o, true)[0],
                        cur_p = (prev) ? -cur_w : cur_w,
                        css_o = {},
                        ani_o = {};
                css_o[o.dimensions[0]] = cur_w;
                css_o[o.dimensions[6]] = cur_p;
                ani_o[o.dimensions[6]] = 0;
                c1.animate({ opacity: '+=0' }, d);
                c2.css(css_o).animate(ani_o, {
                        duration: d,
                        easing: sO.easing,
                        complete: function() {
                                $(this).remove();
                        }
                });
        }
        function fx_uncover(sO, c, o, d, prev) {
                var cur_w = getSizes(getItems(c), o, true)[0],
                        cur_p = (prev) ? cur_w : -cur_w,
                        css_o = {},
                        ani_o = {};
                css_o[o.dimensions[0]] = cur_w;
                ani_o[o.dimensions[6]] = cur_p;
                c.css(css_o).animate(ani_o, {
                        duration: d,
                        easing: sO.easing,
                        complete: function() {
                                $(this).remove();
                        }
                });
        }

        function showNavi(o, t) {
                if (t == 'show' || t == 'hide') {
                        var f = t;
                } else if (o.items.minimum >= t) {
                        log('Not enough items: not scrolling');
                        var f = 'hide';
                } else {
                        var f = 'show';
                }
                if (o.prev.button) o.prev.button[f]();
                if (o.next.button) o.next.button[f]();
                if (o.pagination.container) o.pagination.container[f]();
        }
        function enableNavi(o, f) {
                if (o.circular || o.infinite) return;
                var fx = (f == 'removeClass' || f == 'addClass') ? f : false;
                if (o.next.button) {
                        var fn = fx || (f == o.items.visible) ? 'addClass' : 'removeClass';
                        o.next.button[fn]('disabled');
                }
                if (o.prev.button) {
                        var fn = fx || (f == 0) ? 'addClass' : 'removeClass';
                        o.prev.button[fn]('disabled');
                }
        }
        function getKeyCode(k) {
                if (k == 'right')        return 39;
                if (k == 'left')        return 37;
                if (k == 'up')                return 38;
                if (k == 'down')        return 40;
                return -1;
        }
        function getObject(obj) {
                if (typeof obj == 'undefined') obj = {};
                return obj;
        }
        function getNaviObject(obj, pagi, auto) {
                if (typeof pagi != 'boolean') pagi = false;
                if (typeof auto != 'boolean') auto = false;

                obj = getObject(obj);
                if (typeof obj == 'string') {
                        var temp = getKeyCode(obj);
                        if (temp == -1) obj = $(obj);
                        else                         obj = temp;
                }

                //        pagination
                if (pagi) {
                        if (typeof obj                                 == 'boolean')        obj = { keys: obj };
                        if (typeof obj.jquery                 != 'undefined')        obj = { container: obj };
                        if (typeof obj.container        == 'string')        obj.container = $(obj.container);

                //        auto
                } else if (auto) {
                        if (typeof obj == 'boolean')                                obj = { play: obj };
                        if (typeof obj == 'number')                                        obj = { pauseDuration: obj };
                        if (typeof obj.timer != 'object')                        obj.timer = {};


                //        prev + next
                } else {
                        if (typeof obj.jquery        != 'undefined')                obj = { button: obj };
                        if (typeof obj                         == 'number')                obj = { key: obj };
                        if (typeof obj.button        == 'string')                obj.button = $(obj.button);
                        if (typeof obj.key                == 'string')                obj.key = getKeyCode(obj.key);
                }
                return obj;
        }
        function getItemIndex(num, dev, org, firstItem, totalItems, $cfs) {
                if (typeof num == 'string') {
                        if (isNaN(num)) num = $(num);
                        else                         num = parseInt(num);
                }
                if (typeof num == 'object') {
                        if (typeof num.jquery == 'undefined') num = $(num);
                        num = getItems($cfs).index(num);
                        if (num == -1) num = 0;
                        if (typeof org != 'boolean') org = false;
                } else {
                        if (typeof org != 'boolean') org = true;
                }
                if (isNaN(num))        num = 0;
                else                         num = parseInt(num);
                if (isNaN(dev))        dev = 0;
                else                         dev = parseInt(dev);

                if (org) {
                        num += firstItem;
                }
                num += dev;
                if (totalItems > 0) {
                        while (num >= totalItems)        {        num -= totalItems; }
                        while (num < 0)                                {        num += totalItems; }
                }
                return num;
        }

        function getItems(c, f) {
                if (typeof f != 'string') f = '';
                return $('> *'+f, c);
        }
        function getCurrentItems(c, o) {
                return getItems(c, ':lt('+o.items.visible+')');
        }
        function getOldItemsPrev(c, o, n) {
                return getItems(c, ':lt('+(o.items.oldVisible+n)+'):gt('+(n-1)+')');
        }
        function getNewItemsPrev(c, o) {
                return getItems(c, ':lt('+o.items.visible+')');
        }
        function getOldItemsNext(c, o) {
                return getItems(c, ':lt('+o.items.oldVisible+')');
        }
        function getNewItemsNext(c, o, n) {
                return getItems(c, ':lt('+(o.items.visible+n)+'):gt('+(n-1)+')');
        }

        function resetMargin(i, o, m) {
                var x = (typeof m == 'boolean') ? m : false;
                if (typeof m != 'number') m = 0;
                i.each(function() {
                        var t = parseInt($(this).css(o.dimensions[8]));
                        if (isNaN(t)) t = 0;
                        $(this).data('cfs_tempCssMargin', t);
                        $(this).css(o.dimensions[8], ((x) ? $(this).data('cfs_tempCssMargin') : m + $(this).data('cfs_origCssMargin')));
                });
        }
        function getSizes(i, o, wrapper) {
                s1 = getTotalSize(i, o, 0, wrapper);
                s2 = getLargestSize(i, o, 3, wrapper);
                return [s1, s2];
        }
        function getLargestSize(i, o, dim, wrapper) {
                if (typeof wrapper != 'boolean') wrapper = false;
                if (typeof o[o.dimensions[dim]] == 'number' && wrapper) return o[o.dimensions[dim]];
                if (typeof o.items[o.dimensions[dim]] == 'number') return o.items[o.dimensions[dim]];
                return getTrueLargestSize(i, o, dim+2);
        }
        function getTrueLargestSize(i, o, dim) {
                var s = 0;
                i.each(function() {
                        var m = $(this)[o.dimensions[dim]](true);
                        if (s < m) s = m;
                });
                return s;
        }
        function getTrueInnerSize($el, o, dim) {
                var siz = $el[o.dimensions[dim]](),
                        arr = (o.dimensions[dim].toLowerCase().indexOf('width') > -1) ? ['paddingLeft', 'paddingRight'] : ['paddingTop', 'paddingBottom'];
                for (a = 0; a < arr.length; a++) {
                        var m = parseInt($el.css(arr[a]));
                        if (isNaN(m)) m = 0;
                        siz -= m;
                }
                return siz;
        }
        function getTotalSize(i, o, dim, wrapper) {
                if (typeof wrapper != 'boolean') wrapper = false;
                if (typeof o[o.dimensions[dim]] == 'number' && wrapper) return o[o.dimensions[dim]];
                if (typeof o.items[o.dimensions[dim]] == 'number') return o.items[o.dimensions[dim]] * i.length;
                return getTotalSizeVariable(i, o, dim+2);
        }
        function getTotalSizeVariable(i, o, dim) {
                var s = 0;
                i.each(function() {
                        s += $(this)[o.dimensions[dim]](true);
                });
                return s;
        }

        function hasVariableSizes(i, o, dim) {
                var s = false,
                        v = false;
                i.each(function() {
                        c = $(this)[o.dimensions[dim]]();
                        if (s === false) s = c;
                        else if (s != c) v = true;
                });
                return v;
        }

        function mapWrapperSizes(ws, o, p) {
                if (typeof p != 'boolean') p = true;
                var pad = (o.usePadding && p) ? o.padding : [0, 0, 0, 0];
                var wra = {};
                        wra[o.dimensions[0]] = ws[0] + pad[1] + pad[3];
                        wra[o.dimensions[3]] = ws[1] + pad[0] + pad[2];

                return wra;
        }
        function setSizes($c, o, p) {
                var $w = $c.parent(),
                        $i = getItems($c),
                        $l = $i.filter(':eq('+(o.items.visible-1)+')');

                $w.css(mapWrapperSizes(getSizes($i.filter(':lt('+o.items.visible+')'), o, true), o, p));

                if (o.usePadding) {
                        $l.css(o.dimensions[8], $l.data('cfs_origCssMargin') + o.padding[o.dimensions[10]]);
                        $c.css(o.dimensions[7], o.padding[o.dimensions[9]]);
                        $c.css(o.dimensions[6], o.padding[o.dimensions[12]]);
                }
                $c.css(o.dimensions[0], getTotalSize($i, o, 0)*2);
                $c.css(o.dimensions[3], getLargestSize($i, o, 3));
        }

        function getPadding(p) {
                if (typeof p == 'undefined') return [0, 0, 0, 0];

                if (typeof p == 'number') return [p, p, p, p];
                else if (typeof p == 'string') p = p.split('px').join('').split(' ');

                if (typeof p != 'object') {
                        return [0, 0, 0, 0];
                }
                for (i in p) {
                        p[i] = parseInt(p[i]);
                }
                switch (p.length) {
                        case 0: return [0, 0, 0, 0];
                        case 1: return [p[0], p[0], p[0], p[0]];
                        case 2: return [p[0], p[1], p[0], p[1]];
                        case 3: return [p[0], p[1], p[2], p[1]];
                        default: return [p[0], p[1], p[2], p[3]];
                }
        }
        function getAutoPadding(itm, o) {
                var        wiz = (typeof o[o.dimensions[3]] == 'number') ? o[o.dimensions[3]] : getLargestSize(itm, o, 3);
                return [(o[o.dimensions[0]] - getTotalSize(itm, o, 0)) / 2, (wiz - getLargestSize(itm, o, 3)) / 2];
        }

        function getVisibleItemsPrev($c, o, nI) {
                var items = getItems($c),
                        total = 0,
                        start = o.items.visible - nI - 1,
                        x = 0;

                if (start < 0) start = items.length-1;
                for (var a = start; a >= 0; a--) {
                        total += items.filter(':eq('+ a +')')[o.dimensions[2]](true);
                        if (total > o.maxDimention) return x;
                        if (a == 0) a = items.length;
                        x++;
                }
        }
        function getVisibleItemsNext($c, o, nI) {
                var items = getItems($c),
                        total = 0,
                        x = 0;

                for (var a = nI; a <= items.length-1; a++) {
                        total += items.filter(':eq('+ a +')')[o.dimensions[2]](true);
                        if (total > o.maxDimention) return x;
                        if (a == items.length-1) a = -1;
                        x++;
                }
        }

        function log(m) {
                if (typeof m == 'string') m = 'carouFredSel: ' + m;
                if (window.console && window.console.log) window.console.log(m);
                else try { console.log(m); } catch(err) { }
                return false;
        }



        $.fn.caroufredsel = function(o) {
                return this.carouFredSel(o);
        };

})(jQuery);
