function Carousel()	{
	// how long should the shift take
	this.duration = 500;

	// should the carousel go automaticly?
	this.auto = true;

	// how long should the intervals be?
	this.interval = 1750;

	// which direction should it go?
	this.direction = 'right';

	// the carousel
	var c = $('carousel').getElement('ul');
	
	// get the first item
	var firstItem = c.getElement('li');
	
	// get the ul margin
	var shiftSize = -(firstItem.getSize().x + firstItem.getStyle('margin-right').toInt() - 1);

	// add the first and the last element, in respect, to the end and the beginning
	var newFirstCloned	= c.getElement('li:nth-child(last)').clone().inject(c, 'top');
	var newLastCloned	= c.getElement('li:nth-child(2)').clone().inject(c, 'bottom');

	// scope reference
	var self = this;

	// set the first shift
	c.setStyle('margin-left', shiftSize);

	// the animation
	var shiftAnimation = new Fx.Morph(c, {duration: this.duration, link: 'ignore',  transition: Fx.Transitions.Sine.easeOut});

	// set mouseovers
	c.getElements('img').each( function(e) {
		self.setEvents(e);
	})
	
	// set the events of the buttons
	$('carousel_previous').addEvents({
		'mousedown' : function() {
			// stop the auto carousel
			self.auto = false;
			shiftAnimation.cancel();

			self.shiftPrevious(shiftAnimation, shiftSize, c);

			this.addClass('mousedown');
		},
		'mouseup' : function() {
			this.removeClass('mousedown');
		}
	});

	$('carousel_next').addEvents({
		'mousedown' : function() {
			// stop the auto carousel
			self.auto = false;
			shiftAnimation.cancel();

			self.shiftNext(shiftAnimation, shiftSize, c);

			this.addClass('mousedown');
		},
		'mouseup' : function() {
			this.removeClass('mousedown');
		}
	});

	// automaticly turn the carousel in a direction
	( function() {
		if ( self.auto == true) {
			switch(self.direction) {
				case 'left':
					self.shiftPrevious(shiftAnimation, shiftSize, c);
					break;
				case 'right':
					self.shiftNext(shiftAnimation, shiftSize, c);
					break;
			}	
		}
	}).periodical(this.interval);
}

// shift to the previous
Carousel.prototype.shiftNext = function(shiftAnimation, shiftSize, c) {
	// scope reference
	var self = this;

	shiftAnimation.start({
		'margin-left': 2 * shiftSize
	}).chain( function() {
		// remove the first element
		c.getElement('li:nth-child(1)').destroy();
		
		// reset the margin
		c.setStyle('margin-left', shiftSize);

		// the new last
		var newLast = c.getElement('li:nth-child(2)').clone();
		
		// set events
		self.setEvents( newLast.getElement('img') );

		// inject
		newLast.inject(c, 'bottom');

		// reset tooltips
		self.tips(c);
	});	
}

// shift to the next
Carousel.prototype.shiftPrevious = function(shiftAnimation, shiftSize, c) {
	// scope reference
	var self = this;

	shiftAnimation.start({
		'margin-left': 0
	}).chain( function() {
		// the new first
		var newFirst = c.getElement('li:nth-child('+ (c.getChildren().length - 2) +')').clone();

		// set events
		self.setEvents( newFirst.getElement('img') );
		
		// inject
		newFirst.inject(c, 'top');

		// reset the margin
		c.setStyle('margin-left', shiftSize);
		
		// remove the last element
		c.getElement('li:nth-child(last)').destroy();

		// reset tooltips
		self.tips(c);
	});	
}

// reset tooltips and mouseovers
Carousel.prototype.tips = function(c) {
	new Tips( c.getElements('.tips'), {
		className: 'tooltip'	
	});
}

// set mouseovers on images
Carousel.prototype.setEvents = function(e) {
	e.addEvent('mouseover', function() {
		e.addClass('mouseover');
	});

	e.addEvent('mouseout', function() {
		e.removeClass('mouseover');
	});
}
