function Carousel(el, ui, pages, opts)
{
	var C1 = "current-card";
	var C2 = "new-card";
	var W = opts.width;
	var self = this;
	var len = pages.length;
	var sid = null
	var animating = false;
	
	function createDot(i)
	{
		var d = document.createElement('div');
		d.id = 'dot' + i;
		d.className = 'cr-dot' + (i != 0 ? '' : ' selected');
		d.onclick = function()
		{
			callByIndex(i);
		};
		
		return d;
	}
	
	if (el != null)
	{
		this.container = el;
		this.pages = pages;
		this.index = 0;
		this.timer = 5000;	
		this.transitionDuration = 1;
		
		for (var i = 0; i < len; i++)
		{
			var d = createDot(i);
			d.style.top = '5px';
			d.style.left = (W - (len*20) + i*20) + 'px';
			ui.appendChild(d);
		}
		
		if (opts)
		{
			if (opts.timePerSlide) this.timer = opts.timePerSlide*1000;
			if (opts.transitionDuration) this.transitionDuration = opts.transitionDuration;
		}		
		
		
		
		function callNext()
		{
			self.index++;
			if (self.index > len-1)
				self.index = 0;
			
			callByIndex(self.index, true);
		}
		
		function callBefore()
		{
			self.index--;
			if (self.index < 0)
				self.index = len-1;
			
			self.reverse = true;
			callByIndex(self.index, true);
		}
		
		function callByIndex(index, force)
		{
			if (animating || index == self.index && !force) return;
			self.index = index;
			var first = document.getElementById(C1);
			var second = document.createElement('div');
			second.id = C2;
			second.className = 'card';
			second.style.left = (self.reverse ? -W : W) + 'px';
			
			el.appendChild(second);
			second.innerHTML = pages[index];
			
			animate();
			
			if (sid)
				clearTimeout(sid);
			
			sid = setTimeout(callNext, self.timer);	
			
			for (var i = 0; i < len; i++)
			{
				var d = document.getElementById('dot' + i);
				d.className = 'cr-dot' + (i == index ? ' selected' : '');
			}
		}
		
		function onAnimateEnd()
		{
			var first = document.getElementById(C1);	
			var second = document.getElementById(C2);
			first.parentNode.removeChild(first);
			second.id = C1;
			second.style.left = 0 + 'px';
			animating = false;
			self.reverse = false;
		}
		
		function animate()
		{
			animating = true;
			var interval = 1000/60;
			var dur = self.transitionDuration;
			var shiftAmount = Math.ceil(W/(dur*interval));
			var shift = 0;
			var first = document.getElementById(C1);	
			var second = document.getElementById(C2);
			
			function step()
			{
				shift += shiftAmount;
					
				if (shift < W)
				{
					if (self.reverse)
					{
						first.style.left = shift + 'px';
						second.style.left = -W+shift + 'px';
					}
					else
					{
						first.style.left = -shift + 'px';
						second.style.left = W-shift + 'px';
					}
					setTimeout(step, interval);
				}
				else
				{
					onAnimateEnd();
				}
			}
			step();
		}
		
		sid = setTimeout(callNext, self.timer);
	}

        this.call = function(i) {
          callByIndex(i,true);
        };
	
	this.next = function()
	{
		callNext();
	};
	
	this.prev = function()
	{
		callBefore();
	};
	
	this.precache = function(imgs)
	{
		var len = imgs.length;
		var iIndex = 0;
		var temp = document.createElement('img');
		temp.style.display = 'none';
		
		function nextImage()
		{
			iIndex++;
			loadImage();
		}		
		
		function loadImage()
		{
			if (iIndex >= len) 
			{
				temp = null;
				return;
			}
			var src = imgs[iIndex];
			
			temp.src = src;
		}		
		
		temp.onload = nextImage;
		loadImage();		
	};
};
