/**
 * Carousel with loading
 * 
 * @version $Id$
 */
Carousel = function(config){
  // configurable {
  this.selector = ''; //required
  this.next_button_selector = ''; 
  this.prev_button_selector = '';
  this.auto_init = false;
  this.is_loaded = false;
  this.mousewheel = false;
  this.scroll_speed = 'normal';
  this.element_visible = 3;
  this.element_width = 291;
  this.element_margin = 25;
  this.position = 0; 
  this.load_position = 2;
  this.url = '';
  this.id_prefix = 'citem_';
  // }
  
  this.counter = 0;
  this.load_flag = false;
  
  $.extend(this, config);
  if(this.auto_init)
    this.init();
}

Carousel.prototype = {
  init: function(){
    this.initButtons();
    this.initCarousel();
    this.syncButtons();
    if(this.mousewheel)
      this.initMouseWheel();
  },
  
  initButtons: function(){
    this.getNextButton().click(this.onNext.createDelegate(this));
    this.getPrevButton().click(this.onPrev.createDelegate(this));
  },
  
  initCarousel: function(){
    var li = $('li', this.getListEl());
    var width = 0;
    var _this = this;
    li.each(function(){
      $(this).width(_this.element_width).css('margin-right', _this.element_margin);
      width += _this.element_width + _this.element_margin;
    })
    this.getListEl().width(width);
    this.counter = li.length;
  },
  
  initMouseWheel: function() {
    var $el = this.getEl();
    if($el.mousewheel)
      $el.mousewheel(this.onMouseWheel.createDelegate(this));
  },
  
  syncButtons: function() {
    this._activateButton(this.getNextButton(), this.hasNext());
    this._activateButton(this.getPrevButton(), this.hasPrev());
  },
  
  _activateButton: function($button, state) {
    if(state)
      $button.addClass('active');
    else
      $button.removeClass('active');
  },
  
  hasNext: function() {
    return this.position < this.counter - this.element_visible;
  },
  
  hasPrev: function() {
    return this.position > 0;
  },
  
  doPrev: function(){
    if(this.hasPrev())
      this.doMove('+');
  },
  
  doNext: function(){
    if (this.hasNext()) {
      this.doMove('-');
      if (this.counter - this.position - this.element_visible <= this.load_position) 
        this.preload();
    }
  },
  
  doMove: function(direction){
    this.getListEl().animate({
      left: direction+'='+(this.element_margin + this.element_width)+'px'
    }, this.scroll_speed, 'swing', this.onEndMove.createDelegate(this));
    this.position += (direction == '+') ? -1 : 1;
  },
  
  preload: function(){
    if(this.load_flag || this.is_loaded)
      return;
    this.load_flag = true;
    $.post(this.url, {id:this.getCurrentElementId()}, this.onLoad.createDelegate(this));
  },
  
  getCurrentElementId: function(){
    var item_id = $('li', this.getListEl()).eq(this.counter -1).attr('id');
    return item_id.substr(this.id_prefix.length);
  },
  
  onLoad: function(data){
    this.load_flag = false;
    data = $.trim(data);
    if(data == '') {
      this.is_loaded = true;
      return;
    }
    $(data).appendTo(this.getListEl());
    var new_length = $('li', this.getListEl()).length;
    if(new_length == this.counter)
      this.is_loaded = true;
    this.counter = new_length;
    this.getListEl().width(this.counter*(this.element_width + this.element_margin));
  },
  
  onPrev: function(){
    this.doPrev();
    return false;
  },
  
  onNext: function(){
    this.doNext();
    return false;
  },
  
  onMouseWheel: function(e, delta) {
    return delta > 0 ? this.onPrev() : this.onNext();
  },
  
  onEndMove: function() {
    this.syncButtons();
  },
  
  getListEl: function(){
    return $('ul', this.getEl());
  },
  
  getEl: function(){
    return $(this.selector);
  },
  
  getNextButton: function(){
    return $(this.next_button_selector);
  },
  
  getPrevButton: function(){
    return $(this.prev_button_selector);
  }
}