﻿(function($) {
    $.fn.carousel = function(options) {

        var settings = {
            scroller: "", //id for main scroller area
            scrollList: 'div#scroller_window ul',
            counter: '#scroll_count',
            nextLink: 'li#scroll_next a',
            previousLink: 'li#scroll_prev a',
            scrollDistance: 462,
            displayCount: 1, //the number of items displayed
            anime: false, //whethe the current item in the list will have animation
            expandDistance: 85, //width to expand to for current item, only used when expand = true
            animeNormal: {}, //animation to be used for the normal list item
            animeCurrentSib: {}, //animation to be used for the current item sibiling
            animeCurrent: {}, //animcation to be used for the current item
            randomize: false,
            autoscroll: false,
            horizontal: true, //whether carousel rotates horizontally or vertically,
            speed: 500//speed for animation
        };

        // override setting defaults with any passed in settings
        if (options) {
            jQuery.extend(settings, options);
        }

        return this.each(function() {
            var scrollerlist = $(this).find(settings.scrollList),
                listcount, left, scrolling = false, current = 1, me = this, currentel,
                lefttop = (settings.horizontal === true) ? 'left' : 'top';

            function goNext() {
                if (!scrolling) {
                    left -= settings.scrollDistance;
                    scrolling = true;

                    if (settings.anime === true) {

                        currentel.prev().find('a')
                        .animate(settings.animeNormal, settings.speed)
                        .parent().removeClass("next");

                        currentel.find('a')
                        .animate(settings.animeCurrentSib, settings.speed).parent()
                        .removeClass("current").addClass("next");

                        currentel.next().find('a')
                        .animate(settings.animeCurrent, settings.speed)
                        .parent().addClass("current");

                        currentel.next().next().find('a')
                        .animate(settings.animeCurrentSib, settings.speed)
                        .parent().addClass("next");

                    }

                    var animeScroll = (settings.horizontal === true) ? { left: left + "px"} : { top: left + "px" };

                    scrollerlist.animate(animeScroll, settings.speed, 'swing', function() {
                        //count display
                        current += 1;
                        if (current > listcount) { current = 1; }
                        $(me).find(settings.counter).text(current + ' of ' + listcount);
                        //rearrang list
                        endCheck();
                        currentel = currentel.next();
                        //release lock
                        scrolling = false;
                        if (settings.autoscroll) { goNext(); }
                    });
                }
                return false;
            }

            function endCheck() {
                if ((settings.scrollDistance * settings.displayCount - left - (settings.scrollDistance * listcount)) === 0) {
                    //at end
                    scrollerlist.find('li:first').appendTo(scrollerlist);
                    left += settings.scrollDistance;
                    scrollerlist.css(lefttop, left + "px");
                }
            }

            function goPrev() {
                if (!scrolling) {
                    //rearrange list
                    if (left === 0) {
                        //at start
                        scrollerlist.find('li:last').prependTo(scrollerlist);
                        left -= settings.scrollDistance;
                        scrollerlist.css(lefttop, left + "px");
                    }
                    left += settings.scrollDistance;
                    scrolling = true;
                    if (settings.anime === true) {
                        currentel.find('a')
                        .animate(settings.animeCurrentSib, settings.speed).parent()
                        .removeClass("current").addClass("next");

                        currentel.prev().find('a')
                        .animate(settings.animeCurrent, settings.speed).parent()
                        .removeClass("next").addClass("current");

                        currentel.prev().prev().find('a')
                        .animate(settings.animeCurrentSib, settings.speed).parent()
                        .addClass("next");

                        currentel.next().find('a')
                        .animate(settings.animeNormal, settings.speed).parent()
                        .removeClass("next");
                    }
                    var animeScroll = (settings.horizontal === true) ? { left: left + "px"} : { top: left + "px" };
                    scrollerlist.animate(animeScroll, settings.speed, 'swing', function() {
                        //count display
                        current -= 1;
                        if (current < 1) { current = listcount; }
                        $(me).find(settings.counter).text(current + ' of ' + listcount);
                        currentel = currentel.prev();
                        //release lock
                        scrolling = false;
                    });
                }
                return false;
            }

            function randomize() {
                if (listcount > 1) {
                    var $children = scrollerlist.children('li');
                    var indices = new Array();
                    for (i = 0; i < listcount; i++) { indices[indices.length] = i; }
                    indices = indices.sort(randOrd);
                    $.each(indices, function(j, k) { scrollerlist.append($children.eq(k)); });
                }
            }

            //triggered by the jumptoid custom event
            //not build to handle displaying x of x yet
            function jumpTo(e, id) {
                var $children = scrollerlist.children('li'),
                    jumpEl = $('#' + id, scrollerlist),
                    cur_ix = $children.index(currentel),
                    to_ix = $children.index(jumpEl),
                    moveamnt = settings.scrollDistance * (to_ix - cur_ix);
                left = parseInt(scrollerlist.css(lefttop)) - moveamnt;
                if (moveamnt != 0) {
                    scrollerlist.css(lefttop, left);
                    endCheck();
                    currentel = jumpEl;
                }
            }

            //to randomize an array
            function randOrd() {
                return (Math.round(Math.random()) - 0.5);
            }

            function init() {
                listcount = scrollerlist.find('li').length; left = 0; scrolling = false; current = 1;
                var dim = (settings.horizontal === true) ? 'width' : 'height',
                size = (settings.anime === false) ? (settings.scrollDistance * listcount) : (settings.scrollDistance * (listcount - 1) + settings.expandDistance);
                scrollerlist.css(dim, size + "px").css(lefttop, "0px").show();
                currentel = (settings.anime) ? scrollerlist.find('li.current') : scrollerlist.children('li:first');
                $(me).bind('jumptoid', jumpTo);
            }

            init();

            this.reload = function() { init(); };

            if (settings.randomize) {
                randomize();
            }
            //setup clicks
            if (settings.autoscroll) {
                goNext();
            } else {
                $(this).find(settings.nextLink).click(goNext).end()
                    .find(settings.previousLink).click(goPrev).end()
                    .find(settings.counter).text(current + ' of ' + listcount);
            }

        }); //each function
    }; //scroller function
})(jQuery);
