/*!
 * jCarousel - Riding carousels with jQuery
 *   http://sorgalla.com/jcarousel/
 *
 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Built on top of the jQuery library
 *   http://jquery.com
 *
 * Inspired by the "Carousel Component" by Bill Scott
 *   http://billwscott.com/carousel/
 */

(function(i) {
    var q = {vertical:false,rtl:false,start:1,offset:1,size:null,scroll:1,visible:null,animation:"slow",easing:"swing",auto:4,wrap:'circular',initCallback:null,reloadCallback:null,itemLoadCallback:null,itemFirstInCallback:null,itemFirstOutCallback:null,itemLastInCallback:null,itemLastOutCallback:null,itemVisibleInCallback:null,itemVisibleOutCallback:null,buttonNextHTML:"<div></div>",buttonPrevHTML:"<div></div>",buttonNextEvent:"click",buttonPrevEvent:"click",buttonNextCallback:null,buttonPrevCallback:null, itemFallbackDimension:null},r = false;
    i(window).bind("load.jcarousel", function() {
        r = true
    });
    i.jcarousel = function(a, c) {
        this.options = i.extend({}, q, c || {});
        this.autoStopped = this.locked = false;
        this.buttonPrevState = this.buttonNextState = this.buttonPrev = this.buttonNext = this.list = this.clip = this.container = null;
        if (!c || c.rtl === undefined)this.options.rtl = (i(a).attr("dir") || i("html").attr("dir") || "").toLowerCase() == "rtl";
        this.wh = !this.options.vertical ? "width" : "height";
        this.lt = !this.options.vertical ? this.options.rtl ? "right" : "left" : "top";
        for (var b = "",d = a.className.split(" "),f = 0; f < d.length; f++)if (d[f].indexOf("jcarousel-skin") != -1) {
            i(a).removeClass(d[f]);
            b = d[f];
            break
        }
        if (a.nodeName.toUpperCase() == "UL" || a.nodeName.toUpperCase() == "OL") {
            this.list = i(a);
            this.container = this.list.parent();
            if (this.container.hasClass("jcarousel-clip")) {
                if (!this.container.parent().hasClass("jcarousel-container"))this.container = this.container.wrap("<div></div>");
                this.container = this.container.parent()
            } else if (!this.container.hasClass("jcarousel-container"))this.container = this.list.wrap("<div></div>").parent()
        } else {
            this.container = i(a);
            this.list = this.container.find("ul,ol").eq(0)
        }
        b !== "" && this.container.parent()[0].className.indexOf("jcarousel-skin") == -1 && this.container.wrap('<div class=" ' + b + '"></div>');
        this.clip = this.list.parent();
        if (!this.clip.length || !this.clip.hasClass("jcarousel-clip"))this.clip = this.list.wrap("<div></div>").parent();
        this.buttonNext = i(".jcarousel-next", this.container);
        if (this.buttonNext.size() === 0 && this.options.buttonNextHTML !== null)this.buttonNext = this.clip.after(this.options.buttonNextHTML).next();
        this.buttonNext.addClass(this.className("jcarousel-next"));
        this.buttonPrev = i(".jcarousel-prev", this.container);
        if (this.buttonPrev.size() === 0 && this.options.buttonPrevHTML !== null)this.buttonPrev = this.clip.after(this.options.buttonPrevHTML).next();
        this.buttonPrev.addClass(this.className("jcarousel-prev"));
        this.clip.addClass(this.className("jcarousel-clip")).css({overflow:"hidden",position:"relative"});
        this.list.addClass(this.className("jcarousel-list")).css({overflow:"hidden", position:"relative",top:0,margin:0,padding:0}).css(this.options.rtl ? "right" : "left", 0);
        this.container.addClass(this.className("jcarousel-container")).css({position:"relative"});
        !this.options.vertical && this.options.rtl && this.container.addClass("jcarousel-direction-rtl").attr("dir", "rtl");
        var j = this.options.visible !== null ? Math.ceil(this.clipping() / this.options.visible) : null;
        b = this.list.children("li");
        var e = this;
        if (b.size() > 0) {
            var g = 0,k = this.options.offset;
            b.each(function() {
                e.format(this, k++);
                g += e.dimension(this, j)
            });
            this.list.css(this.wh, g + 100 + "px");
            if (!c || c.size === undefined)this.options.size = b.size()
        }
        this.container.css("display", "block");
        this.buttonNext.css("display", "block");
        this.buttonPrev.css("display", "block");
        this.funcNext = function() {
            e.next()
        };
        this.funcPrev = function() {
            e.prev()
        };
        this.funcResize = function() {
            e.reload()
        };
        this.options.initCallback !== null && this.options.initCallback(this, "init");
        if (!r && i.browser.safari) {
            this.buttons(false, false);
            i(window).bind("load.jcarousel", function() {
                e.setup()
            })
        } else this.setup()
    };
    var h = i.jcarousel;
    h.fn = h.prototype = {jcarousel:"0.2.7"};
    h.fn.extend = h.extend = i.extend;
    h.fn.extend({setup:function() {
        this.prevLast = this.prevFirst = this.last = this.first = null;
        this.animating = false;
        this.tail = this.timer = null;
        this.inTail = false;
        if (!this.locked) {
            this.list.css(this.lt, this.pos(this.options.offset) + "px");
            var a = this.pos(this.options.start, true);
            this.prevFirst = this.prevLast = null;
            this.animate(a, false);
            i(window).unbind("resize.jcarousel", this.funcResize).bind("resize.jcarousel", this.funcResize)
        }
    }, reset:function() {
        this.list.empty();
        this.list.css(this.lt, "0px");
        this.list.css(this.wh, "10px");
        this.options.initCallback !== null && this.options.initCallback(this, "reset");
        this.setup()
    },reload:function() {
        this.tail !== null && this.inTail && this.list.css(this.lt, h.intval(this.list.css(this.lt)) + this.tail);
        this.tail = null;
        this.inTail = false;
        this.options.reloadCallback !== null && this.options.reloadCallback(this);
        if (this.options.visible !== null) {
            var a = this,c = Math.ceil(this.clipping() / this.options.visible),b = 0,d = 0;
            this.list.children("li").each(function(f) {
                b += a.dimension(this, c);
                if (f + 1 < a.first)d = b
            });
            this.list.css(this.wh, b + "px");
            this.list.css(this.lt, -d + "px")
        }
        this.scroll(this.first, false)
    },lock:function() {
        this.locked = true;
        this.buttons()
    },unlock:function() {
        this.locked = false;
        this.buttons()
    },size:function(a) {
        if (a !== undefined) {
            this.options.size = a;
            this.locked || this.buttons()
        }
        return this.options.size
    },has:function(a, c) {
        if (c === undefined || !c)c = a;
        if (this.options.size !== null && c > this.options.size)c = this.options.size;
        for (var b = a; b <= c; b++) {
            var d = this.get(b);
            if (!d.length || d.hasClass("jcarousel-item-placeholder"))return false
        }
        return true
    },get:function(a) {
        return i(".jcarousel-item-" + a, this.list)
    },add:function(a, c) {
        var b = this.get(a),d = 0,f = i(c);
        if (b.length === 0) {
            var j,e = h.intval(a);
            for (b = this.create(a); ;) {
                j = this.get(--e);
                if (e <= 0 || j.length) {
                    e <= 0 ? this.list.prepend(b) : j.after(b);
                    break
                }
            }
        } else d = this.dimension(b);
        if (f.get(0).nodeName.toUpperCase() == "LI") {
            b.replaceWith(f);
            b = f
        } else b.empty().append(c);
        this.format(b.removeClass(this.className("jcarousel-item-placeholder")), a);
        f = this.options.visible !== null ? Math.ceil(this.clipping() / this.options.visible) : null;
        d = this.dimension(b, f) - d;
        a > 0 && a < this.first && this.list.css(this.lt, h.intval(this.list.css(this.lt)) - d + "px");
        this.list.css(this.wh, h.intval(this.list.css(this.wh)) + d + "px");
        return b
    },remove:function(a) {
        var c = this.get(a);
        if (!(!c.length || a >= this.first && a <= this.last)) {
            var b = this.dimension(c);
            a < this.first && this.list.css(this.lt, h.intval(this.list.css(this.lt)) + b + "px");
            c.remove();
            this.list.css(this.wh, h.intval(this.list.css(this.wh)) - b + "px")
        }
    },next:function() {
        this.tail !== null && !this.inTail ? this.scrollTail(false) : this.scroll((this.options.wrap == "both" || this.options.wrap == "last") && this.options.size !== null && this.last == this.options.size ? 1 : this.first + this.options.scroll)
    },prev:function() {
        this.tail !== null && this.inTail ? this.scrollTail(true) : this.scroll((this.options.wrap == "both" || this.options.wrap == "first") && this.options.size !== null && this.first == 1 ? this.options.size : this.first - this.options.scroll)
    },scrollTail:function(a) {
        if (!(this.locked || this.animating || !this.tail)) {
            this.pauseAuto();
            var c = h.intval(this.list.css(this.lt));
            c = !a ? c - this.tail : c + this.tail;
            this.inTail = !a;
            this.prevFirst = this.first;
            this.prevLast = this.last;
            this.animate(c)
        }
    },scroll:function(a, c) {
        if (!(this.locked || this.animating)) {
            this.pauseAuto();
            this.animate(this.pos(a), c)
        }
    },pos:function(a, c) {
        var b = h.intval(this.list.css(this.lt));
        if (this.locked || this.animating)return b;
        if (this.options.wrap != "circular")a = a < 1 ? 1 : this.options.size && a > this.options.size ? this.options.size : a;
        for (var d = this.first > a,f = this.options.wrap != "circular" && this.first <= 1 ? 1 : this.first,j = d ? this.get(f) : this.get(this.last),e = d ? f : f - 1,g = null,k = 0,l = false,m = 0; d ? --e >= a : ++e < a;) {
            g = this.get(e);
            l = !g.length;
            if (g.length === 0) {
                g = this.create(e).addClass(this.className("jcarousel-item-placeholder"));
                j[d ? "before" : "after"](g);
                if (this.first !== null && this.options.wrap == "circular" && this.options.size !== null && (e <= 0 || e > this.options.size)) {
                    j = this.get(this.index(e));
                    if (j.length)g = this.add(e, j.clone(true))
                }
            }
            j = g;
            m = this.dimension(g);
            if (l)k += m;
            if (this.first !== null && (this.options.wrap == "circular" || e >= 1 && (this.options.size === null || e <= this.options.size)))b = d ? b + m : b - m
        }
        f = this.clipping();
        var p = [],o = 0,n = 0;
        j = this.get(a - 1);
        for (e = a; ++o;) {
            g = this.get(e);
            l = !g.length;
            if (g.length === 0) {
                g = this.create(e).addClass(this.className("jcarousel-item-placeholder"));
                j.length === 0 ? this.list.prepend(g) : j[d ? "before" : "after"](g);
                if (this.first !== null && this.options.wrap == "circular" && this.options.size !== null && (e <= 0 || e > this.options.size)) {
                    j = this.get(this.index(e));
                    if (j.length)g = this.add(e, j.clone(true))
                }
            }
            j = g;
            m = this.dimension(g);
            if (m === 0)throw Error("jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...");
            if (this.options.wrap != "circular" && this.options.size !== null && e > this.options.size)p.push(g); else if (l)k += m;
            n += m;
            if (n >= f)break;
            e++
        }
        for (g = 0; g < p.length; g++)p[g].remove();
        if (k > 0) {
            this.list.css(this.wh, this.dimension(this.list) + k + "px");
            if (d) {
                b -= k;
                this.list.css(this.lt, h.intval(this.list.css(this.lt)) - k + "px")
            }
        }
        k = a + o - 1;
        if (this.options.wrap != "circular" && this.options.size && k > this.options.size)k = this.options.size;
        if (e > k) {
            o = 0;
            e = k;
            for (n = 0; ++o;) {
                g = this.get(e--);
                if (!g.length)break;
                n += this.dimension(g);
                if (n >= f)break
            }
        }
        e = k - o + 1;
        if (this.options.wrap != "circular" && e < 1)e = 1;
        if (this.inTail && d) {
            b += this.tail;
            this.inTail = false
        }
        this.tail = null;
        if (this.options.wrap != "circular" && k == this.options.size && k - o + 1 >= 1) {
            d = h.margin(this.get(k), !this.options.vertical ? "marginRight" : "marginBottom");
            if (n - d > f)this.tail = n - f - d
        }
        if (c && a === this.options.size && this.tail) {
            b -= this.tail;
            this.inTail = true
        }
        for (; a-- > e;)b += this.dimension(this.get(a));
        this.prevFirst = this.first;
        this.prevLast = this.last;
        this.first = e;
        this.last = k;
        return b
    },animate:function(a, c) {
        if (!(this.locked || this.animating)) {
            this.animating = true;
            var b = this,d = function() {
                b.animating = false;
                a === 0 && b.list.css(b.lt, 0);
                if (!b.autoStopped && (b.options.wrap == "circular" || b.options.wrap == "both" || b.options.wrap == "last" || b.options.size === null || b.last < b.options.size || b.last == b.options.size && b.tail !== null && !b.inTail))b.startAuto();
                b.buttons();
                b.notify("onAfterAnimation");
                if (b.options.wrap == "circular" && b.options.size !== null)for (var f = b.prevFirst; f <= b.prevLast; f++)if (f !== null && !(f >= b.first && f <= b.last) && (f < 1 || f > b.options.size))b.remove(f)
            };
            this.notify("onBeforeAnimation");
            if (!this.options.animation || c === false) {
                this.list.css(this.lt, a + "px");
                d()
            } else this.list.animate(!this.options.vertical ? this.options.rtl ? {right:a} : {left:a} : {top:a}, this.options.animation, this.options.easing, d)
        }
    },startAuto:function(a) {
        if (a !== undefined)this.options.auto = a;
        if (this.options.auto === 0)return this.stopAuto();
        if (this.timer === null) {
            this.autoStopped = false;
            var c = this;
            this.timer = window.setTimeout(function() {
                c.next()
            }, this.options.auto * 1E3)
        }
    },stopAuto:function() {
        this.pauseAuto();
        this.autoStopped = true
    },pauseAuto:function() {
        if (this.timer !== null) {
            window.clearTimeout(this.timer);
            this.timer = null
        }
    },buttons:function(a, c) {
        if (a == null) {
            a = !this.locked && this.options.size !== 0 && (this.options.wrap && this.options.wrap != "first" || this.options.size === null || this.last < this.options.size);
            if (!this.locked && (!this.options.wrap || this.options.wrap == "first") && this.options.size !== null && this.last >= this.options.size)a = this.tail !== null && !this.inTail
        }
        if (c == null) {
            c = !this.locked && this.options.size !== 0 && (this.options.wrap && this.options.wrap != "last" || this.first > 1);
            if (!this.locked && (!this.options.wrap || this.options.wrap == "last") && this.options.size !== null && this.first == 1)c = this.tail !== null && this.inTail
        }
        var b = this;
        if (this.buttonNext.size() > 0) {
            this.buttonNext.unbind(this.options.buttonNextEvent + ".jcarousel", this.funcNext);
            a && this.buttonNext.bind(this.options.buttonNextEvent + ".jcarousel", this.funcNext);
            this.buttonNext[a ? "removeClass" : "addClass"](this.className("jcarousel-next-disabled")).attr("disabled", a ? false : true);
            this.options.buttonNextCallback !== null && this.buttonNext.data("jcarouselstate") != a && this.buttonNext.each(
                                                                                                                           function() {
                                                                                                                               b.options.buttonNextCallback(b, this, a)
                                                                                                                           }).data("jcarouselstate", a)
        } else this.options.buttonNextCallback !== null && this.buttonNextState != a && this.options.buttonNextCallback(b, null, a);
        if (this.buttonPrev.size() > 0) {
            this.buttonPrev.unbind(this.options.buttonPrevEvent + ".jcarousel", this.funcPrev);
            c && this.buttonPrev.bind(this.options.buttonPrevEvent + ".jcarousel", this.funcPrev);
            this.buttonPrev[c ? "removeClass" : "addClass"](this.className("jcarousel-prev-disabled")).attr("disabled", c ? false : true);
            this.options.buttonPrevCallback !== null && this.buttonPrev.data("jcarouselstate") != c && this.buttonPrev.each(
                                                                                                                           function() {
                                                                                                                               b.options.buttonPrevCallback(b, this, c)
                                                                                                                           }).data("jcarouselstate", c)
        } else this.options.buttonPrevCallback !== null && this.buttonPrevState != c && this.options.buttonPrevCallback(b, null, c);
        this.buttonNextState = a;
        this.buttonPrevState = c
    },notify:function(a) {
        var c = this.prevFirst === null ? "init" : this.prevFirst < this.first ? "next" : "prev";
        this.callback("itemLoadCallback", a, c);
        if (this.prevFirst !== this.first) {
            this.callback("itemFirstInCallback", a, c, this.first);
            this.callback("itemFirstOutCallback", a, c, this.prevFirst)
        }
        if (this.prevLast !== this.last) {
            this.callback("itemLastInCallback", a, c, this.last);
            this.callback("itemLastOutCallback", a, c, this.prevLast)
        }
        this.callback("itemVisibleInCallback", a, c, this.first, this.last, this.prevFirst, this.prevLast);
        this.callback("itemVisibleOutCallback", a, c, this.prevFirst, this.prevLast, this.first, this.last)
    },callback:function(a, c, b, d, f, j, e) {
        if (!(this.options[a] == null || typeof this.options[a] != "object" && c != "onAfterAnimation")) {
            var g = typeof this.options[a] == "object" ? this.options[a][c] : this.options[a];
            if (i.isFunction(g)) {
                var k = this;
                if (d === undefined)g(k, b, c); else if (f === undefined)this.get(d).each(function() {
                    g(k, this, d, b, c)
                }); else {
                    a = function(m) {
                        k.get(m).each(function() {
                            g(k, this, m, b, c)
                        })
                    };
                    for (var l = d; l <= f; l++)l !== null && !(l >= j && l <= e) && a(l)
                }
            }
        }
    },create:function(a) {
        return this.format("<li></li>", a)
    },format:function(a, c) {
        a = i(a);
        for (var b = a.get(0).className.split(" "),d = 0; d < b.length; d++)b[d].indexOf("jcarousel-") != -1 && a.removeClass(b[d]);
        a.addClass(this.className("jcarousel-item")).addClass(this.className("jcarousel-item-" + c)).css({"float":this.options.rtl ? "right" : "left","list-style":"none"}).attr("jcarouselindex", c);
        return a
    },className:function(a) {
        return a + " " + a + (!this.options.vertical ? "-horizontal" : "-vertical")
    },dimension:function(a, c) {
        var b = a.jquery !== undefined ? a[0] : a,d = !this.options.vertical ? (b.offsetWidth || h.intval(this.options.itemFallbackDimension)) + h.margin(b, "marginLeft") + h.margin(b, "marginRight") : (b.offsetHeight || h.intval(this.options.itemFallbackDimension)) + h.margin(b, "marginTop") + h.margin(b, "marginBottom");
        if (c == null || d == c)return d;
        d = !this.options.vertical ? c - h.margin(b, "marginLeft") - h.margin(b, "marginRight") : c - h.margin(b, "marginTop") - h.margin(b, "marginBottom");
        i(b).css(this.wh, d + "px");
        return this.dimension(b)
    },clipping:function() {
        return!this.options.vertical ? this.clip[0].offsetWidth - h.intval(this.clip.css("borderLeftWidth")) - h.intval(this.clip.css("borderRightWidth")) : this.clip[0].offsetHeight - h.intval(this.clip.css("borderTopWidth")) - h.intval(this.clip.css("borderBottomWidth"))
    },index:function(a, c) {
        if (c == null)c = this.options.size;
        return Math.round(((a - 1) / c - Math.floor((a - 1) / c)) * c) + 1
    }});
    h.extend({defaults:function(a) {
        return i.extend(q, a || {})
    },margin:function(a, c) {
        if (!a)return 0;
        var b = a.jquery !== undefined ? a[0] : a;
        if (c == "marginRight" && i.browser.safari) {
            var d = {display:"block","float":"none",width:"auto"},f,j;
            i.swap(b, d, function() {
                f = b.offsetWidth
            });
            d.marginRight = 0;
            i.swap(b, d, function() {
                j = b.offsetWidth
            });
            return j - f
        }
        return h.intval(i.css(b, c))
    },intval:function(a) {
        a = parseInt(a, 10);
        return isNaN(a) ? 0 : a
    }});
    i.fn.jcarousel = function(a) {
        if (typeof a == "string") {
            var c = i(this).data("jcarousel"),b = Array.prototype.slice.call(arguments, 1);
            return c[a].apply(c, b)
        } else return this.each(function() {
            i(this).data("jcarousel", new h(this, a))
        })
    }
})(jQuery);

