(function($) {
    $.fn.imageRotator = function(dataSource, options) {
        var defaults = {
            previousButton: null,
            nextButton: null,
            imageContainer: null,
            titleContainer: null,
            descriptionContainer: null,
            progressBarContainer: null,
            contentContainer: null,
            fadeOutSpeed: 2000,
            fadeInSpeed: 2000,
            speed: 12000 // in millesecond
        };
        var options = $.extend(defaults, options);
        var currentImage = 0;
        var currentTimer = null;
        var animating = false;

        return this.each(function() {
            setupRotator();
            displayImage();
        });

        function setupRotator() {
            options.previousButton.click(
			    function() {
			        displayPrevious();
			    }
		    );

            options.nextButton.click(
			    function() {
			        displayNext();
			    }
		    );

            setupProgressBar();
        }

        function setupProgressBar() {
            for (var i = 0; i < dataSource.length; i++) {
                var progress = $("<div class='empty' id='progress" + i + "'></a></div>");
                options.progressBarContainer.append(progress);
            }
        }

        function displayNext() {
            if (animating == false) {
                ++currentImage;

                if (currentImage > dataSource.length - 1) {
                    currentImage = 0;
                }

                if (currentTimer != null) {
                    clearTimeout(currentTimer);
                }

                displayImage();
            }
        }

        function displayPrevious() {
            if (animating == false) {
                --currentImage;

                if (currentImage < 0) {
                    currentImage = dataSource.length - 1;
                }

                if (currentTimer != null) {
                    clearTimeout(currentTimer);
                }

                displayImage();
            }
        }

        function displayImage() {
            animating = true;

            options.titleContainer.html(dataSource[currentImage].Title);
            options.descriptionContainer.html(dataSource[currentImage].Description);

            var imageTag = $("<a href='" + dataSource[currentImage].NavigationUrl + "'><img src='" + dataSource[currentImage].ImageUrl + "' /></a>")
		        .hide();

            options.imageContainer.prepend(imageTag);

            if (options.imageContainer.children().length > 1) {
                var last = options.imageContainer.children(':last');

                options.contentContainer.hide();
                options.contentContainer.show(); //.fadeIn(options.fadeInSpeed);

                updateProgress();

                last
                    .stop({ gotoEnd: true })
                    .fadeOut(
		                options.fadeOutSpeed,
		                function() {
		                    $(this).remove();
		                    //updateProgress();
		                    //		                imageTag.fadeIn(
		                    //		                    options.fadeInSpeed,
		                    //		                    function() {
		                    //                                currentTimer = setTimeout(displayNext, options.speed);
		                    //                            }
		                    //                        );
		                }
                    );

                // We need to position the new image absolutely over the old one
                // so that the fade in/out effect works properly
                var pos = last.position;

                imageTag
		            .css(
		                {
		                    position: 'absolute',
		                    marginLeft: 0,
		                    marginTop: 0,
		                    top: pos.top,
		                    left: pos.left
		                }
		            )
                    .stop({ gotoEnd: true })
                    .fadeIn(
                        options.fadeInSpeed,
                        function() {
                            animating = false;

                            if (options.speed > 0) {
                                currentTimer = setTimeout(displayNext, options.speed);
                            }
                        }
                    );
            } else {
                imageTag.show();
                updateProgress();

                if (options.speed > 0) {
                    currentTimer = setTimeout(displayNext, options.speed);
                }

                animating = false;
            }
        }

        function updateProgress() {
            options.progressBarContainer.children().each(
	            function() {
	                $(this)
	                    .removeClass('filled')
	                    .addClass('empty');
	            }
	        );

            options.progressBarContainer
	                .children('#progress' + currentImage)
                    .addClass('filled');
        }
    };
})(jQuery);