var jbSlideshow = function() {
	S = {
		init: function(opts){
			if(initialized) return; // don't initialize twice
			initialized = true;
			
			opts = opts || {};
			this.slideTimer = '';
			this.isFading = false;
			this.isPlaying = false;
			this.fadeTime = 0.7;
			this.slidecounter = 0;
            this.parentdiv = opts.parentdiv;
            this.numImages = $$('#' + this.parentdiv + ' .jb_slidediv').size();
            this.slideRate = opts.slideRate;
            this.beforeAnimateStart = opts.beforeAnimateStart;
            this.afterAnimateFinish = opts.afterAnimateFinish;
			this.callAnimate();
		},
		
		callAnimate: function() {
			clearTimeout(this.slideTimer);
			this.isPlaying = true;
			this.animate(1);
			this.slideTimer = setTimeout(this.callAnimate.bind(this),this.slideRate * 1000);//using prototype bind method because setTimeout's scope is squirrely
		},
		
		animate: function(which) {
			if (this.isFading) { return; }
			this.isFading = true;
			nextslide = this.slidecounter + which;
			currentslide = this.slidecounter;
			if (nextslide < 0) {
				nextslide = this.numImages;
			}
			if (nextslide >= this.numImages) {
				nextslide = 0;
			}
			if (nextslide > this.slidecounter) { //forward
				$(this.parentdiv + nextslide).setStyle({ display: "block" });
				Effect.Fade(this.parentdiv + this.slidecounter, { duration: this.fadeTime,
					beforeStart: this.beforeAnimate.bind(this, this.parentdiv + this.slidecounter),
					afterFinish: this.afterAnimate.bind(this, this.parentdiv + this.slidecounter)
				});
			} else {
				Effect.Appear(this.parentdiv + nextslide, { duration: this.fadeTime,
					beforeStart: this.beforeAnimate.bind(this, this.parentdiv + this.slidecounter),
					afterFinish: this.afterAnimate.bind(this, this.parentdiv + this.slidecounter)
				});
			}
			this.slidecounter = nextslide;
		},
		
		afterAnimate: function(which) {
			$(which).setStyle({ display: "none" });
			this.isFading = false;
			if (this.afterAnimateFinish) {
				eval(this.afterAnimateFinish + '(this)');
			}
		},

		beforeAnimate: function(which) {
			if (this.beforeAnimateStart) {
				eval(this.beforeAnimateStart + '(this)');
			}
		}

	};
	initialized = false;
	return S;
};
