var UI = window.UI||{};

UI.Carousel = Class.create({
  initialize : function(element, options){
    this.element = $(element);
    this.options = Object.extend({
      items : 'li',
      next : true,
      previous : true,
      numbers : true,
      scrollbar : false,
      scrollbar_markup : '<span class="l"></span><span class="r"></span>',
      handle_minimum_width : 20,
      onScroll : Prototype.emptyFunction,
			of_text : 'OF'
    }, options||{});

    this.offset = 0;
    this.index = 0;

    this.build();
  },
  build : function(){
    this.items = this.element.select(this.options.items);

    this.width = this.items.inject(0, function(acc, element, i){
      return acc+element.scrollWidth;
    });

    this.clipping = this.element.down('.ui-carousel-clipping');
    this.clipping.scrollLeft = 0;

    this.content = this.element.down('.ui-carousel-content');
    this.content.style.width = this.width+'px';



    if(this.options.scrollbar){
      this.track = new Element('div', {className: 'ui-carousel-scrollbar-track'}).update(new Element('div', {className: 'ui-carousel-scrollbar-handle'}).update(this.options.scrollbar_markup));
      this.handle = this.track.firstDescendant();
      this.element.insert(this.track);
      this.slider = new Control.Slider(this.handle, this.track, {
        axis : 'horizontal',
        onChange : this.on_change.bind(this),
        onSlide : this.on_change.bind(this)
      });
      if(this.width<=this.clipping.offsetWidth){
        this.track.hide();
      }
    }

    if(this.options.previous){
      this.previous = new Element('a', {className: 'ui-carousel-control-previous', href: '#'}).update('Previous');
      this.element.insert(this.previous);
      this.previous.observe('click', this.on_previous.bindAsEventListener(this));
      this.previous.setStyle({
        'opacity' : 0.4
      });
    }

    if(this.options.numbers){
      this.numbers = new Element('span', {className: 'ui-carousel-control-numbers'}).update('1 '+this.options.of_text+' '+this.items.size());
      this.element.insert(this.numbers);
    }

    if(this.options.next){
      this.next = new Element('a', {className: 'ui-carousel-control-next', href: '#'}).update('Next');
      this.element.insert(this.next);
      this.next.observe('click', this.on_next.bindAsEventListener(this));
      if(this.width<=this.clipping.offsetWidth){
        this.next.setStyle({
          'opacity' : 0.4
        });
      }
    }

    this.resize();
  },
  resize : function(){
    if(this.options.scrollbar){
      var w = parseInt(Math.max(this.track.offsetWidth * (this.clipping.offsetWidth / this.clipping.scrollWidth),this.options.handle_minimum_width), 10);
      if(w){
        this.slider.trackLength = this.slider.maximumOffset() - this.slider.minimumOffset();
        this.handle.style.width = w + 'px';
        this.slider.handleLength = w;
      }
    }
  },
  on_change : function(value){
    this.clipping.scrollLeft = this.get_offset(value);
    this.offset = value;
    this.toggle_controls();
    this.options.onScroll();
  },
  get_offset : function(value){
    return Math.round(value/1 * (this.clipping.scrollWidth - this.clipping.offsetWidth));
  },
  tween : function(from, to){
    if(this.options.scrollbar){
      this.slider.options.onChange = Prototype.emptyFunction;
    }
    new Effect.Tween(null, from, to, {
      duration: 0.5,
      afterFinish : function(){
        if(this.options.scrollbar){
          this.slider.options.onChange = this.on_change.bind(this);

        }
        this.options.onScroll();
      }.bind(this)
    }, function(value){

      this.clipping.scrollLeft = this.get_offset(value);
      if(this.options.scrollbar){
        this.slider.setValue(value);
      }
    }.bind(this));
  },
  on_next : function(e){
    e.stop();
    var value = Math.min(this.offset+(1/(this.items.size()-1)), 1);
    this.tween(this.offset, value);
    this.offset = value;
    this.toggle_controls();
  },
  on_previous : function(e){
    e.stop();
    var value = Math.max(this.offset-(1/(this.items.size()-1)), 0);
    this.tween(this.offset, value);
    this.offset = value;
    this.toggle_controls();
  },
  toggle_controls : function(){
    var width = this.width/this.items.size();

    var page = (this.get_offset(this.offset)/width)+1;

    this.numbers.update(page+' '+this.options.of_text+' '+this.items.size());

    if(this.width>this.clipping.offsetWidth){
      if(this.previous){
        this.previous.setStyle({
          'opacity' : ((this.offset < 0.01) ? 0.4 : 1)
        });
      }
      if(this.next){
        this.next.setStyle({
          'opacity' : ((this.offset > 0.99) ? 0.4 : 1)
        });
      }
    }
  }
});