(function($) {
    $.fn.featureCarousel = function (options) {
        options = $.extend({}, $.fn.featureCarousel.defaults, options || {});
        return $(this).each(function () {
            var pluginData = {
                currentCenterNum:       options.startingFeature,
                containerWidth:         0,
                containerHeight:        0,
                largeFeatureWidth:      0,
                largeFeatureHeight:     0,
                smallFeatureWidth:      0,
                smallFeatureHeight:     0,
                totalFeatureCount:      $(this).children("div").length,
                currentlyMoving:        false,
                featuresContainer:      $(this),
                featuresArray:          [],
                containerIDTag:         "#"+$(this).attr("id"),
                timeoutVar:             null,
                rotationsRemaining:     0,
                itemsToAnimate:         0,
                borderWidth:		    0
            };
            preload(function () {setupFeatureDimensions();setupCarousel();setupFeaturePositions();setupBlips();initiateMove(true,1);});
            function animateArrows() {
		var time;
		if (parseInt($(".feature-arrow-right").css('left')) == 0) {time = options.carouselSpeed - 400;} else {time = 320;}
		$(".feature-arrow-left").animate({left:-195}, time).animate({left:-185}, 300).animate({left:-200}, 275).animate({left:-195}, 250);	
		$(".feature-arrow-right").animate({left:160}, time).animate({left:150}, 300).animate({left:165}, 275).animate({left:160}, 250);	
	    }		
	    function preload(callback) {
                if (options.preload == true) {
                    var $imageElements = pluginData.featuresContainer.find("img");
                    var loadedImages = 0;
                    var totalImages = $imageElements.length;

                    $imageElements.each(function () {
                        $(this).load(function () {
                            loadedImages++;
                            if (loadedImages == totalImages) {callback();}
                        });
                        if (this.complete) {$(this).trigger('load');}
                    });
                } else {callback();}
            }
            function getContainer(featureNum) {return pluginData.featuresArray[featureNum-1];}
            function getBySetPos(position) {
                $.each(pluginData.featuresArray, function () {
                    if ($(this).data().setPosition == position)
                        return $(this);
                });
            }
            function getPreviousNum(num) {
                if ((num - 1) == 0) {
                    return pluginData.totalFeatureCount;
                } else {
                    return num - 1;
                }
            }
            function getNextNum(num) {
                if ((num + 1) > pluginData.totalFeatureCount) {
                    return 1;
                } else {
                    return num + 1;
                }
            }
            function setupFeatureDimensions() {
                pluginData.containerWidth = pluginData.featuresContainer.width();
                pluginData.containerHeight = pluginData.featuresContainer.height();
                var $firstFeatureImage = $(pluginData.containerIDTag).find("div.feature-image img:first");

                if (options.largeFeatureWidth > 1)
                    pluginData.largeFeatureWidth = options.largeFeatureWidth;
                else if (options.largeFeatureWidth > 0 && options.largeFeatureWidth < 1)
                    pluginData.largeFeatureWidth = $firstFeatureImage.width() * options.largeFeatureWidth;
                else
                    pluginData.largeFeatureWidth = $firstFeatureImage.outerWidth();
                if (options.largeFeatureHeight > 1)
                    pluginData.largeFeatureHeight = options.largeFeatureHeight;
                else if (options.largeFeatureHeight > 0 && options.largeFeatureHeight < 1)
                    pluginData.largeFeatureHeight = $firstFeatureImage.height() * options.largeFeatureHeight;
                else
                    pluginData.largeFeatureHeight = $firstFeatureImage.outerHeight();
                if (options.smallFeatureWidth > 1)
                    pluginData.smallFeatureWidth = options.smallFeatureWidth;
                else if (options.smallFeatureWidth > 0 && options.smallFeatureWidth < 1)
                    pluginData.smallFeatureWidth = $firstFeatureImage.width() * options.smallFeatureWidth;
                else
                    pluginData.smallFeatureWidth = $firstFeatureImage.outerWidth() / 2;
                if (options.smallFeatureHeight > 1)
                    pluginData.smallFeatureHeight = options.smallFeatureHeight;
                else if (options.smallFeatureHeight > 0 && options.smallFeatureHeight < 1)
                    pluginData.smallFeatureHeight = $firstFeatureImage.height() * options.smallFeatureHeight;
                else
                    pluginData.smallFeatureHeight = $firstFeatureImage.outerHeight() / 2;
            }
            function setupCarousel() {
                if (options.displayCutoff > 0 && options.displayCutoff < pluginData.totalFeatureCount) {
                    pluginData.totalFeatureCount = options.displayCutoff;
                }
                pluginData.featuresContainer.children("div").each(function (index) {
                    if (index < pluginData.totalFeatureCount) {
                        pluginData.featuresArray[index] = $(this);
                    }
                });
                if (pluginData.featuresContainer.children("div").first().css("borderLeftWidth") != "medium") {
                    pluginData.borderWidth = parseInt(pluginData.featuresContainer.children("div").first().css("borderLeftWidth"))*2;
                }
                pluginData.featuresContainer
                    .children("div").each(function () {
                        $(this).css({
                            'left': (pluginData.containerWidth / 2) - (pluginData.smallFeatureWidth / 2) - (pluginData.borderWidth / 2),
                            'width': pluginData.smallFeatureWidth,
                            'height': pluginData.smallFeatureHeight,
                            'top': options.smallFeatureOffset + options.topPadding,
                            'opacity': 0
                        });
                    }).find("div.feature-image img:first").css({'width': pluginData.smallFeatureWidth});
                if (pluginData.totalFeatureCount < 4) {
                    pluginData.itemsToAnimate = pluginData.totalFeatureCount;
                } else {
                    pluginData.itemsToAnimate = 4;
                }
                pluginData.featuresContainer.find("div > div.feature-text")
                    .hide();
            }
            function setupFeaturePositions() {
                $.each(pluginData.featuresArray, function (i) {
                    $(this).data('setPosition',i+1);
                });
                var oneBeforeStarting = getPreviousNum(options.startingFeature);
                pluginData.currentCenterNum = oneBeforeStarting;
                var $centerFeature = getContainer(oneBeforeStarting);
                $centerFeature.data('position',1);
                var $prevFeatures = $centerFeature.prevAll();
                $prevFeatures.each(function (i) {
                    $(this).data('position',(pluginData.totalFeatureCount - i));
                });
                var $nextFeatures = $centerFeature.nextAll();
                $nextFeatures.each(function (i) {
                    if ($(this).data('setPosition') != undefined) {
                        $(this).data('position',(i + 2));
                    }
                });
                if (options.counterStyle == 3) {
                    $.each(pluginData.featuresArray, function () {
                        var pos = getPreviousNum($(this).data('position'));
                        var $numberTag = $("<span></span>");
                        $numberTag.addClass("numberTag");
                        $numberTag.html("("+ pos + " of " + pluginData.totalFeatureCount + ") ");
                        $(this).find('div.feature-text p').prepend($numberTag);
                    });
                }
            }
            function setupBlips(){
                if (options.counterStyle == 1 || options.counterStyle == 2) {
                    var $list = $("<ul></ul>");
                    $list.addClass("blipsContainer");
                    for (var i = 0; i < pluginData.totalFeatureCount; i++) {
                        var counter;
                        if (options.counterStyle == 2)
                            counter = "";
                        else
                            counter = i+1;
                        var $blip = $("<div>"+counter+"</div>");
                        $blip.addClass("blip");
                        $blip.css("cursor","pointer");
                        $blip.attr("id","blip_"+(i+1));
                        var $listEntry = $("<li></li>");
                        $listEntry.append($blip);
                        $listEntry.css("float","left");
                        $listEntry.css("list-style-type","none");
                        $list.append($listEntry);
                    }
                    $(pluginData.containerIDTag).append($list);
                    $list.hide().show();
                }
            }
            function changeBlip(oldCenter, newCenter)
            {
                var $blipsContainer = pluginData.featuresContainer.find(".blipsContainer");
                var $oldCenter = $blipsContainer.find("#blip_"+oldCenter);
                var $newCenter = $blipsContainer.find("#blip_"+newCenter);
                $oldCenter.removeClass("blipSelected");
                $newCenter.addClass("blipSelected");
            }
            function autoPlay() {
                if (pluginData.timeoutVar != null) {
                    pluginData.timeoutVar = clearTimeout(pluginData.timeoutVar);
                }
                if (options.autoPlay != 0) {
                    var autoTime = (Math.abs(options.autoPlay) < options.carouselSpeed) ? options.carouselSpeed : Math.abs(options.autoPlay);
                    pluginData.timeoutVar = setTimeout(function () {
                        if (options.autoPlay > 0)
                            initiateMove(true,1);
                        else if (options.autoPlay < 0)
                            initiateMove(false,1);
                    }, autoTime);
                }
            }
            function rotatePositions(direction) {
                $.each(pluginData.featuresArray, function () {
                    var newPos;
                    if (direction == false) {
                        newPos = getNextNum($(this).data().position);
                    } else {
                        newPos = getPreviousNum($(this).data().position);
                    }
                    $(this).data('position',newPos);
                });
            }
            function animateFeature($feature, direction)
            {
                var new_width, new_height, new_top, new_left, new_zindex, new_padding, new_fade;
                var oldPosition = $feature.data('position');
                var newPosition;
                if (direction == true)
                    newPosition = getPreviousNum(oldPosition);
                else
                    newPosition = getNextNum(oldPosition);
                if (newPosition == 1) {
                    new_width = pluginData.largeFeatureWidth;
                    new_height = pluginData.largeFeatureHeight;
                    new_top = options.topPadding;
                    new_zindex = $feature.css("z-index");
                    new_left = (pluginData.containerWidth / 2) - (pluginData.largeFeatureWidth / 2) - (pluginData.borderWidth / 2);
                    new_fade = 1.0;
                } else {
                    new_width = pluginData.smallFeatureWidth;
                    new_height = pluginData.smallFeatureHeight;
                    new_top = options.smallFeatureOffset + options.topPadding;
                    new_zindex = 1;
                    new_fade = 0.5;
                    if (newPosition == pluginData.totalFeatureCount) {
                        new_left = options.sidePadding;
                    } else if (newPosition == 2) {
                        new_left = pluginData.containerWidth - pluginData.smallFeatureWidth - options.sidePadding - pluginData.borderWidth;
                    } else {
                        new_left = (pluginData.containerWidth / 2) - (pluginData.smallFeatureWidth / 2) - (pluginData.borderWidth / 2);
                        new_fade = 0;
                    }
                }
                if (newPosition != 1) {$feature.find("div.feature-text").fadeOut('slow');}
                $feature.animate({width: new_width,height: new_height,top: new_top,left: new_left,opacity: new_fade},
                        options.carouselSpeed,
                        options.animationEasing,
                        function () {
                            if (newPosition == 1) {$feature.find("div.feature-text").fadeTo("slow",0.90);}
                            pluginData.rotationsRemaining = pluginData.rotationsRemaining - 1;
                            $feature.css("z-index", new_zindex);
                            if (options.counterStyle == 1 || options.counterStyle == 2) {
                                if (newPosition == 1) {
                                    var newCenterItemNum = pluginData.featuresContainer.children("div").index($feature) + 1;
                                    var oldCenterItemNum;
                                    if (direction == false)
                                        oldCenterItemNum = getNextNum(newCenterItemNum);
                                    else
                                        oldCenterItemNum = getPreviousNum(newCenterItemNum);
                                    changeBlip(oldCenterItemNum, newCenterItemNum);
                                }
                            }
                            var divide = pluginData.rotationsRemaining / pluginData.itemsToAnimate;
                            if (divide % 1 == 0) {
                                pluginData.currentlyMoving = false;
                                rotatePositions(direction);
                                if (pluginData.rotationsRemaining > 0)move(direction);
                            }
                            autoPlay();
                        }
			//First change
                   // ).find("img:first").animate({width: new_width,height: new_height},options.carouselSpeed,options.animationEasing).end();
                   ).find("div.feature-image img:first").animate({width: new_width},options.carouselSpeed,options.animationEasing).end();
            }
            function move(direction)
            {
                pluginData.currentlyMoving = true;
                var $newCenter, $newLeft, $newRight, $newHidden;
                if (direction == true) {
                    $newCenter = getContainer(getNextNum(pluginData.currentCenterNum));
                    $newLeft = getContainer(pluginData.currentCenterNum);
                    $newRight = getContainer(getNextNum(getNextNum(pluginData.currentCenterNum)));
                    $newHidden = getContainer(getPreviousNum(pluginData.currentCenterNum));
                    pluginData.currentCenterNum = getNextNum(pluginData.currentCenterNum);
                } else {
                    $newCenter = getContainer(getPreviousNum(pluginData.currentCenterNum));
                    $newLeft = getContainer(getPreviousNum(getPreviousNum(pluginData.currentCenterNum)));
                    $newRight = getContainer(pluginData.currentCenterNum);
                    $newHidden = getContainer(getNextNum(pluginData.currentCenterNum));
                    pluginData.currentCenterNum = getPreviousNum(pluginData.currentCenterNum);
                }
                if (direction) {$newLeft.css("z-index", 3);} else {$newRight.css("z-index", 3);}
                $newCenter.css("z-index", 4);
                animateFeature($newLeft, direction);
                animateFeature($newCenter, direction);
                animateFeature($newRight, direction);
                if (pluginData.totalFeatureCount > 3) {animateFeature($newHidden, direction);}
            }
            function initiateMove(direction, rotations) {
                if (pluginData.currentlyMoving == false) {
                    var queue = rotations * pluginData.itemsToAnimate;
                    pluginData.rotationsRemaining = queue;
			animateArrows();move(direction);
		}
            }
            function findShortestDistance(from, to) {
                var goingToLeft = 1, goingToRight = 1, tracker;
                tracker = from;
                while ((tracker = getPreviousNum(tracker)) != to) {goingToLeft++;}
                tracker = from;
                while ((tracker = getNextNum(tracker)) != to) {goingToRight++;}
                return (goingToLeft < goingToRight) ? goingToLeft*-1 : goingToRight;
            }
            $(".leftButton, .feature-arrow-left").click(function () {initiateMove(false,1);});
            $(".rightButton, .feature-arrow-right").click(function () {initiateMove(true,1);});
            pluginData.featuresContainer.children("div")
                .click(function () {
                    var position = $(this).data('position');
                    if (position == 2) {initiateMove(true,1);
                    } else if (position == pluginData.totalFeatureCount) {
                        initiateMove(false,1);
                    }
                })
                .mouseover(function () {
                    if (pluginData.currentlyMoving == false) {
                        var position = $(this).data('position');
                        if (position == 2 || position == pluginData.totalFeatureCount) {
                            $(this).css("opacity",0.8);
                        }
                    }
                })
                .mouseout(function () {
                    if (pluginData.currentlyMoving == false) {
                        var position = $(this).data('position');
                        if (position == 2 || position == pluginData.totalFeatureCount) {
                            $(this).css("opacity",0.5);
                        }
                    }
                });
            $("a", pluginData.containerIDTag).live("click", function (event) {
                var $parents = $(this).parentsUntil(pluginData.containerIDTag);
                $parents.each(function () {
                    var position = $(this).data('position');
                    if (position != undefined) {
                        if (position != 1) {
                            if (position == pluginData.totalFeatureCount) {
                                initiateMove(false,1);
                            } else if (position == 2) {
                                initiateMove(true,1);
                            }
                            event.preventDefault();
                            return false;
                        }
                    }
                });
            });

            $(".blip").live("click",function () {
                var goTo = $(this).attr("id").substring(5);
                var whereIsIt = pluginData.featuresContainer.children("div").eq(goTo-1).data('position');
                var currentlyAt = pluginData.currentCenterNum;
                if (goTo != currentlyAt) {
                    var shortest = findShortestDistance(1, whereIsIt);
                    if (shortest < 0) {
                        initiateMove(false,(shortest*-1));
                    } else {
                        initiateMove(true,shortest);
                    }
                }

            });
        });
    };

    $.fn.featureCarousel.defaults = {
        largeFeatureWidth: 0,
        largeFeatureHeight: 200,
        smallFeatureWidth: .5,
        smallFeatureHeight: 100,
        topPadding: 10,
        sidePadding: 10,
        smallFeatureOffset:	60,
        startingFeature:        1,
        carouselSpeed:          3000,
        autoPlay:               3000,
        counterStyle:           0,
        preload:                true,
        displayCutoff:          0,
        animationEasing:        'swing'
    };

})(jQuery);

