(function($) {
 
 $.fn.jcarousel=function(o) {
 return this.each(function() {
 new $jc(this,o);
 });
 };
 var defaults= {
 vertical:false,
 start:1,
 size:null,
 scroll:3,
 visible:null,
 animation: 'fast',
 easing:null,
 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
 };
 
 $.jcarousel=function(e,o) {
 this.options = $.extend({},defaults,o|| {});
 this.container =null;
 this.clip =null;
 this.list =null;
 this.buttonNext=null;
 this.buttonPrev=null;
 this.wh= !this.options.vertical? 'width': 'height';
 this.lt= !this.options.vertical? 'left': 'top';
 if(e.nodeName== 'UL'||e.nodeName== 'OL') {
 this.list= $(e);
 this.container=this.list.parent();
 if($.className.has(this.container[0].className, 'jcarousel-clip')) {
 if(!$.className.has(this.container[0].parentNode.className, 'jcarousel-container'))
 this.container=this.container.wrap('<div></div>');
 this.container=this.container.parent();
 }else if(!$.className.has(this.container[0].className, 'jcarousel-container'))
 this.container=this.list.wrap('<div></div>').parent();
 var split=e.className.split(' ');
 for(var i=0;i<split.length;i++) {
 if(split[i].indexOf('jcarousel-skin') != -1) {
 this.list.removeClass(split[i]);
 this.container.addClass(split[i]);
 break;
 }
 }
 }else{
 this.container= $(e);
 this.list= $('ul,ol',e);
 }
 this.clip=this.list.parent();
 if(!this.clip.length|| !$.className.has(this.clip[0].className, 'jcarousel-clip'))
 this.clip=this.list.wrap('<div></div>').parent();
 this.buttonPrev= $('.jcarousel-prev',this.container);
 if(this.buttonPrev.size() ==0&&this.options.buttonPrevHTML!=null)
 this.buttonPrev=this.clip.before(this.options.buttonPrevHTML).prev();
 this.buttonPrev.addClass(this.className('jcarousel-prev'));
 this.buttonNext= $('.jcarousel-next',this.container);
 if(this.buttonNext.size() ==0&&this.options.buttonNextHTML!=null)
 this.buttonNext=this.clip.before(this.options.buttonNextHTML).prev();
 this.buttonNext.addClass(this.className('jcarousel-next'));
 this.clip.addClass(this.className('jcarousel-clip'));
 this.list.addClass(this.className('jcarousel-list'));
 this.container.addClass(this.className('jcarousel-container'));
 var di=this.options.visible!=null?Math.ceil(this.clipping() /this.options.visible) :null;
 var li= $('li',this.list);
 var self=this;
 if(li.size() >0) {
 var wh=0,i=this.options.start;
 li.each(function() {
 self.format(this,i++);
 wh+=self.dimension(this,di);
 });
 this.list.css(this.wh,wh+ 'px');
 if(!o||o.size==undefined)
 this.options.size=li.size();
 }
 this.container.css('display', 'block');
 this.buttonNext.css('display', 'block');
 this.buttonPrev.css('display', 'block');
 this.funcNext =function() {self.next(); };
 this.funcPrev =function() {self.prev(); };
 this.funcStop =function() {self.stop(); };
 this.funcResize=function() {self.reload(); };
 this.init();
 };
 var $jc= $.jcarousel;
 $jc.fn= $jc.prototype= {
 jcarousel: '2.0.0'
 };
 $jc.fn.extend= $jc.extend= $.extend;
 $jc.fn.extend({
 
 setup:function() {
 this.first =null;
 this.last =null;
 this.prevFirst=null;
 this.prevLast =null;
 this.animating=false;
 this.timer =null;
 this.tail =null;
 this.inTail =false;
 this.locked =false;
 this.scroll(this.options.start,false);
 },
 
 init:function() {
 if(this.options.initCallback!=null)
 this.options.initCallback(this, 'init');
 this.setup();
 $(window).bind('resize',this.funcResize);
 },
 
 reset:function() {
 this.list.empty();
 this.list.css(this.lt, '0px');
 this.list.css(this.wh, '0px');
 if(this.options.initCallback!=null)
 this.options.initCallback(this, 'reset');
 this.setup();
 },
 
 reload:function() {
 if(this.tail!=null&&this.inTail)
 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) +this.tail);
 this.tail =null;
 this.inTail=false;
 if(this.options.reloadCallback!=null)
 this.options.reloadCallback(this);
 if(this.options.visible!=null) {
 var self=this;
 var di=Math.ceil(this.clipping() /this.options.visible),wh=0,lt=0;
 $('li',this.list).each(function(i) {
 wh+=self.dimension(this,di);
 if(i+1<self.first)
 lt=wh;
 });
 this.list.css(this.wh,wh+ 'px');
 this.list.css(this.lt, -lt+ 'px');
 }
 this.scroll(this.first,false);
 },
 
 lock:function() {
 this.locked=true;
 this.buttons();
 },
 
 unlock:function() {
 this.locked=false;
 this.buttons();
 },
 
 size:function(s) {
 if(s!=undefined) {
 this.options.size=s;
 if(!this.locked)
 this.buttons();
 }
 return this.options.size;
 },
 
 has:function(i,i2) {
 if(i2==undefined|| !i2)
 i2=i;
 for(var j=i;j<=i2;j++) {
 var e=this.get(j).get(0);
 if(!e|| $.className.has(e, 'jcarousel-item-placeholder'))
 return false;
 }
 return true;
 },
 
 get:function(i) {
 return $('.jcarousel-item-'+i,this.list);
 },
 
 add:function(i,s) {
 var e=this.get(i),old=0;
 if(e.length==0) {
 var c,e=this.create(i),j= $jc.intval(i);
 while(c=this.get(--j)) {
 if(j<=0||c.length) {
 j<=0?this.list.prepend(e) :c.after(e);
 break;
 }
 }
 }else
 old=this.dimension(e);
 e.removeClass(this.className('jcarousel-item-placeholder'));
 typeof s== 'string'?e.html(s) :e.empty().append(s);
 var di=this.options.visible!=null?Math.ceil(this.clipping() /this.options.visible) :null;
 var wh=this.dimension(e,di) -old;
 if(i>0&&i<this.first)
 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) +wh+ 'px');
 this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) +wh+ 'px');
 return e;
 },
 
 remove:function(i) {
 var e=this.get(i);
 if(!e.length|| (i>=this.first&&i<=this.last))
 return;
 var d=this.dimension(e);
 if(i<this.first)
 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) +d+ 'px');
 e.remove();
 this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) -d+ 'px');
 },
 
 next:function() {
 this.stopAuto();
 if(this.tail!=null&& !this.intail)
 this.scrollTail(false);
 else
 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();
 if(this.tail!=null&&this.inTail)
 this.scrollTail(true);
 else
 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(b) {
 if(this.locked||this.animating|| !this.tail)
 return;
 var pos = $jc.intval(this.list.css(this.lt));
 !b?pos-=this.tail:pos+=this.tail;
 this.inTail= !b;
 this.prevFirst=this.first;
 this.prevLast =this.last;
 this.animate(pos);
 },
 
 scroll:function(i,a) {
 if(this.locked||this.animating)
 return;
 this.animate(this.pos(i),a);
 },
 
 pos:function(i) {
 if(this.locked||this.animating)
 return;
 if(this.options.wrap!= 'circular')
 i=i<1?1: (this.options.size&&i>this.options.size?this.options.size:i);
 var back=this.first>i;
 var pos = $jc.intval(this.list.css(this.lt));
 var f=this.options.wrap!= 'circular'&&this.first<=1?1:this.first;
 var c=back?this.get(f) :this.get(this.last);
 var j=back?f:f-1;
 var e=null,l=0,p=false,d=0;
 while(back? --j>=i: ++j<i) {
 e=this.get(j);
 p= !e.length;
 if(e.length==0) {
 e=this.create(j).addClass(this.className('jcarousel-item-placeholder'));
 c[back? 'before': 'after'](e);
 }
 c=e;
 d=this.dimension(e);
 if(p)
 l+=d;
 if(this.first!=null&& (this.options.wrap== 'circular'|| (j>=1&& (this.options.size==null||j<=this.options.size))))
 pos=back?pos+d:pos-d;
 }
 var clipping=this.clipping();
 var cache= [];
 var visible=0,j=i,v=0;
 var c=this.get(i-1);
 while(++visible) {
 e=this.get(j);
 p= !e.length;
 if(e.length==0) {
 e=this.create(j).addClass(this.className('jcarousel-item-placeholder'));
 c.length==0?this.list.prepend(e) :c[back? 'before': 'after'](e);
 }
 c=e;
 d=this.dimension(e);
 if(d==0) {
 return 0;
 }
 if(this.options.wrap!= 'circular'&&this.options.size!==null&&j>this.options.size)
 cache.push(e);
 else if(p)
 l+=d;
 v+=d;
 if(v>=clipping)
 break;
 j++;
 }
 for(var x=0;x<cache.length;x++)
 cache[x].remove();
 if(l>0) {
 this.list.css(this.wh,this.dimension(this.list) +l+ 'px');
 if(back) {
 pos-=l;
 this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) -l+ 'px');
 }
 }
 var last=i+visible-1;
 if(this.options.wrap!= 'circular'&&this.options.size&&last>this.options.size)
 last=this.options.size;
 var first=last-visible+1;
 if(this.options.wrap!= 'circular'&&first<1)
 first=1;
 if(this.inTail&&back) {
 pos+=this.tail;
 this.inTail=false;
 }
 this.tail=null;
 if(this.options.wrap!= 'circular'&&last==this.options.size&& (last-visible+1) >=1) {
 var m= $jc.margin(this.get(last), !this.options.vertical? 'marginRight': 'marginBottom');
 if((v-m) >clipping)
 this.tail=v-clipping-m;
 }
 while(i-- >first)
 pos+=this.dimension(this.get(i));
 this.prevFirst=this.first;
 this.prevLast =this.last;
 this.first =first;
 this.last =last;
 return pos;
 },
 
 animate:function(p,a) {
 if(this.locked||this.animating)
 return;
 this.animating=true;
 var self=this,pos=p;
 var scrolled=function() {
 self.animating=false;
 if(pos==0)
 self.list.css(self.lt, 0);
 if(self.options.wrap== 'both'||self.options.wrap== 'last'||self.options.size==null||self.last<self.options.size)
 self.startAuto();
 self.buttons();
 self.notify('onAfterAnimation');
 };
 this.notify('onBeforeAnimation');
 if(!this.options.animation||a==false) {
 this.list.css(this.lt,p+ 'px');
 scrolled();
 }else{
 var o= !this.options.vertical? {'left':p} : {'top':p};
 this.list.animate(o,this.options.animation,this.options.easing,scrolled);
 }
 },
 
 startAuto:function(s) {
 if(s!=undefined)
 this.options.auto=s;
 if(this.options.auto==0)
 return this.stopAuto();
 if(this.timer!=null)
 return;
 var self=this;
 this.timer=setTimeout(function() {self.next(); },this.options.auto*1000);
 },
 
 stopAuto:function() {
 if(this.timer==null)
 return;
 clearTimeout(this.timer);
 this.timer=null;
 },
 
 buttons:function(n,p) {
 if(n==undefined||n==null) {
 var n= !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)
 n=this.tail!=null&& !this.inTail;
 }
 if(p==undefined||p==null) {
 var p= !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)
 p=this.tail!=null&&this.inTail;
 }
 var self=this;
 this.buttonNext[n? 'bind': 'unbind'](this.options.buttonNextEvent,this.funcNext)[n? 'removeClass': 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled',n?false:true);
 this.buttonPrev[p? 'bind': 'unbind'](this.options.buttonPrevEvent,this.funcPrev)[p? 'removeClass': 'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled',p?false:true);
 if(this.buttonNext.length>0&& (this.buttonNext[0].jcarouselstate==undefined||this.buttonNext[0].jcarouselstate!=n) &&this.options.buttonNextCallback!=null) {
 this.buttonNext.each(function() {self.options.buttonNextCallback(self,this,n); });
 this.buttonNext[0].jcarouselstate=n;
 }
 if(this.buttonPrev.length>0&& (this.buttonPrev[0].jcarouselstate==undefined||this.buttonPrev[0].jcarouselstate!=p) &&this.options.buttonPrevCallback!=null) {
 this.buttonPrev.each(function() {self.options.buttonPrevCallback(self,this,p); });
 this.buttonPrev[0].jcarouselstate=p;
 }
 },
 notify:function(evt) {
 var state=this.prevFirst==null? 'init': (this.prevFirst<this.first? 'next': 'prev');
 this.callback('itemLoadCallback',evt,state);
 if(this.prevFirst!=this.first) {
 this.callback('itemFirstInCallback',evt,state,this.first);
 this.callback('itemFirstOutCallback',evt,state,this.prevFirst);
 }
 if(this.prevLast!=this.last) {
 this.callback('itemLastInCallback',evt,state,this.last);
 this.callback('itemLastOutCallback',evt,state,this.prevLast);
 }
 this.callback('itemVisibleInCallback',evt,state,this.first,this.last,this.prevFirst,this.prevLast);
 this.callback('itemVisibleOutCallback',evt,state,this.prevFirst,this.prevLast,this.first,this.last);
 },
 callback:function(cb,evt,state,i1,i2,i3,i4) {
 if(this.options[cb] ==undefined|| (typeof this.options[cb] != 'object'&&evt!= 'onAfterAnimation'))
 return;
 var callback=typeof this.options[cb] == 'object'?this.options[cb][evt] :this.options[cb];
 if(!$.isFunction(callback))
 return;
 var self=this;
 if(i1===undefined)
 callback(self,state,evt);
 else if(i2===undefined)
 this.get(i1).each(function() {callback(self,this,i1,state,evt); });
 else{
 for(var i=i1;i<=i2;i++)
 if(!(i>=i3&&i<=i4))
 this.get(i).each(function() {callback(self,this,i,state,evt); });
 }
 },
 create:function(i) {
 return this.format('<li></li>',i);
 },
 format:function(e,i) {
 var $e= $(e).addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-'+i));
 $e.attr('jcarouselindex',i);
 return $e;
 },
 className:function(c) {
 return c+ ' '+c+ (!this.options.vertical? '-horizontal': '-vertical');
 },
 dimension:function(e,d) {
 var el=e.jquery!=undefined?e[0] :e;
 var old= !this.options.vertical?
 el.offsetWidth+ $jc.margin(el, 'marginLeft') + $jc.margin(el, 'marginRight') :
 el.offsetHeight+ $jc.margin(el, 'marginTop') + $jc.margin(el, 'marginBottom');
 if(d==undefined||old==d)
 return old;
 var w= !this.options.vertical?
 d- $jc.margin(el, 'marginLeft') - $jc.margin(el, 'marginRight') :
 d- $jc.margin(el, 'marginTop') - $jc.margin(el, 'marginBottom');
 $(el).css(this.wh,w+ 'px');
 return this.dimension(el);
 },
 clipping:function() {
 return!this.options.vertical?
 this.clip[0].offsetWidth- $jc.intval(this.clip.css('borderLeftWidth')) - $jc.intval(this.clip.css('borderRightWidth')) :
 this.clip[0].offsetHeight- $jc.intval(this.clip.css('borderTopWidth')) - $jc.intval(this.clip.css('borderBottomWidth'));
 },
 index:function(i,s) {
 if(s==undefined)
 s=this.options.size;
 return Math.round((((i-1) /s) -Math.floor((i-1) /s)) *s) +1;
 }
 });
 $jc.extend({
 
 defaults:function(d) {
 $.extend(defaults,d);
 },
 margin:function(e,p) {
 if(!e)
 return 0;
 var el=e.jquery!=undefined?e[0] :e;
 if(p== 'marginRight'&& $.browser.safari) {
 var old= {'display': 'block', 'float': 'none', 'width': 'auto'},oWidth,oWidth2;
 $.swap(el,old,function() {oWidth=el.offsetWidth; });
 old['marginRight'] =0;
 $.swap(el,old,function() {oWidth2=el.offsetWidth; });
 return oWidth2-oWidth;
 }
 return $jc.intval($.css(el,p));
 },
 intval:function(v) {
 v=parseInt(v);
 return isNaN(v) ?0:v;
 }
 });
})(jQuery);
