/**
 * jCarouselLite 1.0.9 - jQuery plugin to navigate images/any content in a Carousel style widget.
 * http://gmarwaha.com/jquery/jCarousellite/
 * Copyright (c) 2007 Ganeshji Marwaha (gmarwaha.com)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
 (function ($) {
    $.fn.jCarouselLite = function (o) {
        o = $.extend({
            btnPrev: null,
            btnNext: null,
            btnGo: null,
            mouseWheel: false,
            auto: null,
            speed: 200,
            easing: null,
            vertical: false,
            circular: true,
            visible: 3,
            start: 0,
            scroll: 1,
            beforeStart: null,
            afterEnd: null
        }, o || {});

        return this.each(function () { // Returns the element collection. Chainable.

            var running = false,
                animCss = o.vertical ? "top" : "left",
                sizeCss = o.vertical ? "height" : "width",
                sizeAlt = o.vertical ? "width" : "height",
                c = $(this),        // main Carousel element
                ul = $("ul", c),
                tLi = $("li", ul),  // LI tags
                numOriginalItems = tLi.size(),    // num li tags
                numVisible = o.visible,      // num li tags visible at a time
                timer;
            if (o.circular) {
                ul.prepend(tLi.slice(numOriginalItems - numVisible).clone())     // prepend last LI to list
                  .append(tLi.slice(0, numVisible).clone());             // append first LI to list
                o.start += numVisible;
            }

            tLi = $("li", ul);      // get LIs again (including ones we just added)
            var numItems = tLi.size();

            //var f = $("li", ul),
            var curr = o.start;
            c.css("visibility", "visible");
            tLi.css({
                overflow: "hidden",
                float: o.vertical ? "none" : "left"
            });
            ul.css({
                margin: "0",
                padding: "0",
                position: "relative",
                "list-style-type": "none",
                "z-index": "1"
            });
            c.css({
                overflow: "hidden",
                position: "relative",
                "z-index": "2",
                left: "0px"
            });
            var mW = 0,     // width of widest LI
                mH = 0;     // height of highest LI
            tLi.each(function () {
                var s = $(this);
                mW = Math.max(mW, s.width());
                mH = Math.max(mH, s.height());
            });
            var liWidth = o.vertical ? mH : mW,	    	// Full li size (incl margin) - Used for animation
                visibleWidth = liWidth * numVisible,				// Visible width of UL		
                ulWidthFull = liWidth * numItems;       // size of full ul (total length, not just for the visible items)
            //console.log('setting width', tLi)
            tLi.css({
                width: mW /*,
                height: mH*/
            });
            ul.css(sizeCss, ulWidthFull + "px").css(animCss, -(curr * liWidth));
            c.css(sizeCss, visibleWidth + "px");
            c.css(sizeAlt, (o.vertical ? mW : mH) + 'px');

            // Previous button action
            if (o.btnPrev) c.parent().find(o.btnPrev).click(function () {
                return go(curr - o.scroll)
            });

            // Next button action
            if (o.btnNext) c.parent().find(o.btnNext).click(function () {
                return go(curr + o.scroll)
            });

            // Play/Go button action
            if (o.btnGo) $.each(o.btnGo, function (i, a) {
                $(a).click(function () {
                    return go(o.circular ? o.visible + i : i)
                })
            });

            // Mousewheel support
            if (o.mouseWheel && c.mousewheel) c.mousewheel(function (e, d) {
                return d > 0 ? go(curr - o.scroll) : go(curr + o.scroll)
            });

            // Listen for event, sets auto-scrolling to true/false
            c.bind('changeAuto', function (e, a) {
                if (timer) clearInterval(timer);
                if (a) {
                    o.auto = a;
                    timer = setInterval(function () {
                        go(curr + o.scroll)
                    }, o.auto + o.speed)
                }
            });
            if (o.auto) c.trigger('changeAuto', [o.auto]);

            function vis() {
                return tLi.slice(curr).slice(0, numVisible)      
            };

            // Do the scrolling thing...
            function go(itemIndex) {
                if (running) { return false }

				if (o.beforeStart) o.beforeStart.call(this, vis());

				// Do circular wrap-around magic if necessary
				if (o.circular) {
					if (itemIndex <= o.start - numVisible - 1) {
						ul.css(animCss, -((numItems - (numVisible * 2)) * liWidth) + "px");
						curr = itemIndex == o.start - numVisible - 1 ? numItems - (numVisible * 2) - 1 : numItems - (numVisible * 2) - o.scroll
					} else if (itemIndex >= numItems - numVisible + 1) {
						ul.css(animCss, -((numVisible) * liWidth) + "px");
						curr = itemIndex == numItems - numVisible + 1 ? numVisible + 1 : numVisible + o.scroll
					} else curr = itemIndex
				} else {
					if (itemIndex < 0) curr = 0;
					else if (itemIndex > numItems - numVisible) curr = numItems - numVisible;
					else curr = itemIndex;
				}

				running = true;
				ul.animate(animCss == "left" ? {
					left: -(curr * liWidth)
				} : {
					top: -(curr * liWidth)
				}, o.speed, o.easing, function () {
					if (o.afterEnd) o.afterEnd.call(this, vis());
					running = false
				});

				
				// Disable buttons when the Carousel reaches the last/first, and enable when not
				if (!o.circular) {
					c.parent().find(o.btnPrev + ',' + o.btnNext).removeClass("disabled");
				
					if (curr == 0)
						c.parent().find(o.btnPrev).addClass("disabled");
					if (curr + numVisible >= numItems)
						c.parent().find(o.btnNext).addClass("disabled");
				}
                
                return false;
            };

            // Listen for event (parameter = number of )
            c.bind('slideGo', function (e, numToScroll) {
                go(curr + numToScroll)
            });
            c.bind('slideGoTo', function (e, s) {
                go(s.index())
            });
        });
    };

    function css(el, prop) {
        return parseInt($.css(el[0], prop)) || 0;
    };

    function width(el) {
        return el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
    };

    function height(el) {
        return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
    };

    function maxHeight(jqItems) {
        //console.log(jqItems);
        var num = jqItems.size();
        var mh = jqItems.eq(0).height();
        for (var i=1; i<num; i++) { mh = Math.max(mh, jqItems.eq(i).height()) }
        return mh;
    }
})(jQuery);
