Carousel = function(numberOfSlides, slideChangeInterval, pauseInterval) {
    this.numberOfSlides = numberOfSlides;
    this.slideChangeInterval = slideChangeInterval;
    this.pauseInterval = pauseInterval;

    this.currentSlide = 0;
    this.currentlyChanging = false;
    
    // to preserve scope inside of callbacks (callbacks take the scope of the object they are defined on)
    var thisCarousel = this; 
    
    this.startSlideShow = function() {
        jQuery("#carousel-buttons").removeClass('hidden');
        
        thisCarousel.currentSlide = 0;
        thisCarousel.currentlyChanging = false;
        
        jQuery('#carousel-button' + thisCarousel.currentSlide).addClass('current-slide');
        
        jQuery(thisCarousel).everyTime(thisCarousel.slideChangeInterval, 'slideTransition', function() {        
            thisCarousel.changeToSlide(thisCarousel.currentSlide + 1);
        });
    };
    
    this.stopSlideShow = function() {
        jQuery(thisCarousel).stopTime('slideTransition');
        thisCarousel.currentlyChanging = false;
    };
    
    this.resumeSlideShow = function() {
        jQuery(thisCarousel).stopTime('pauseTimeOut'); // cancel any existing pause time outs
        
        jQuery('#carousel-pause').removeClass('hidden');
        jQuery('#carousel-resume').addClass('hidden');
        
        jQuery(thisCarousel).everyTime(thisCarousel.slideChangeInterval, 'slideTransition', function() {        
            thisCarousel.changeToSlide(thisCarousel.currentSlide + 1);
        });
    };
    
    this.pauseSlideShowAt = function(index) {
        if (!thisCarousel.currentlyChanging) {
            thisCarousel.stopSlideShow();
            jQuery(thisCarousel).stopTime('pauseTimeOut');
            
            if (thisCarousel.currentSlide !== index)
            {
                thisCarousel.changeToSlide(index);
            }
            
            jQuery('#carousel-pause').addClass('hidden');
            jQuery('#carousel-resume').removeClass('hidden');
            
            jQuery(thisCarousel).oneTime(thisCarousel.pauseInterval, 'pauseTimeOut', function() {
                thisCarousel.resumeSlideShow();
            });
        }
    };
    
    this.changeToSlide = function(index) {
        if (!thisCarousel.currentlyChanging) {
            thisCarousel.currentlyChanging = true;
            
            jQuery('#carousel-slide' + thisCarousel.currentSlide).fadeOut('normal', function() {
                jQuery('#carousel-button' + thisCarousel.currentSlide).removeClass('current-slide');
                thisCarousel.setCurrentSlide(index);
                jQuery('#carousel-slide' + thisCarousel.currentSlide).fadeIn('normal', function() {thisCarousel.currentlyChanging = false; });
                jQuery('#carousel-button' + thisCarousel.currentSlide).addClass('current-slide');
            });
        }
    };
    
    this.setCurrentSlide = function(newSlide) {
        if (newSlide < 0) {
            newSlide += thisCarousel.numberOfSlides;
        }
        
        thisCarousel.currentSlide = newSlide % thisCarousel.numberOfSlides;
    };
    
    jQuery('#carousel-pause').click(function() {
        thisCarousel.pauseSlideShowAt(thisCarousel.currentSlide);
    });
    
    jQuery('#carousel-resume').click(function () {
        thisCarousel.resumeSlideShow();
    });
    
    jQuery('#carousel-previous').click(function () {
        thisCarousel.pauseSlideShowAt(thisCarousel.currentSlide - 1);
    });
    
    jQuery('#carousel-next').click(function () {
        thisCarousel.pauseSlideShowAt(thisCarousel.currentSlide + 1);
    });
  
    jQuery('.carouselText a').hover(function() {
    	$(this.parentNode).addClass('hover');
    }, function() {
    	$(this.parentNode).removeClass('hover');
    });
    
    
    function buttonForSlide(slideNumber)
    {
        return function() {
            thisCarousel.pauseSlideShowAt(slideNumber);
        };
    }
    
    for (var i = 0; i < thisCarousel.numberOfSlides; i++) {
        jQuery('#carousel-button' + i).click(buttonForSlide(i));
    }
};