(function($)
 {
    var ITEM_SIZE;
    var ITEM_RECTS;
	var CAROUSEL_WIDTH;
	var CAROUSEL_HEIGHT;

    var _selectedIndex = -1;
    var _settings;

    function setupVars(ref, settings)
    {
        _settings = $.extend({
            items: new Array(),
            itemSize: 256
        },
        settings || {});

        ITEM_SIZE = _settings.itemSize;
        CAROUSEL_WIDTH = ref.width();
        CAROUSEL_HEIGHT = ref.height();
        ITEM_RECTS = preCalculateRects(_settings.items.length);
    }

    $.fn.carousel = function(settings)
    {
        var refCarousel = $(this);
        setupVars(refCarousel, settings);

        // Add items
        for (var i = 0; i < _settings.items.length; i++)
        {
            // Create item
            var wrapper = createItem(i);

            // Tooltip
            wrapper.cluetip({
                splitTitle: '|',
                width: 200,
                cluetipClass: 'carousel',
                dropShadowSteps: 4,
                leftOffset: 0,
                dropShadow: false,
                topOffset: -30,
                positionBy: "fixed"
            });

            // Click event handler
            wrapper.click(function(event)
            {
                var newIndex = $(this).attr("itemIndex");
                if (newIndex == _selectedIndex)
                {
                    // Navigate to item
                }
                else
                {
					doSelection(newIndex);
					
                    event.preventDefault();
                }
                
            });

            refCarousel.append(wrapper);
        }

        // First time animation
		doSelection(0);
        return this;
    };

	function doSelection(index)
	{
		beforeSelectionStarts();

		_selectedIndex = index;

		layout(index);
	}

	function showProjectInfo()
	{
        $("#item-title").attr("href", _settings.items[_selectedIndex].url);
        $("#item-title").html(_settings.items[_selectedIndex].title);

        $("#item-description").text(_settings.items[_selectedIndex].description);
	}
	
	function beforeSelectionStarts()
	 {
		if (_selectedIndex != -1)
		{
			$("#item_" + _selectedIndex).removeClass("item-selected");
		}
	 }

	function selectionCompleted(wrapper)
	 {
		showProjectInfo();
		wrapper.addClass("item-selected");
	 }

    function preCalculateRects(count)
    {
        var rectList = new Array();
        for (var i = 0; i < count; i++)
        {
            var rect = calculateRect(i, count);
            rectList.push(rect);
        }

        return rectList;
    }

    function createItem(index)
    {
        var img = $("<img src='" + _settings.items[index].image + "' />");
        var wrapper = $("<a id='item_" + index + "' class='carousel-link tooltip' href='" + _settings.items[index].url + "'/>").append(img);
        wrapper.attr("title", _settings.items[index].title);

        // Store index of item
        wrapper.attr("itemIndex", index);

        return wrapper;
    }

    function calculateRect(index, count)
    {
        var ratio = (index / count);
        var x = (CAROUSEL_WIDTH * 0.7) * Math.sin(ratio * 2 * Math.PI); // change CAROUSEL_WIDTH * 0.5 for wider / smaller 
        var z = Math.sin(ratio * Math.PI);

        var scale = 1 / (1 + z);

        var rect = new Object();
        rect.width = ITEM_SIZE * scale;
//         rect.height = ITEM_SIZE * scale; // use below and change multiplier for non-square
        rect.height = ITEM_SIZE * scale * 1.3;

        rect.x = (CAROUSEL_WIDTH - rect.width) * 0.5 + (x * scale);
        rect.z = count - Math.floor(count * z);
        rect.y = scale * (rect.height/1.5); // describes the streching of the entire carousel 1.5=higher, 2=flatter

        return rect;
    }

    function layout(selectedIndex)
    {
        var itemCount = _settings.items.length;
        for (var i = 0; i < itemCount; i++)
        {
            // Get the rect to be used
            var rectIndex = i - selectedIndex;
            if (rectIndex < 0)
            {
                rectIndex += _settings.items.length;
            }

            var rect = ITEM_RECTS[rectIndex];

            var wrapper = $("#item_" + i);
            wrapper.css("zIndex", rect.z);
            var img = wrapper.find("img:first");

            // Animate
            wrapper.animate({
                left: rect.x,
                top: rect.y,
                width: rect.width,
                height: rect.height
            }, 
			{complete: function()
				{
					var index = $(this).attr("itemIndex");
					if (index == _selectedIndex)
					{
						selectionCompleted($(this));
					}
				}});

            img.animate({
                width: rect.width,
                height: rect.height
            });
        }
    }

})(jQuery);

