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