var Carrousel = new Class({
  Implements: Options,
  options: {
    'container'         : 'carrousel',
    'buttonNext'        : 'button-next',
    'buttonPrevious'    : 'button-previous',
    'addSelectors'      : false,
    'selectorClass'     : 'selector',
    'selectorId'        : 'carrousel_btn_',
    'subSelectorId'     : 'carrousel_dim_btn_',
    'selectorPosition'  : 'bottom',
    'selected'          : 'selected'
  },
  initialize: function(root, options) {
    this.setOptions(options)
    this.carrousel = root.getElement('.'+this.options.container)
    if (!this.carrousel || this.carrousel.getElements('li').length == 0) return false
    this.carrousel_window = this.carrousel.getElements('ul').getParent()[0]
    this.carrousel_items = this.carrousel.getElement('ul').getChildren('li')
    this.carrousel_length = this.carrousel_items.length
    this.carrousel_current = 0
    this.carrousel_move = this.carrousel_items[0].getSize().x
    // Get Multidimensional lists
    this.subs = (this.carrousel_items[0].getElements('ul').length > 0)
    if(this.subs) {
      this.carrousel_sub_items   = new Array()
      this.carrousel_sub_lengths = new Array()
      this.carrousel_sub_current = new Array()
      
      this.carrousel_items.each( function(li, i) {
        this.carrousel_sub_items[i]   = li.getElements('li')
        this.carrousel_sub_lengths[i] = li.getElements('li').length
        this.carrousel_sub_current[i] = 0
      }.bind(this))
      
      this.carrousel_sub_move = this.carrousel_sub_items[0][0].getSize().y
    }
    window.addEvent('load', function() {
      this.build()
    }.bind(this))
  },
  build: function() {
    // Build selectors
    this.selectors = new Array
    this.addSelectors(0)
    if(this.subs) { this.addSelectors(1) }
    if(this.carrousel_length <= 1) { return }
    // Build buttons
    var that = this
    this.btnPrevious = new Element('a', {
      'class': that.options.buttonPrevious
    }).addEvent('click', function(e) {
      e.stop()
      that.move(that.carrousel_current - 1)
      return false
    }).inject(this.carrousel_window, 'before')
    this.btnNext = new Element('a', {
      'class': this.options.buttonNext
    }).addEvent('click', function(e) {
      e.stop()
      that.move(that.carrousel_current + 1)
      return false
    }).inject(this.carrousel_window, 'after')
    this.updateButtons()
  },
  addSelectors: function(lvl) {
    if(!lvl) { lvl = 0 }
    if(!this.options.addSelectors && 0 == lvl) { return }
    if(!this.div) { this.div = new Element('div', {'class': this.options.selectorClass+'s' }) }
    else { this.div.empty() }
    var div = this.div
    if(0 == lvl) { elements = this.carrousel_items  }
    else { elements = this.carrousel_sub_items[this.carrousel_current] }
    elements.each(function(e, i) {
      btn = new Element('div', {
        'id': (0 == lvl ? this.options.selectorId : this.options.subSelectorId)+i,
        'class': this.options.selectorClass
      }).addEvent('click', function(e){
        if(0 == lvl) { this.move(i) }
        else { this.moveSubs(i) }
      }.bind(this)).inject(div, 'bottom')
    }.bind(this))
    this.selectors[lvl] = div.getElements('.'+this.options.selectorClass)
    this.updateSelectors(lvl)
    div.inject(this.carrousel, this.options.selectorPosition)
    if(0 == lvl) {
      var wid = this.carrousel_length * (div.getFirst().getWidth() + div.getFirst().getStyle('margin-left').toInt() + div.getFirst().getStyle('margin-right').toInt() +1)
    } else {
      var wid = this.carrousel_sub_lengths[this.carrousel_current] * (div.getFirst().getWidth() + div.getFirst().getStyle('margin-left').toInt() + div.getFirst().getStyle('margin-right').toInt() +1)
    }
    div.setStyle('width', wid)
  },
  updateButtons: function() {
    this.btnPrevious.removeClass('disabled')
    this.btnNext.removeClass('disabled')
    if(this.carrousel_current == this.carrousel_length - 1) { this.btnNext.addClass('disabled') }
    else if(this.carrousel_current == 0) {this.btnPrevious.addClass('disabled') }
  },
  updateSelectors: function(lvl) {
    if(!lvl) { lvl = 0 }
    this.carrousel.getElements('.'+this.options.selected).removeClass(this.options.selected)
    if(0 == lvl) { this.selectors[0][this.carrousel_current].addClass(this.options.selected) }
    else if(1 == lvl) { this.selectors[0][this.carrousel_sub_current[this.carrousel_current]].addClass(this.options.selected) }
  },
  move: function (pos) {
    if (pos > this.carrousel_length-1) { pos = 0 }
    else if (pos < 0) { pos = this.carrousel_length-1 }
    if (this.carrousel_current == pos) { return }
    this.carrousel_current = pos
    this.updateButtons()
    this.updateSelectors(0)
    this.carrousel.getElement('ul').tween('margin-left', 0-(this.carrousel_current * this.carrousel_move))
    if(this.subs) { this.addSelectors(1) }
  },
  moveSubs: function (pos) {
    if(pos > this.carrousel_sub_lengths[this.carrousel_current]-1) { pos = this.carrousel_sub_lengths[this.carrousel_current]-1 }
    else if(pos < 0) { pos = 0 }
    if(this.carrousel_sub_current[this.carrousel_current] == pos) { return }
    this.carrousel_sub_current[this.carrousel_current] = pos
    this.carrousel_items[this.carrousel_current].getElement('ul').tween('margin-top', (0-(pos * this.carrousel_sub_move)))
    this.updateSelectors(1)
  }
})

Element.behaviour(function() { new Carrousel(this, { addSelectors: true }) })
