function RadioCarousel(userOpts)
{
	function defaultOpts()
	{
		this.wrapper = '.radioCarousel';
		this.radioItem = '.radioCarouselItem';
		this.firstSelectedIndex = 0;
		this.startCb = null;
		this.stopCb = null;
	}
	
	var inst = this;
	inst.opts = new defaultOpts();
	inst.currentEl = {};
	inst.slideDirection = "left"; //maybe convert these to vars so that 'this' isn't being used throughout???
	inst.clickEnabled = false;
	inst.currentIndex = null;
	
	var carouselWrapper = null,
	carouselItems = null;
	
	//****CONSTANTS****
	var ANIMATION_DURATION = 400,
	ANIMATION_EASING = 'swing',
	CAROUSEL_WINDOW_WIDTH = '480px',
	CAROUSEL_WINDOW_HEIGHT = '115px',
	CAROUSEL_DEFAULT_WIDTH = '350px',
	carouselHeight = CAROUSEL_WINDOW_HEIGHT;
	
	
	function setConfig(userOpts)
	{
		if (!!userOpts) {
            $.each(inst.opts, function( key ){
                if (typeof userOpts[key] != 'undefined') {
                    inst.opts[key] = userOpts[key];
                }
            });
        }
	}
	
	function RadioCarouselItem()
	{
		this.radioIndex = 0;
		this.selectedState = false;
		this.radioButton = {};
		
		this.setIndex = function(val)
		{
			this.radioIndex = val;	
		}
		this.getIndex = function()
		{
			return this.radioIndex;	
		}
		this.setSelected = function(val)
		{
			this.selectedState = val;	
		}
		this.isSelected = function()
		{
			return this.selectedState;	
		}								   
	}
	
	function getCurrentSelection()
	{
		return inst.currentIndex;	
	}
	
	function next(event)
	{
		event.preventDefault();
		
		if(!inst.clickEnabled) return;
		
		inst.slideDirection = 'left';
		
		if(inst.currentIndex == ((carouselItems.length) - 1))
		{
			slideTo(0);
		} else {
			slideTo(inst.currentIndex + 1);
		}
		
		if (typeof inst.opts.startCb == 'function') {
			inst.opts.startCb.apply(carouselItems, [getCurrentSelection(), inst.slideDirection]);
		}
	}
	
	function previous(event)
	{
		event.preventDefault();
		
		if(!inst.clickEnabled) return;
		
		inst.slideDirection = 'right';
		
		if((inst.currentIndex) == 0)
		{
			slideTo((carouselItems.length) - 1);
		} else {
			slideTo((inst.currentIndex) - 1);
		}
		
		if (typeof inst.opts.startCb == 'function') {
			inst.opts.startCb.apply(carouselItems, [getCurrentSelection(), inst.slideDirection]);
		}
	}
	
	function slideTo(index)
	{
		
		inst.clickEnabled = false;
		if(index == inst.currentIndex) return;
		
		var previousItem = carouselItems.get(inst.currentIndex);
		previousItem.radioCarouselItem.setSelected(false);
		
		var previousIndex = inst.currentIndex;
		
		inst.currentIndex = index;
		var newItem = carouselItems.get(inst.currentIndex);
		newItem.radioCarouselItem.setSelected(true);
		
		// select the appropriate radio button
		newItem.radioCarouselItem.radioButton.attr('checked', 'true');
		inst.currentEl = newItem.radioCarouselItem.radioButton;
		
		var amt = CAROUSEL_WINDOW_WIDTH,
		leftPad = $.forceInt(($.forceInt(CAROUSEL_WINDOW_WIDTH) - $.forceInt($(newItem).outerWidth() || CAROUSEL_DEFAULT_WIDTH)) / 2);

		if (inst.slideDirection == 'left')
		{
			$(newItem).css({left: amt, top: '0'});
			amt = '-'+amt;
		} else {
			$(newItem).css({left: '-'+amt, top: '0'});
		}
		
		setTimeout(function() {
			$(previousItem).animate({left: amt}, {duration: ANIMATION_DURATION, easing: ANIMATION_EASING, complete:function(){
				inst.clickEnabled = true;
				if (typeof inst.opts.stopCb == 'function') {
					inst.opts.stopCb.apply(carouselItems, [getCurrentSelection()]);
				}
			}});
			$(newItem).animate({left: leftPad}, {duration: ANIMATION_DURATION, easing: ANIMATION_EASING, complete:function(){
				inst.clickEnabled = true;
				if (typeof inst.opts.stopCb == 'function') {
					inst.opts.stopCb.apply(carouselItems, [getCurrentSelection()]);
				}
			}});
		}, 0);
		
	}
	
	function init(initOpts)
	{
		setConfig(initOpts);
		
		var counter = 0,
		lastItem = {},
		itemHasBeenChecked = false;
		
		carouselWrapper = $(inst.opts.wrapper);
		carouselWrapper.addClass('carouselWindow');
		carouselItems = carouselWrapper.find(inst.opts.radioItem);
		
		if (carouselItems.length != 0)
		{
			carouselItems.each(function()
			{
				var thisObj = $(this);
				this.radioCarouselItem = new RadioCarouselItem();
				var rci = this.radioCarouselItem;
				rci.radioButton = thisObj.find('input[type="radio"]');
				
				if (rci.radioButton.attr('checked'))
				{
					itemHasBeenChecked = true;
				}
				
			});
			
			//if there weren't any carousel items selected, select the first one
			if (!itemHasBeenChecked)
			{
				carouselItems[0].radioCarouselItem.radioButton.attr('checked', true);
				inst.currentIndex = 0;
			}
			
			carouselItems.each(function()
			{
				var thisObj = $(this),
				tempHeight = thisObj.outerHeight(),
				leftPad = $.forceInt(($.forceInt(CAROUSEL_WINDOW_WIDTH) - $.forceInt(thisObj.outerWidth() || CAROUSEL_DEFAULT_WIDTH)) / 2);
				
				//this.radioCarouselItem = new RadioCarouselItem();
				var rci = this.radioCarouselItem;
				rci.setIndex(counter);
				
				//rci.radioButton = thisObj.find('input[type="radio"]');
				
				if ($.forceInt(carouselHeight) < $.forceInt(tempHeight)) {
					carouselHeight = tempHeight;
				}
				
				if (rci.radioButton.attr('checked') && itemHasBeenChecked) //do i need to check that more that one isn't checked here???
				{
					rci.setSelected(true);
					inst.currentIndex = counter;
					inst.currentEl = rci.radioButton;
					thisObj.css({left: leftPad, top: '0', position: 'absolute'}); //make these CSS values CONSTANTS defined above
				} else {
					thisObj.css({left: leftPad, top: '500px', position: 'absolute'}); //make these CSS values CONSTANTS defined above
				}
				counter++;
				lastItem = this; 
			});
			
			if(carouselItems.length > 1)
			{
				$(lastItem).after(
				'	<div id="carouselButtons">'+
				'		<a id="prevItem" href="#">'+
				'			<span>Previous</span>'+
				'		</a>'+
				'		<div class="carouselInfo">'+
				'			<strong>Saved Card</strong><br>'+
							'<span id="currentCarouselIndex" style="margin: 0; float: none;">' + (inst.currentIndex + 1) + '</span>' + '  of  ' + carouselItems.length +
				'		</div>'+
				'		<a id="nextItem" href="#">'+
				'			<span>Next</span>'+
				'		</a>'+
				'		<div class="clear"></div>'+
				'	</div>'
				);
			}
		}
		
		carouselItems.wrapAll('<div class="carouselWindow"></div>');
		
		carouselWrapper.find('div.carouselWindow').css({overflow: 'hidden', width: CAROUSEL_WINDOW_WIDTH, height: carouselHeight, position: 'relative'});
		
		carouselWrapper.find('a#prevItem').bind('click', previous);
		carouselWrapper.find('a#nextItem').bind('click', next); 
		
		inst.clickEnabled = true;
	}
	init(userOpts);
}
