var fancyCarousel = new Class({
	Implements: [Options, Events],
	
	options: {
		fade: false,
		duration: 500,
		auto: false,
		autoTime: 1000,
		initialPosition: 0,
		orientation: 'horizontal',
		transition: 'sine:in:out',
		fps: 50
	},
	
	initialize: function(wrapper,itemCname,options){
		this.setOptions(options);
		this.wrapper = $(wrapper);
		this.itemCname = itemCname;
		this.items = this.wrapper.getElements("."+this.itemCname);
		this.nItems = this.items.length;
		if (this.options.initialPosition=='random'){
		  this.options.initialPosition = Math.floor(Math.random()*this.nItems);
		}
		if (this.options.orientation=='horizontal'){
		  this.despl = this.items[this.options.initialPosition].getStyle('width').toInt();
		  this.wrapper.setStyle('margin-left',this.wrapper.getStyle('margin-left').toInt()-(this.despl*this.options.initialPosition));
		  this.cMargin = this.wrapper.getStyle('margin-left').toInt();
		}else{
		  this.despl = this.items[this.options.initialPosition].getStyle('height').toInt();
		  this.wrapper.setStyle('margin-top',this.wrapper.getStyle('margin-top').toInt()-(this.despl*this.options.initialPosition));
		  this.cMargin = this.wrapper.getStyle('margin-top').toInt();
		}
		this.fx = new Fx.Tween(this.wrapper,{
		  duration: this.options.duration,
		  link: 'cancel',
		  fps: this.options.fps,
		  transition: this.options.transition,
		  onComplete: function(){
		    this.fireEvent('completed',this.cIndex);
		  }.bind(this)
		});
		this.cIndex = this.options.initialPosition;
	},
	fire: function(){
	  this.fireEvent('started',this.cIndex);
	  
	  if (this.options.auto){
	    var initialFunction = function(){
	      this.goNext();
	    }.bind(this);
	    this.moveFunction = initialFunction.create({
	      periodical: this.options.autoTime
	    });
	    this.moveFunction.bind(this);
	    this.timer = this.moveFunction.run();
	  }
	},
	goTo: function(where){
		var jumps = where-this.cIndex;
		var direction;
		if (jumps>0){
		  direction = -1;
		}else if (jumps<0){
		  direction = 1;
		}else{
		  direction = 0;
		}
		if (direction!=0){
		  var despl = (this.despl)*jumps;
		  if (direction>0){
		      despl = Math.abs(despl);
		  }else{
		      despl = despl * -1;
		  }
		  this.cMargin = this.cMargin + despl;
		  if (this.options.fade)
		    this._fadeAnim(this.cMargin);
		  else
		    this._anim(this.cMargin);
		  this.cIndex = where;
		  this.fireEvent('started',this.cIndex);
		}
	},
	goNext: function(){
	  this.goTo((this.cIndex+1)%this.nItems);
	},
	goPrev: function(){
	  if (this.cIndex-1<0)
	    this.goTo(this.nItems-1)
	  else
	    this.goTo(this.cIndex-1);
	},
	_anim: function(despl){
		if (this.options.orientation == "horizontal")
		  this.fx.start('margin-left',despl);
		else
		  this.fx.start('margin-top',despl);
	},
	_fadeAnim: function(despl){
		this.fx.start('opacity',0).chain(function(){
		    if (this.options.orientation == 'horizontal')
		      this.wrapper.setStyle('margin-left',despl);
		    else
		      this.wrapper.setStyle('margin-top',despl);
		    this.fx.start('opacity',1);
		}.bind(this));
	},
	bindNext: function(elem){
	  $(elem).addEvent('click',function(){
	      this.goNext();
	      return false;
	  }.bind(this));
	},
	bindPrev: function(elem){
	  $(elem).addEvent('click',function(){
	      this.goPrev();
	      return false;
	  }.bind(this));
	},
	bindControl: function(elem, cls, pos){
	  $(elem).addEvent('click',function(){
	    this.goTo(pos);
	    return false;
	  }.bind(this));
	  this.addEvent('started', function(idx){
		if ($(elem).hasClass(cls)){
		  $(elem).toggleClass(cls);
		}else if (pos==idx)
		  $(elem).toggleClass(cls);
	  });
	}
});
