(function($){
  function vSlider(){
  }
  vSlider.prototype={
    s:{},                //параметры
    iHeight:0,          //высота элементов
    iCount:0,            //общее количество элементов в слайдере
    $cont:null,          //контейнер для элементов (jQuery-объект)
    $next:null,          //кнопка прокручивания вниз (jQuery-объект)
    $prev:null,          //кнопка прокурчивания вверх (jQuery-объект)
    $items:null,        //хэш всех элементов (jQuery-объект)
    iCSS:{},            //объект, хранящий css-свойства элементов, влияющие на отображение: height, padding (top+bottom), margin (top+bottom)
    nullCSS:{            //объект, перечисляющий вышеперечисленные css-свойства, значения всех равны нулю
      height:0
    },          
    anim:false,          //флаг, включающийся на время анимации, чтобы не обрабатывать в это время кнопки
    init:function(s,p){
      this.s=s;
      this.$items=$(".item",p)
      this.iCount=this.$items.length;
      //для проворачивания вниз необходимо наличие N элементов над видимой областью, чтобы можно было их свернуть   (N=s.clideCount)
      //аналогично должно быть N элементов под видимой областью, чтобы можно было их показать при проворачивании вниз
      // плюс N элементов, которые видны в данный момент
      // итого, если элементов меньше, чем N*3, то слайдер реализовать невозможно
      if (this.iCount < this.s.slideCount*3){
        return false;
      }
      //берём первый элемент слайдера, и основные параметры берём с него.
      var css={
        paddingTop:'padding-top',
        paddingBottom:'padding-bottom',
        marginTop:'margin-top',
        marginBottom:'margin-bottom'
      };
      var o=this.$items.eq(0);
      this.iCSS.height=this.iHeight=o.height();
      for (var key in css){
        var prop=parseInt(o.css(key));
        if (prop != 0){
          this.iCSS[key]=prop;
          this.nullCSS[key]=0;
          this.iHeight+=prop;
        }
      }
      this.$cont=$(".container",p);
      this.initContainer();
      var self=this;
      this.$next=$('.next',p).css('display','block').click(function(){return self.slideDown.apply(self)});
      this.$prev=$('.prev',p).css('display','block').click(function(){return self.slideUp.apply(self)});
      return true;
    },
    
    initContainer:function(){
      //перемещаем последние элементы в начало контейнера
      this.$items.slice(-this.s.slideCount).reverse().prependTo(this.$cont);
      //контейнер провораичваем, чтобы были видны те же элементы, что были видны изначально
      this.$cont.css('top', - this.iHeight * this.s.slideCount);
      //порядок элементов изменился, соответственно обновляем порядок в хэше
      this.$items=$('.item',this.$cont);    
    },
    
    //функция проворачивания вниз
    slideDown:function(){
      if (this.anim) return false;
      this.anim=true;
      var self=this;
      //берём верхние элементы, и сворачиваем их в ноль
      //после этого перемещаем их в самый низи восстанавливаем их CSS-свойства
      var moving_items =
        this.$items
          .slice(0,this.s.slideCount)                    //выборка элементов
          .animate(                                      //сворачивание
              this.nullCSS,  
              this.s.speed,
              this.s.easing,
              function(){
                moving_items
                  .appendTo(self.$cont)                  //перемещение
                  .css(self.iCSS)                        //восстановление свойств
                ;
                self.$items=$('.item',self.$cont);      //порядок элементов изменился, соответственно обновляем порядок в хэше
                self.anim=false;
              }
          );
      ;    
      return false;
    },
    
    //функция проворачивания вверх
    slideUp:function(){
      if (this.anim) return false;
      this.anim=true;
      var self=this;
      //берём нижние элементы, `обнуляем` их CSS
      //затем помащаем их в самый верх
      //затем плавно их разворачиваем, восстанавливая CSS-свойства
      var moving_items =
        this.$items
          .slice(-this.s.slideCount).reverse()          //выборка элементов
          .css(self.nullCSS)                            //`обнуление` свойств          
          .prependTo(self.$cont)                        //перемещение вверх
          .animate(                                      //разворачивание
              this.iCSS,  
              this.s.speed,
              this.s.easing,
              function(){
                
                self.$items=$('.item',self.$cont);      //порядок элементов изменился, соответственно обновляем порядок в хэше
                self.anim=false;
              }
          );
      ;    
      return false;
    }
  }
  
  //новая jquery-функция функция для `переворачивания`массива jquery-элементов
  if ($.fn.reverse == undefined){
    $.fn.reverse=function(){
      return $($.makeArray(this).reverse());
    }
  }
  
  //новая jquery-функция собственно для реализации слайдера
  $.fn.vSlider = function(options) {
    var defaults = {
      speed: 'normal',
      easing: 'swing',
      slideCount:1
    };
    var options = $.extend(defaults, options);
    return this.each(function(){
      var slider=new vSlider();
      slider.init(options,this);
    });
  };
})(jQuery);