function Carousel(cont, framesContSel, framesSel, navItemsSel, transition) {
	this.cont = $(cont);
	
	this.framesCont = framesContSel ? this.cont.find(framesContSel) : this.cont;
	
	if (this.framesCont.css('position') == 'static') {
		this.framesCont.css({
			'position': 'relative'
		});
	}
	
	this.frames = this.cont.find(framesSel);
	this.frames.css({
		'position': 'absolute'
	});
	
	if (navItemsSel) {
		this.navItems = this.cont.find(navItemsSel);
	}
	
	this.transition = transition;
	
	this.init();
	this.selectedFrame = -1;
	this.selectFrame(0);
}

Carousel.transition = {
	slide: {
		init: function() {
			var width = this.width();
			
			this.framesCont.css('overflow', 'hidden');
			
			this.frames.each(function(i, frame) {
				$(frame).css('left', width * i);
			});
		},
		selectFrame: function(oldFrame, newFrame) {
			this.framesCont.animate({scrollLeft: newFrame * this.width()}, 500);
		}
	},
	fade: {
		init: function() {
			this.frames.css({opacity: 0, display: 'none'});
		},
		selectFrame: function(oldFrame, newFrame) {
			if (oldFrame != -1) {
				$(this.frames.get(oldFrame)).animate({opacity:0}, {
					duration: 2000,
					complete: function() {
						$(this).css('display', 'none');
					}
				});
				$(this.frames.get(newFrame)).css('display', 'block').animate({opacity:1}, 2000);
			}
			else {
				$(this.frames.get(newFrame)).css({'display': 'block', opacity: 1});
			}
			
		}
	}
	
};

Carousel.prototype = {
	init: function() {
		var that = this;
		if (this.navItems) {
			this.navItems.find('a').click(function() {
				var index = $(this).parent().index();
				that.selectFrame(index);
				return false;
			});
		}
		
		Carousel.transition[this.transition].init.call(this);
	},
	width: function() {
		return this.framesCont.innerWidth();
	},
	selectFrame: function(index) {
		var oldFrame = this.selectedFrame;
		this.selectedFrame = index;
		
		if (this.navItems) {
			var selected = this.navItems.filter('.selected').removeClass('selected');
			$(this.navItems.get(index)).addClass('selected');
		}
		
		Carousel.transition[this.transition].selectFrame.call(this, oldFrame, index);
		this._auto();
	},
	next: function() {
		this.selectFrame((this.selectedFrame + 1) % this.frames.length);
	},
	prev: function() {
		if (this.selectedFrame == 0) this.selectFrame(this.frames.length - 1);
		else this.selectFrame(this.selectedFrame - 1);
	},
	
	_auto: function() {
		if (this.autoRotate) {
			var that = this;
			
			clearTimeout(this.autoRotateTimer);
			
			this.autoRotateTimer = setTimeout(function() {
				that.next();
			}, 9000);
		}
	},
	
	auto: function(on) {
		this.autoRotate = on;
		this._auto();
	}
};

$(document).ready(function() {
	$.fn.carousel = function(opts) {
		var carousel = new Carousel(this, opts.framesContSel, opts.framesSel, opts.navItemsSel, opts.transition);
		$(this).data('carousel', carousel);
	}
});
