Edit in JSFiddle

var Loop = new Class({

    loopCount: 0,
    isStopped: true,
    isLooping: false,
    loopMethod: $empty,

    setLoop: function(fn, delay){
        if(this.isLooping) {
            this.stopLoop();
            var wasLooping = true;
        } else {
            var wasLooping = false;
        }
        this.loopMethod = fn;
        this.loopDelay = delay || 3000;
        if(wasLooping) this.startLoop();
        return this;
    },

    stopLoop: function() {
        this.isStopped = true;
        this.isLooping = false;
        $clear(this.periodical);
        return this;
    },

    startLoop: function(delay) {
        if(this.isStopped){
            var delay = (delay) ? delay : this.loopDelay;
            this.isStopped = false;
            this.isLooping = true;
            this.periodical = this.looper.periodical(delay,this);
        };
        return this;
    },

    resetLoop: function(){
        this.loopCount = 0;
        return this;
    },

    looper: function(){
        this.loopCount++;
        this.loopMethod(this.loopCount);
        return this;
    }

});

var Slideshow = new Class({
    
    Implements: [Options, Events, Loop],
        
        options: {
            /*
            onShow: $empty,
            onShowComplete: $empty,
            onReverse: $empty,
            onPlay: $empty,
            onPause: $empty
            */
            delay: 7000,
            transition: 'crossFade',
            duration: '500',
            autoplay: false
        },
    
    jQuery: 'slideshow',
    
    initialize: function(element, options){
        this.setOptions(options);
        this.setLoop(this.showNext, this.options.delay);
        this.element = jQuery(element);
        this.slides = this.element.children();
        this.current = this.slides[0];
        this.setup();
        if(this.options.autoplay) this.startLoop();
    },
    
    setup: function(){
        this.setupElement();
        this.setupSlides();
        return this;
    },
    
    setupElement: function(){
        var el = this.element;
        if(el.css('position') != 'absolute' && el != document.body) el.css('position','relative');
        return this;
    },
    
    setupSlides: function(){
        this.slides.each(function(index, slide){
            var slide = jQuery(slide);
            this.storeTransition(slide).reset(slide);
            if(index != 0) jQuery(slide).css('display','none');
        }.bind(this));
        return this;
    },
    
    storeTransition: function(slide){
        var classes = slide.attr('class');
        var transitionRegex = /transition:[a-zA-Z]+/;
        var durationRegex = /duration:[0-9]+/;
        var transition = (classes.match(transitionRegex)) ? classes.match(transitionRegex)[0].split(':')[1] : this.options.transition;
        var duration = (classes.match(durationRegex)) ? classes.match(durationRegex)[0].split(':')[1] : this.options.duration;
        slide.data('ssTransition', transition);
        slide.data('ssDuration', duration);
        return this;
    },
    
    getTransition: function(slide){
        return slide.data('ssTransition');
    },
    
    getDuration: function(slide){
        return slide.data('ssDuration');
    },
    
    show: function(slide){
        this.fireEvent('show');
        slide = (typeof slide == 'number') ? jQuery(this.slides[slide]) : jQuery(slide);
        if(slide[0] != jQuery(this.current)[0]){
            var transition = this.getTransition(slide);
            var duration = this.getDuration(slide);
            var previous = jQuery(this.current).css('z-index', 1);
            var next = this.reset(slide);
            this.transitions[transition](previous, next, duration.toInt(), this);
            (function() { 
                previous.css('display','none'); // jquery
                this.fireEvent('showComplete'); // Class.Extras
            }).bind(this).delay(duration); // Function.delay, Function.bind
            this.current = next;
        }
        return this;
    },
    
    reset: function(slide){
        return jQuery(slide).css({ // jquery .css
            'position': 'absolute',
            'z-index': 0,
            'display': 'block',
            'left': 0,
            'top': 0
        }).show(); // jquery .show
    },
    
    nextSlide: function(){
        var next = jQuery(this.current).next(); // jquery .next
        return (next[0]) ? next : this.slides[0];
    },

    previousSlide: function(){
        var previous = jQuery(this.current).prev(); // jquery .prev
        return (previous[0]) ? previous : this.slides.last(); // jquery .last
    },
    
    showNext: function(){
        this.show(this.nextSlide());
        return this;
    },
    
    showPrevious: function(){
        this.show(this.previousSlide());
        return this;
    },
    
    play: function(){
        this.startLoop();
        this.fireEvent('play');
        return this;
    },
    
    pause: function(){
        this.stopLoop();
        this.fireEvent('pause');
        return this;
    },
    
    reverse: function(){
        var fn = (this.loopMethod == this.showNext) ? this.showPrevious : this.showNext;
        this.setLoop(fn, this.options.delay);
        this.fireEvent('reverse');
        return this;
    }
    
});

Slideshow.adders = {
    
    transitions:{},
    
    add: function(className, fn){
        this.transitions[className] = fn;
        this.implement({
            transitions: this.transitions
        });
    },
    
    addAllThese : function(transitions){
        $A(transitions).each(function(transition){
            this.add(transition[0], transition[1]);
        }, this);
    }
    
}

$extend(Slideshow, Slideshow.adders);
Slideshow.implement(Slideshow.adders);

Slideshow.add('fade', function(previous, next, duration, instance){
    previous.fadeOut(duration);
    return this;
});

Slideshow.addAllThese([

    ['none', function(previous, next, duration, instance){
        previous.css('display','none');
        return this;
    }],

    ['crossFade', function(previous, next, duration, instance){
        previous.fadeOut(duration);
        next.fadeIn(duration);
        return this;
    }],
    
    ['fadeThroughBackground', function(previous, next, duration, instance){
        var half = duration/2;
        next.hide();
        previous.fadeOut(half,function(){
            next.fadeIn(half);
        });
    }],

    ['pushLeft', function(previous, next, duration, instance){
        var distance = instance.element.css('width').toInt();
        next.css('left', distance);
        [next, previous].each(function(slide){
            var to = slide.css('left').toInt() - distance;
            slide.animate({'left': to}, duration);
        });
        return this;
    }],
    
    ['pushRight', function(previous, next, duration, instance){
        var distance = instance.element.css('width').toInt();
        next.css('left', -distance);
        [next, previous].each(function(slide){
            var to = slide.css('left').toInt() + distance;
            slide.animate({'left': to}, duration);
        });
        return this;
    }],
    
    ['pushDown', function(previous, next, duration, instance){
        var distance = instance.element.css('height').toInt();
        next.css('top', -distance);
        [next, previous].each(function(slide){
            var to = slide.css('top').toInt() + distance;
            slide.animate({'top': to}, duration);
        });
        return this;
    }],
    
    ['pushUp', function(previous, next, duration, instance){
        var distance = instance.element.css('height').toInt();
        next.css('top', distance);
        [next, previous].each(function(slide){
            var to = slide.css('top').toInt() - distance;
            slide.animate({'top': to}, duration);
        });
        return this;
    }],
    
    ['blindLeft', function(previous, next, duration, instance){
        var distance = instance.element.css('width').toInt();
        next
            .css({
                'left': distance,
                'z-index': 1
            })
            .animate({'left': 0}, duration);
        return this;
    }],

    ['blindRight', function(previous, next, duration, instance){
        var distance = instance.element.css('width').toInt();
        next
            .css({
                'left': -distance,
                'z-index': 1
            })
            .animate({'left': 0}, duration);
        return this;
    }],
    
    ['blindUp', function(previous, next, duration, instance){
        var distance = instance.element.css('height').toInt();
        next
            .css({
                'top': distance,
                'z-index': 1
            })
            .animate({'top': 0}, duration);
        return this;
    }],
    
    ['blindDown', function(previous, next, duration, instance){
        var distance = instance.element.css('height').toInt();
        next
            .css({
                'top': -distance,
                'z-index': 1
            })
            .animate({'top': 0}, duration);
        return this;
    }],
    
    ['blindDownFade', function(p,n,d,i){
        this.blindDown(p,n,d,i).fade(p,n,d,i);
    }],
    
    ['blindUpFade', function(p,n,d,i){
        this.blindUp(p,n,d,i).fade(p,n,d,i);
    }],
    
    ['blindLeftFade', function(p,n,d,i){
        this.blindLeft(p,n,d,i).fade(p,n,d,i);
    }],
    
    ['blindRightFade', function(p,n,d,i){
        this.blindRight(p,n,d,i).fade(p,n,d,i);
    }]
    
]);

var mySlideshow;

$(document).ready(function(){

    // typical jquery instantiation + class event goodness
    $('#ticker').slideshow({
        delay: 2000,
        autoplay: true,
        transition: 'pushUp',
        onShow: function(){ // can even add events here
            this.element.effect('highlight');
        }
    });

    // object oriented instance with a few options
    mySlideshow = new Slideshow('#slides',{
        delay: 3000,
        autoplay: true
    });
    
    // Event demonstration
    mySlideshow.addEvents({
        onShow: function(){ $('#onShow').effect('highlight'); },
        onShowComplete: function(){ $('#onShowComplete').effect('highlight'); },
        onReverse: function(){ $('#onReverse').effect('highlight'); },
        onPlay: function(){ $('#onPlay').effect('highlight'); },
        onPause: function(){ $('#onPause').effect('highlight'); }
    });
    
    // the rest of the demo showing how to control the instance
    var toggled = [$('#show'), $('#showNext'), $('#showPrevious'), $('#showIndex')];
    
    $('#pause').click(function(){
        
        // object oriented, call the method directly
        mySlideshow.pause();
        
        // conventional jquery with some plugin sugar
        $('#ticker').slideshow('pause');
        
        // demo stuff
        toggled.each(function(button){ 
            $(button).attr('disabled', false); 
        });
        $(this).attr('disabled', true);
        $('#play').attr('disabled', false);
        $('#reverse').attr('disabled', true);
    });
    
    $('#play').click(function(){
        
        // object oriented
        mySlideshow.play();
        // conventional jquery
        $('#ticker').slideshow('play');
        
        // demo stuff
        toggled.each(function(button){
            $(button).attr('disabled', true);
        });
        $(this).attr('disabled', true);
        $('#pause').attr('disabled', false);
        $('#reverse').attr('disabled', false);
    });
    
    $('#reverse').click(function(){
        mySlideshow.reverse();
        $('#ticker').slideshow('reverse');
    });
    
    $('#show').click(function(){
        mySlideshow.show(4, 'one', 'two', 'three');
        $('#ticker').slideshow('show');        
    });
    
    $('#showIndex').click(function(){
        mySlideshow.show(0);
        $('#ticker').slideshow('show', 0);
    });
    
    $('#showNext').click(function(){
        mySlideshow.showNext();
        $('#ticker').slideshow('showNext');
    });
    
    $('#showPrevious').click(function(){
        mySlideshow.showPrevious();
        $('#ticker').slideshow('showPrevious');
    });

});
<h1>Slideshow Demo</h1>
<div id="slides">
    <div class="red transition:crossFade duration:1000">1</div>
    <div class="green transition:blindUp">2</div>
    <div class="blue transition:pushLeft duration:1000">3</div>
    <div class="red transition:fadeThroughBackground duration:1000">4</div>
    <div class="green transition:blindLeftFade duration:2000">5</div>
    <div class="blue transition:blindRightFade duration:500">6</div>
</div>
<h2>Events</h2>
<p>
    <span id="onShow">show</span>
    <span id="onShowComplete">showComplete</span>
    <span id="onPlay">play</span>
    <span id="onPause">pause</span>
    <span id="onReverse">reverse</span>
</p>
<h2>Methods</h2>
<p>
    <button id="pause">pause</button>
    <button id="play" disabled="disabled">play</button> 
    <button id="reverse">reverse</button> &nbsp; 
    <button id="showNext" disabled="disabled">showNext</button>
    <button id="showPrevious" disabled="disabled">showPrevious</button>
    <button id="show" disabled="disabled">show slide 5</button>
    <button id="showIndex" disabled="disabled">show slide 1</button> &nbsp;
</p>

<h2>Conventional jQuery Instantiated Instance</h2>
<ol id="ticker">
    <li>Lorem ipsum dolor sit amet, consectetur</li>
    <li>adipisicing elit, sed do eiusmod tempor</li> 
    <li>incididunt ut labore et dolore magna aliqua.</li> 
    <li>Ut enim ad minim veniam, quis nostrud</li>
    <li>exercitation ullamco laboris nisi ut aliquip</li>
    <li>ex ea commodo consequat. Duis aute irure</li>
</ol>

div#slides {
    width: 500px;
    height: 280px;
    overflow: hidden;
    border: solid 2px #000;
}

div#slides div {
    height: 280px;
    width: 500px;
    font-size: 100px;
    line-height: 200px;
    text-align: center;
    color: #fff;
}

ol#ticker {
    height: 1.4em;
    overflow: hidden;
    border: solid 1px #aaa;
    background: #ccc;
}

ul#ticker li {
    padding: 0.2em 0;
}
/* @end */

/* @group global */

body {
    font-family: Helvetica, arial;
    background: #fff;
}

h1 {
    color: #0094d5;
}

h2 {
    color: #43aa38;
}

a {
    color: #0094d5;
}

a:visited, a:hover {
    color: #00577e;
}

.red {
    background: #e40053;
}

.blue {
    background: #0094d5;
}

.green {
    background: #43aa38;
}

h2 {
    margin-top: 20px;
}