(function($){
$.fn.jMyCarousel=function(o){
o=$.extend({
btnPrev: null,
btnNext: null,
mouseWheel: true,
auto: false,
speed: 800,
easing: 'linear',
vertical: false,
circular: true,
visible: '4',
start: 0,
scroll: 1,
step: 50,
eltByElt: false,
evtStart : 'mouseover',
evtStop : 'mouseout',
beforeStart: null,
afterEnd: null
},o ||{})
return this.each(function(){
var running=false,animCss=o.vertical?"top":"left",sizeCss=o.vertical?"height":"width"
var div=$(this),ul=$("ul",div),tLi=$("li",ul),tl=tLi.size(),v=o.visible
var mousewheelN=0
var defaultBtn=(o.btnNext===null&&o.btnPrev===null)? true : false
var cssU=(v.toString().indexOf("%")!=-1 ? '%' :(v.toString().indexOf("px")!=-1)? 'px' : 'el')
var direction=null
if(o.circular){
var imgSet=tLi.clone()
ul.prepend(imgSet).append(imgSet.clone())}
var li=$("li",ul)
div.css("visibility","visible")
li.css("overflow","hidden")
.css("float",o.vertical ? "none" : "left")
.children().css("overflow","hidden")
if(!o.vertical){li.css("display","inline");}
if(li.children().get(0).tagName.toLowerCase()=='a'&&!o.vertical){
li.children().css('float','left')}
if(o.vertical&&jQuery.browser.msie){
li.css('line-height','4px').children().css('margin-bottom','-4px')}
ul.css("margin","0")
.css("padding","0")
.css("position","relative")
.css("list-style-type","none")
.css("z-index","1")
div.css("overflow","hidden")
.css("position","relative")
.css("z-index","2")
.css("left","0px")
var liSize=o.vertical ? height(li): width(li)
var liSizeV=o.vertical ? elHeight(li): height(li)
var curr=o.start
var nbAllElts=li.size()
var ulSize=liSize*nbAllElts
var nbElts=tl
var eltsSize=nbElts*liSize
var allEltsSize=nbAllElts*liSize
var step=o.step=='default' ? liSize : o.step
o.btnPrev=defaultBtn ? $('<input type="button" class="'+(o.vertical ? 'up' : 'prev')+'" />'): $(o.btnPrev)
o.btnNext=defaultBtn ? $('<input type="button" class="'+(o.vertical ? 'down' : 'next')+'" />'): $(o.btnNext)
var prev=o.btnPrev
var next=o.btnNext
if(defaultBtn&&o.auto !==true){
prev.css({'opacity':'0.6'})
next.css({'opacity' :'0.6'})
div.prepend(prev)
div.prepend(next)
o.btnPrev=prev
o.btnNext=next}
if(o.eltByElt){
step=liSize
if(o.start % liSize !==0){
var imgStart=parseInt(o.start/liSize)
curr=o.start=(imgStart*liSize)}}
if(o.circular){
o.start+=(liSize*tl)
curr+=(liSize*tl)}
var divSize,cssSize,cssUnity
if(cssU=='%'){
divSize=0
cssSize=parseInt(v)
cssUnity="%"}
else if(cssU=='px'){
divSize=parseInt(v)
cssSize=parseInt(v)
cssUnity="px"}
else{
divSize=liSize*parseInt(v)
cssSize=liSize*parseInt(v)
cssUnity="px"}
ul.css(sizeCss,ulSize+"px")
.css(animCss,-(o.start))
div.css(sizeCss,cssSize+cssUnity)
if(o.vertical&&cssUnity=='%'){
var pxsize=((liSize*nbElts)*(parseInt(v)/100))
div.css(sizeCss,pxsize+'px')}
if(divSize===0){
divSize=div.width()}
if(o.vertical){
div.css("width",liSizeV+'px')
ul.css("width",liSizeV+'px')
li.css('margin-bottom',(parseInt(li.css('margin-bottom'))*2)+'px')
li.eq(li.size()-1).css('margin-bottom',li.css('margin-top'))
}else{
div.css('height',liSizeV+'px')
ul.css('height',liSizeV+'px')}
if(cssU=='%'){
v=divSize/li.width()
if(v % 1 !==0){v+=1;}
v=parseInt(v)}
var divVSize=div.height()
if(defaultBtn){
next.css({'z-index':200,'position':'absolute'})
prev.css({'z-index':200,'position':'absolute'})
if(o.vertical){
prev.css({'width': prev.width(),'height' : prev.height(),'top' : '0px','left': parseInt(liSizeV/2)-parseInt(prev.width()/2)+'px'})
next.css({'width': prev.width(),'height' : prev.height(),'top' :(divVSize-prev.height())+'px','left' : parseInt(liSizeV/2)-parseInt(prev.width()/2)+'px'})}
else{
prev.css({'left':'0px','top': parseInt(liSizeV/2)-parseInt(prev.height()/2)+'px'})
next.css({'right':'0px','top': parseInt(liSizeV/2)-parseInt(prev.height()/2)+'px'})}}
if(o.btnPrev){
$(o.btnPrev).bind(o.evtStart,function(){
if(defaultBtn){o.btnPrev.css('opacity',0.9);}
running=true
direction='backward'
return backward()
})
$(o.btnPrev).bind(o.evtStop,function(){
if(defaultBtn){o.btnPrev.css('opacity',0.6);}
running=false
direction=null
return stop()
})}
if(o.btnNext){
$(o.btnNext).bind(o.evtStart,function(){
if(defaultBtn){o.btnNext.css('opacity',0.9);}
running=true
direction='forward'
return forward()
})
$(o.btnNext).bind(o.evtStop,function(){
if(defaultBtn){o.btnNext.css('opacity',0.6);}
running=false
direction=null
return stop()
})}
if(o.auto===true){
running=true
forward()}
if(o.mouseWheel&&div.mousewheel){
div.mousewheel(function(e,d){
if(!o.circular&&(d>0 ?(curr+divSize<ulSize):(curr>0))|| o.circular){
mousewheelN+=1
if(running===false){
if(d>0){forward(step,true);}
else{backward(step,true);}
running=true}}
})}
function forward(stepsize,once){
var s=(stepsize ? stepsize : step)
if(running===true&&direction==="backward"){return;}
if(!o.circular){
if(curr+s+(o.vertical ? divVSize : divSize)>eltsSize){
s=eltsSize-(curr+(o.vertical ? divVSize : divSize))}}
ul.animate(
animCss=="left" ?{left:-(curr+s)}:{top:-(curr+s)},o.speed,o.easing,
function(){
curr+=s
if(o.circular){
if(curr+(o.vertical ? divVSize : divSize)+liSize>=allEltsSize){
ul.css(o.vertical ? 'top' : 'left',-curr+eltsSize)
curr-=eltsSize}}
if(!once&&running){
forward()}
else if(once){
if(--mousewheelN>0){
this.forward(step,true)}
else{
running=false
direction=null}}}
)}
function backward(stepsize,once){
var s=(stepsize ? stepsize : step)
if(running===true&&direction==="forward"){return;}
if(!o.circular){
if(curr-s<0){
s=curr-0}}
ul.animate(
animCss=="left" ?{left:-(curr-s)}:{top:-(curr-s)},o.speed,o.easing,
function(){
curr-=s
if(o.circular){
if(curr<=liSize){
ul.css(o.vertical ? 'top' : 'left',-(curr+eltsSize))
curr+=eltsSize}}
if(!once&&running){
backward()}
else if(once){
if(--mousewheelN>0){
backward(step,true)}
else{
running=false
direction=null}}}
)}
function stop(){
if(!o.eltByElt){
ul.stop()
curr=0-parseInt(ul.css(animCss))}
running=false
direction=null}
function imgSize(el,dimension){
if(dimension=='width'){
return el.find('img').width()}
else{
return el.find('img').height()}}
function elHeight(el){
var elImg=el.find('img')
if(o.vertical){
return parseInt(el.css('margin-left'))+parseInt(el.css('margin-right'))+parseInt(elImg.width())+parseInt(el.css('border-left-width'))+parseInt(el.css('border-right-width'))+parseInt(el.css('padding-right'))+parseInt(el.css('padding-left'))}
else{
return parseInt(el.css('margin-top'))+parseInt(el.css('margin-bottom'))+parseInt(elImg.width())+parseInt(el.css('border-top-height'))+parseInt(el.css('border-bottom-height'))+parseInt(el.css('padding-top'))+parseInt(el.css('padding-bottom'))}}
function debug(html){
$('#debug').html($('#debug').html()+html+"<br/>")}
})}
function css(el,prop){
return parseInt($.css(el[0],prop))|| 0}
function width(el){
return el[0].offsetWidth+css(el,'marginLeft')+css(el,'marginRight')}
function height(el){
return el[0].offsetHeight+css(el,'marginTop')+css(el,'marginBottom')}
})(jQuery)

