/*!
 * 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 : 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
  },
  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 ? this.last : 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.first : 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);
 
