/**
 * Acceleration slider
 */
AccelerationSlider = function(config) {
  // configurable {
  this.selector = ''; // required
  this.slider_selector = '.slider';
  this.divider_selector = 'td.divider';
  this.image_container = 'td.img_cont';
  this.auto_init = true;
  this.auto_scroll = false;
  this.count_zones = 10;
  this.block = {
    width: 235,
    divider: 15,
    duration: {
      min: 250,
      max: 2500
    }
  }
  // }
  $.extend(true, this, config);
  
  this.prev_zone = 0;
  this.stopped = !this.auto_scroll;
  
  if(this.auto_init)
    this.init();
}

AccelerationSlider.prototype = {
  init: function() {
    if(!this.isSliderOverloaded())
      return;
      
    this.initEvents();
    
    if(this.auto_scroll)
      this.initAutoScroll();
  },
  
  initEvents: function() {
    this.getEl().mousemove($.proxy(this.onMouseMove, this))
                .mouseleave($.proxy(this.onMouseLeave, this));
  },
  
  initAutoScroll: function() {
    this.getDividers().width(this.getDividerWidth());
    this.getImageContainers().width(this.getImageWidth());
    
    this._createAutoScrollImages();
    this.getSlider().width(this.getImageContainers().length * this.getImageFullWidth() + this.getDividerWidth());
    this.getSlider().css('left', -this.calcVisibleImagesCount() * this.getImageFullWidth());
    this.startAutoScroll();
  },
  
  _createAutoScrollImages: function() {
    var count = this.calcVisibleImagesCount();
    
    for(var i = 0; i < count; i ++) {
      var $divider = this.getDividers().eq(i);
      $divider.clone().appendTo($divider.parent());

      var $img = this.getImageContainers().eq(i);
      $img.clone().appendTo($img.parent());
    }
    
    var images_count = this.getImageContainers().length;
    
    for(var i = 0; i < count; i ++) {
      var num = images_count - count - i - 1;
      
      var $divider = this.getDividers().eq(num);
      $divider.clone().prependTo($divider.parent());

      var $img = this.getImageContainers().eq(num);
      $img.clone().prependTo($img.parent());
      
      images_count ++;
    }
    
    var $divider = this.getDividers().eq(images_count - count - 1);
    $divider.clone().prependTo($divider.parent()).appendTo($divider.parent());
  },
  
  startAutoScroll: function() {
    setTimeout($.proxy(function() {this.startAnimation(this.prev_zone);}, this), 10);
  },
  
  startAnimation: function(zone) {
    if(!this.stopped && zone == this.prev_zone && !this.auto_scroll)
      return;
    
    this.stopAnimation();
    
    this.prev_zone = zone;
    
    if(this.auto_scroll && zone == 0)
      zone = 1;
                      
    var slide_delta = zone > 0
                      ? this.getSlider().position().left + this.getSlideDelta() 
                      : -this.getSlider().position().left;
                      
    var sliding_blocks = slide_delta / this.block.width;
    var block_duration = this.block.duration.max - (Math.abs(zone) - 1) * (this.block.duration.max - this.block.duration.min) / (this.count_zones - 1) * 2;
    var duration = sliding_blocks * block_duration;
    
    this.stopped = false;
    this.getSlider().animate({
      left: (zone < 0 ? '+=' : '-=') + slide_delta
    }, duration, 'linear', $.proxy(this.onAnimationComplete, this));
  },
  
  stopAnimation: function() {
    this.stopped = true;
    this.getSlider().stop();
  },
  
  isSliderOverloaded: function() {
    return this.getSlideDelta() > 0;
  },
  
  findZone: function(x) {
    var delta = x - this.getCenter();
    var abs_delta = Math.abs(delta);
    var zone_half = this.getZoneWidth() / 2;
    if(abs_delta <= zone_half)
      return 0;
      
    var abs_zone = Math.floor((abs_delta - zone_half) / (zone_half * 2)) + 1;
    return delta < 0 ? -abs_zone : abs_zone;
  },
  
  getSlideDelta: function() {
    return this.getSlider().width() - this.getEl().width();
  },
  
  getZoneWidth: function() {
    return this.getEl().width() / this.count_zones;
  },
  
  getCenter: function() {
    return this.getEl().width() / 2;
  },
  
  getSlider: function() {
    return $(this.slider_selector, this.getEl());
  },
  
  calcVisibleImagesCount: function() {
    return Math.ceil(this.getEl().width() / this.getImageFullWidth());
  },
  
  getImageFullWidth: function() {
    return this.block.width;
  },
  
  getDividerWidth: function() {
    return this.block.divider;
  },
  
  getImageWidth: function() {
    return this.block.width - this.block.divider;
  },
  
  getDividers: function() {
    return $(this.divider_selector, this.getEl());
  },
  
  getImageContainers: function() {
    return $(this.image_container, this.getEl());
  },
  
  getEl: function() {
    return $(this.selector);
  },
  
  onMouseMove: function(e) {
    var zone = this.findZone(e.pageX - this.getEl().offset().left);
    if(zone != 0)
      this.startAnimation(zone);
    else
      this.stopAnimation();
  },
  
  onMouseLeave: function() {
    if(this.auto_scroll) {
      this.startAnimation(0);
    } else {
      this.stopAnimation();
    }
  },
  
  onAnimationComplete: function() {
    if(this.auto_scroll) {
//      var 
      
      this.getSlider().css({
        left: this.prev_zone < 0 
              ? -this.getImageFullWidth() * this.getImageContainers().length + this.calcVisibleImagesCount() * this.getImageFullWidth() * 2 
              : -this.calcVisibleImagesCount() * this.getImageFullWidth() - this.getDividerWidth() * 2
      });
//      console.log('zone: ' + this.prev_zone);
//      console.log('offset: ' + (this.calcVisibleImagesCount() * this.getImageFullWidth() - this.getDividerWidth()));
      this.startAutoScroll();
    }
  }
}

