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