(function($) { 
   var defaults = {
      duration: 'fast',
      easing: 'linear', // linear or other easings
      start: 0, // 0 indexed
      scroll: 1,
      fixed_column_width: null,
      first_visible: null,
      first_not_visible: null,
      last_visible: null,
      last_not_visible: null,
      previous: null,
      next: null
   }

   $.fn.carousel = function(o) {
      o = $.extend(defaults, o || {});
      return this.each(function() {
         $.fn.extend({
            resize_to: resize_to
         })

         var car=$(this)
         var list=$(car.children()[0])
         var pos=0
         var one_size=o.fixed_column_width
         if(!one_size) {
            one_size=list.children().outerWidth(true)
            log('computing one_size to: '+one_size)
         }
         var total=list.children().length
         var visible
         var active=false
         var first_called=false
         var last_called=false
         car.resize_to(car.width())

         // this makes all the items not appear on second line
         list.width((total+1)*one_size)
         // the +1 is needed for IE6

         $(o.previous).click(function(e){ go(pos-o.scroll) }) 
         $(o.next).click(function(e){ go(pos+o.scroll) }) 

         callbacks()
         if(pos != o.start)
            go(o.start)

         function resize_to(new_width) {
		 	
			log('resize_to: width inside is '+new_width)
            visible=Math.floor(new_width/one_size)
            log('resize_to: visible is '+visible)
            car.width(visible*one_size)
            log('resize_to: width inside is '+car.width())
            log('resize_to: one_size is '+one_size)
            var r=(new_width-(visible*one_size))/2
            log('resize_to: setting left margin to '+r)

            car.css('margin-left',r)
            go(pos) // fills up empty space
            callbacks()
         }

         function go(to) {
            log('go from: '+pos+' to: '+to);
            if(active) return;
            if(to+visible>total) to=total-visible;
            if(to<0) to=0;
            if(pos==to) return;
            pos=to;
            active=true;
            log('before starting animation')
            o.start_animation && o.start_animation()
            list.animate({
                  left: -(pos*one_size),
                  y: 0
               }, o.duration, o.easing, finish)
            log('just programmed animation')
         }

         function callbacks() {
            if(pos==0) {
               first_called=true
               o.first_visible && o.first_visible()
            }
            if(first_called && pos!=0) {
               first_called=false
               o.first_not_visible && o.first_not_visible()
            }
            if(pos+visible>=total) {
               last_called=true
               o.last_visible && o.last_visible()
            }
            if(last_called && pos+visible<total) {
               last_called=false
               o.last_not_visible && o.last_not_visible()
            }
         }

         function finish() {
            if(!active) return;
            log('finished animation')
            callbacks()
            active=false;
            o.finish_animation && o.finish_animation()
         }
      })
   }
})(jQuery);
