function CouroSlideshow(options) {
    var isAnimating = false;
	var isAutoPlaying = false;
	var slideshow;
	var slides;
	var slides_count = 0;
	var currentSlide = 0;
	var lastSlide = 0;
	var width = 0;
	var slideshowTimeout;
	var imagesProcessed = ['test'];
	var processingTimeout;
	var processingDelay = 100;
	var slideshowRatio = 0;
    
    // default configuration properties
	var defaults = {			
		id: 	        'CouroSlideshow',
		format:         'numbers',	// numbers | squares | circles
		speed:          500,
		pause:          3000,
		height:         259,
        width:          513,
        autoplay:       true,
        showPlayPause:  true
	}; 
		
	var options = $.extend(defaults, options);

	var init = function () {
	    slideshow = jQuery('#' + options.id);
	    slides = jQuery('.slide', slideshow);
	    slides_count = slides.length;
	    slideshowRatio = options.width / options.height;

	    generateControls();
	    highlightThumb();

	    slides.css('left', options.width);
	    jQuery('.slide:eq(0)', slideshow).css('left', 0);

	    if (options.autoplay) {
	        isAutoPlaying = true;
	        slideshowTimeout = setTimeout(nextSlide, options.pause);
	    }
	    resizeSlideshow();
	    processingTimeout = setTimeout(processImages, processingDelay); 
	}

    var resizeSlideshow = function () {
        jQuery('.outer', slideshow).css('height', options.height).css('width', options.width);
        jQuery('.slide', slideshow).css('height', options.height).css('width', options.width);
        jQuery('.slide p', slideshow).css('width', options.width - 20);
        jQuery('.slideshowControls', slideshow).css('width', options.width - 10);
    }

    var processImages = function () {
        var i = -1;

        jQuery('.slide', slideshow).each(function (index) {
            if (jQuery.inArray(index, imagesProcessed) == -1) {

                var height = jQuery('img', jQuery(this)).height();
                var width = jQuery('img', jQuery(this)).width();

                if (height > 0 && width > 0) {
                    if (width / height > slideshowRatio) {
                        jQuery('img', jQuery(this)).css('width', options.width);
                    } else {
                        jQuery('img', jQuery(this)).css('height', options.height);
                    }

                    imagesProcessed.push('test');
                }
            }
        });

        if (imagesProcessed.length < slides_count) {
            processingTimeout = setTimeout(processImages, processingDelay);
        }
    }

    var generateControls = function () {
        var html = [];
        html.push('<div class="slideshowControls"> <a class="btnPrev" href="javascript:void(0)">Prev</a><a class="btnNext" href="javascript:void(0)">Next</a>');
        if (options.showPlayPause) {
            html.push('<a class="btnPlayPause" href="javascript:void(0)">' + (options.autoplay ? 'Pause' : 'Play') + '</a>');
        }
        html.push('<p class="slideshowThumbs thumbsFormat_' + options.format + '">');

        var i = -1;
        while (++i < slides_count) {
            html.push('<a rel="' + i + '" class="thumb thumb_' + (i + 1) + '" href="javascript:void(0)">' + (i + 1) + '</a>');
        }

        html.push('</p> </div>');

        slideshow.append(html.join(' '));
        jQuery('.slideshowControls .thumb', slideshow).click(thumb_click);
        jQuery('.slideshowControls .btnPrev', slideshow).click(btnPrev_click);
        jQuery('.slideshowControls .btnNext', slideshow).click(btnNext_click);
        jQuery('.slideshowControls .btnPlayPause', slideshow).click(btnPlayPause_click);
        if (options.autoplay) jQuery('.slideshowControls .btnPlayPause', slideshow).addClass('playing');
    }

    var stopAutoPlaying = function () {
        clearTimeout(slideshowTimeout);
        isAutoPlaying = false;
        jQuery('.slideshowControls .btnPlayPause', slideshow).html('Play');
        jQuery('.slideshowControls .btnPlayPause', slideshow).removeClass('playing');
    }

    var startAutoPlaying = function () {
        slideshowTimeout = setTimeout(nextSlide, options.pause);
        isAutoPlaying = true;
        jQuery('.slideshowControls .btnPlayPause', slideshow).html('Pause');
        jQuery('.slideshowControls .btnPlayPause', slideshow).addClass('playing');
    }

    var btnPlayPause_click = function () {
        if (isAutoPlaying) {
            stopAutoPlaying();
        } else {
            startAutoPlaying();
        }
    }
	
	var btnPrev_click = function() {
		stopAutoPlaying();
		prevSlide();
	}
	
	var btnNext_click = function() {
		stopAutoPlaying();
		nextSlide();
	}
	
	var thumb_click = function() {
		stopAutoPlaying();
		gotoSlide(parseInt($(this).attr('rel')));
	}
	
	var gotoSlide = function(i) {
		if (i == currentSlide) return;
		if (isAnimating) return;
				
		lastSlide = currentSlide;
		currentSlide = i;		
		
		isAnimating = true;
		jQuery('.slide', slideshow).css('left', options.width * 2);
		jQuery('.slide:eq(' + lastSlide + ')', slideshow).css('left', 0);
		jQuery('.inner', slideshow).animate({ left: -options.width }, { duration: options.speed, complete: animate_complete });
		jQuery('.slide:eq(' + currentSlide + ')', slideshow).css('left', options.width);
	}
	
	var nextSlide = function() {
		var targetSlide = currentSlide + 1;
		if (targetSlide >= slides_count) {
			targetSlide = 0;
		}
		gotoSlide(targetSlide);
	}
	
	var prevSlide = function() {
		var targetSlide = currentSlide - 1;
		if (targetSlide < 0) {
			targetSlide = slides_count - 1;
		}
		gotoSlide(targetSlide);
	}
	
	var animate_complete = function() {
	    jQuery('.slide:eq(' + lastSlide + ')', slideshow).css('left', options.width);
		jQuery('.slide:eq(' + currentSlide + ')', slideshow).css('left', 0);
		jQuery('.inner', slideshow).css('left', 0);
		highlightThumb();
		isAnimating = false;
		
		if (isAutoPlaying) {
			slideshowTimeout = setTimeout(nextSlide, options.pause);
		}
	}
	
	var highlightThumb = function() {
		jQuery('.thumb', slideshow).removeClass('active');
		jQuery('.thumb:eq(' + currentSlide + ')', slideshow).addClass('active');
	}
	
	init();

    // public methods
	return {
	    pause: function () {
	        stopAutoPlaying();
	    },
	    play: function () {
	        startAutoPlaying();
	    }
	}
}
