(function($) {
  function Gallery(el, options) {
    this._hold = $(el);
    this.initOptions(options);
    this._timer = options.autoRotation;
    this._t;
    this.initialize();
  }
  
  $.fn.gallery = function(options) {
    return this.each(function(){
      new Gallery(this, options);
    });
  };
  
  Gallery.prototype = {
    initOptions: function(_obj){
      this.options = {
        duration: 700,
        slideElement: 1,
        autoRotation: false,
        effect: false,
        listOfSlides: 'ul > li',
        switcher: false,
        disableBtn: false,
        nextBtn: 'a.link-next, a.btn-next, a.next',
        prevBtn: 'a.link-prev, a.btn-prev, a.prev',
        circle: true,
        direction: false,
        IE: false
      };
      for(key in _obj) this.options[key] = _obj[key];
    },
    initialize: function(){
      var _this = this;
      var _hold = _this._hold;
      var _speed = _this.options.duration;
      var _timer = _this.options.autoRotation;
      var _el = _hold.find(_this.options.listOfSlides);
      if (_this.options.effect) var _list = _el;
      else var _list = _el.parent();
      var _switcher = _hold.find(_this.options.switcher);
      var _next = _hold.find(_this.options.nextBtn);
      var _prev = _hold.find(_this.options.prevBtn);
      var _count = _el.index(_el.filter(':last'));
      var _w = _el.outerWidth(true);
      var _h = _el.outerHeight(true);
      if (_this.options.switcher) var _active = _switcher.index(_switcher.filter('.active:eq(0)'));
      else var _active = _el.index(_el.filter('.active:eq(0)'));
      if (_active < 0) _active = 0;
      var _last = _active;
      
      // Installation directions
      if (!_this.options.direction) {
        var _wrapHolderW = Math.ceil(_list.parent().width() / _w);
        if (((_wrapHolderW - 1) * _w + _w / 2) > _list.parent().width()) _wrapHolderW--;
      }
      else{
        var _wrapHolderW = Math.ceil(_list.parent().height()/_h);
        if (((_wrapHolderW-1)*_h + _h/2) > _list.parent().height()) _wrapHolderW--;
      }
      
      // Setting "fade" or "slide" effect
      if (!_this.options.effect) var rew = _count - _wrapHolderW + 1;
      else var rew = _count;
      if (!_this.options.effect) {
        if (!_this.options.direction) _list.css({marginLeft: -(_w * _active)})
        else _list.css({marginTop: -(_h * _active)})
      }
      else {
        _list.css({
          opacity: 0
        }).removeClass('active').eq(_active).addClass('active').css({
          opacity: 1
        }).css('opacity', 'auto');
        _switcher.removeClass('active').eq(_active).addClass('active');
      }
      
      // Disable or enable buttons "prev next"
      if (_this.options.disableBtn) {
        if (_count < _wrapHolderW) _next.addClass(_this.options.disableBtn);
        _prev.addClass(_this.options.disableBtn);
      }
      
      // Function to "fade"
      function fadeElement(){
        if ($.browser.msie && _this.options.IE){
          _list.eq(_last).css({opacity:0});
          _list.removeClass('active').eq(_active).addClass('active').css({opacity:'auto'});
        }
        else{
          _list.eq(_last).animate({opacity:0}, {queue:false, duration: _speed});
          _list.removeClass('active').eq(_active).addClass('active').animate({
            opacity:1
          }, {queue:false, duration: _speed, complete: function(){
            $(this).css('opacity','auto');
          }});
        }
        if (_this.options.switcher) _switcher.removeClass('active').eq(_active).addClass('active');
        _last = _active;
      }
      
      // Function for "slide"
      function scrollEl(){
        if (!_this.options.direction) _list.animate({marginLeft: -(_w * _active)}, {queue:false, duration: _speed})
        else _list.animate({marginTop: -(_h * _active)}, {queue:false, duration: _speed})
        if (_this.options.switcher) _switcher.removeClass('active').eq(_active/_this.options.slideElement).addClass('active');
      }
      function toPrepare(){
        if ((_active == rew) && _this.options.circle) _active = -_this.options.slideElement;
        for (var i = 0; i < _this.options.slideElement; i++){
          _active++;
          if (_active > rew) {
            _active--;
            if (_this.options.disableBtn &&(_count > _wrapHolderW)) _next.addClass(_this.options.disableBtn);
          }
        };
        if (_active == rew) if (_this.options.disableBtn &&(_count > _wrapHolderW)) _next.addClass(_this.options.disableBtn);
        if (!_this.options.effect) scrollEl();
        else fadeElement();
      }
      _this._hold.bind('runTimer', function(){
        _this._t = setInterval(function(){
          toPrepare();
        }, _this._timer);
      });
      _next.click(function(){
        if(_this._t) clearTimeout(_this._t);
        if (_this.options.disableBtn &&(_count > _wrapHolderW)) _prev.removeClass(_this.options.disableBtn);
        toPrepare();
        if (_this._timer) _this._hold.trigger('runTimer');
        return false;
      });
      _prev.click(function(){
        if(_this._t) clearTimeout(_this._t);
        if (_this.options.disableBtn &&(_count > _wrapHolderW)) _next.removeClass(_this.options.disableBtn);
        if ((_active == 0) && _this.options.circle) _active = rew + _this.options.slideElement;
        for (var i = 0; i < _this.options.slideElement; i++){
          _active--;
          if (_active < 0) {
            _active++;
            if (_this.options.disableBtn &&(_count > _wrapHolderW)) _prev.addClass(_this.options.disableBtn);
          }
        };
        if (_active == 0) if (_this.options.disableBtn &&(_count > _wrapHolderW)) _prev.addClass(_this.options.disableBtn);
        if (!_this.options.effect) scrollEl();
        else fadeElement();
        if (_this._timer) _this._hold.trigger('runTimer');
        return false;
      });
      if (_this.options.switcher) _switcher.click(function(){
        _active = _switcher.index($(this))*_this.options.slideElement;
        if(_this._t) clearTimeout(_this._t);
        if (!_this.options.effect) scrollEl();
        else fadeElement();
        if (_this._timer) _this._hold.trigger('runTimer');
        return false;
      });
      if (_this._timer) _this._hold.trigger('runTimer');
    },
    stop: function(){
      var _this = this;
      if (_this._t) clearTimeout(_this._t);
    },
    play: function(){
      var _this = this;
      if (_this._t) clearTimeout(_this._t);
      if (_this._timer) _this._hold.trigger('runTimer');
    }
  }
}(jQuery));

$(document).ready(function(){
  $('div.carousel').gallery({
    duration: 500,
    listOfSlides: 'li',
    slideElement: 3
  });
  $('div.promo-gallery').gallery({
    duration: 1000,
    listOfSlides: '.item',
    effect: 'fade',
    switcher: '.swicher li',
    autoRotation: 7000,
    IE: true
  });
});
