   var ncmsSlideshow = new Class({
        'initialize': function(className, duration, timeout) {
            this.className = className;
            this.duration  = duration;
            this.timeout   = timeout;
            this.imageOut= 1;
            this.imageIn = 0;

            // fetch slideshow and image nodes
            this.galleryNode = $$(this.className);
            this.images = this.galleryNode.getElements("img")[0];
            this.numImages = this.images.length;
            this.imageIndex = [];
            this.index = this.galleryNode.getElements('.index')[0][0];

            // setup images
            $each(this.images, this.setupImage, this);

            this.imageIndex[this.imageIn].set('class', 'active');

            // start periodical calls to change() method
            this.change.periodical(timeout, this);
            // initial animation (as first periodical call will
            // occur after configured time)
            this.change();

         },
         /* fade in animation */
        'fadeIn': function(el) {
            var width = el.offsetWidth;
            var height = el.offsetHeight;

            var pwidth = el.offsetParent.offsetWidth;
            var pheight = el.offsetParent.offsetHeight;

            var resize = 200;

            var nheight = pheight + resize;
            var nwidth = pwidth + resize;

            el.set('opacity', 0.0);
            el.set('height', nheight);
            el.set('width', nwidth);
            el.set('visibility', 'visible');
            var ani = new Fx.Morph(el, {'duration':this.duration * 0.8, 'transition': Fx.Transitions.Linear});
            ani.start({
                'height': [nheight, pheight],
                'width': [nwidth, pwidth],
                'top': [-1 * resize / 2, 0],
                'left': [-1 * resize / 2, 0]
            });
            var ani = new Fx.Tween(el, {'property':'opacity', 'duration':this.duration});
            ani.start(1.0);
            return ani;
        },
        /* fade out animation */
        'fadeOut': function(el) {
            //var ani = el.animate().tween('opacity', 0.0, {'duration': this.duration});
            //ani.start();


            var ani = new Fx.Tween(el, {'property':'opacity', 'duration':this.duration});
            ani.start(0.0);
            return ani;
        },
        /* called for each img dom node in slideshow container */
        'setupImage': function(el, index) {
            var gallery = this;
            var idx = new Element('div', {
                'class': 'item',
                'text': index+1,
                'events': {'click': function() { gallery.imageIn = index; gallery.index.getElements('div').set('class', '');
                gallery.imageIndex[gallery.imageIn].set('class', 'active'); }}
            });
            idx.inject(this.index);

            this.imageIndex[index] = idx;

            var fx = new Fx.Tween(el)
            el.number = index;

            if(index == 0) {
                idx.set('class', 'active');
            } else {
                fx.set('z-index', index * -2);
                fx.set('opacity', 0);
            }

        },
        /* periodically called to change images */
        'change': function() {
            // only animate if image pointers are different
            if(this.imageIn != this.imageOut) {
                this.fadeIn(this.images[this.imageIn]);
                this.fadeOut(this.images[this.imageOut]);
                this.index.getElements('div').set('class', '');
                this.imageIndex[this.imageIn].set('class', 'active');
            }

            // skip pointers to next nodes
            this.imageOut = this.imageIn;
            this.imageIn = (this.imageIn + 1) % this.numImages;

            // properly adjust image layering
            new Fx.Tween(this.images[this.imageIn]).set('z-index', -1);
            new Fx.Tween(this.images[this.imageOut]).set('z-index', -2);
        }

    });