// carosello v 2.0 by F.Buratti http.//cssrevolt.com
// inspired by Bruno Bornsztein <bruno@missingmethod.com>  & Victor Stanciu <contact@victorstanciu.ro>
Carosello = Class.create({
					  
	initialize: function(wrapper, options){
	    this.scrolling  		= false;
	    this.wrapper    		= $(wrapper);
	    this.scroller   		= this.wrapper.down('div.scroller');
	    this.sections   		= this.wrapper.getElementsBySelector('div.section');
		this.btn_sections      	= this.wrapper.getElementsBySelector('div.controls a');
		this.options 			= {
									duration: 1.0, 
									frequency: 4, 
									autoGlide:false,
									prevNext:false,
									controls:false,
									selectedClassName: 'selected'
 								  }
 		Object.extend(this.options, options || {})

	    this.sections.each(function(section, index) {
	    	section._index = index;
	    });  
		
		if (this.options.prevNext) {
			this.btn_next = new Element('a', { 'class': 'btn_next', 'title': 'Next', href: '#' }).update("Next");
			this.wrapper.appendChild(this.btn_next);
			this.btn_next.observe('click', this.next.bind(this));
		
			this.btn_previous = new Element('a', { 'class': 'btn_previous', 'title': 'Previous', href: '#' }).update("Previous");
			this.wrapper.appendChild(this.btn_previous);
			this.btn_previous.observe('click', this.previous.bind(this));
		}

		if (this.options.controls) {
			this.btn_sections[0].addClassName(this.options.selectedClassName);
			this.btn_sections.invoke('observe', 'click', this.click.bind(this));
		}
		
		if (this.options.autoGlide) {
			this.start();
			this.sections.invoke('observe', 'mouseover', this.pause.bind(this));
			this.sections.invoke('observe', 'mouseout', this.resume.bind(this));
		}
				
	},

  	click: function(event) {
		this.stop();
    	var element = Event.findElement(event, 'a');
					
    	if (this.scrolling) this.scrolling.cancel();
    
    	this.moveTo(element, element.href.split("#")[1], this.scroller, { duration:this.options.duration });     
    	Event.stop(event);
  	},

	moveTo: function(btn, element, container, options){
		if (this.options.controls && this.options.selectedClassName) {
			this.btn_sections.each((function (elm) { elm.removeClassName(this.options.selectedClassName); }).bind(this));
			btn.addClassName(this.options.selectedClassName);
		}	
	
		this.current = $(element);

		Position.prepare();
	    var containerOffset = Position.cumulativeOffset(container),
	    elementOffset = Position.cumulativeOffset($(element));

		this.scrolling 	= new Effect.SmoothScroll(container, 
				{duration:options.duration, x:(elementOffset[0]-containerOffset[0]), y:(elementOffset[1]-containerOffset[1])});
		  return false;
		},
		
  	next: function(event){
		if (event) { Event.stop(event); }
		
		if (this.scrolling) this.scrolling.cancel();
		
    	if (this.current) {
      		var currentIndex = this.current._index;
      		var nextIndex = (this.sections.length - 1 == currentIndex) ? 0 : currentIndex + 1;      
    	} else var nextIndex = 1;

    	this.moveTo( this.btn_sections[nextIndex], this.sections[nextIndex], this.scroller, { 
      		duration: this.options.duration
    	});
  	},
	
  	previous: function(event){
		if (event) { Event.stop(event); }
		
		if (this.scrolling) this.scrolling.cancel();
		
    	if (this.current) {
      		var currentIndex = this.current._index;
      		var prevIndex = (currentIndex == 0) ? this.sections.length - 1 : currentIndex - 1;
    	} else var prevIndex = this.sections.length - 1;
    
    	this.moveTo(this.btn_sections[prevIndex], this.sections[prevIndex], this.scroller, { duration: this.options.duration });
  	},

	stop: function() {
		clearTimeout(this.timer);
	},
	
	start: function() {
		this.periodicallyUpdate();
	},
	
	pause: function (event) {
		this.stop();
	},
	
	resume: function (event) {
		if (event) {
			var related = event.relatedTarget || event.toElement;	
			if (!related || (!this.sections.include(related) && !this.sections.any(function (slide) { return related.descendantOf(slide); }))) {
				this.start();
			}
		} 
		else {
			this.start();
		}
	},
		
	periodicallyUpdate: function() {  
		if (this.timer != null) {
			clearTimeout(this.timer);
			this.next();
	}
		this.timer = setTimeout(this.periodicallyUpdate.bind(this), this.options.frequency*1000);
	
	}

});

Effect.SmoothScroll = Class.create();
Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'absolute'
    } , arguments[1] || {}  );
    this.start(options);
  },
  setup: function() {
    if (this.options.continuous && !this.element._ext ) {
      this.element.cleanWhitespace();
      this.element._ext=true;
      this.element.appendChild(this.element.firstChild);
    }
   
    this.originalLeft=this.element.scrollLeft;
    this.originalTop=this.element.scrollTop;
   
    if(this.options.mode == 'absolute') {
      this.options.x -= this.originalLeft;
      this.options.y -= this.originalTop;
    } 
  },
  update: function(position) {   
    this.element.scrollLeft = this.options.x * position + this.originalLeft;
    this.element.scrollTop  = this.options.y * position + this.originalTop;
  }
});
