function Slideshow2(containerElement) {
	this.containerElement = $(containerElement)
	if (!this.containerElement.getElementsByTagName) {
		console.error('slideshow container should be an element', this.containerElement);
		debugger;
		throw new TypeError('slideshow container should be an element');
	}
	this.imageElements = this.containerElement.getElementsByTagName('img');
	this.imageCount = this.imageElements.length;
	
	// this.containerElement.style.width = this.imageElements[0].offsetWidth + 'px';
	// this.containerElement.style.height = this.imageElements[0].offsetHeight + 'px';
}
Object.extend(Slideshow2.prototype, {
	log: function () {
	},
	
	holdDuration: 0.3,
	fadeDuration: 0.5,
	crossFade: function (upperImage, lowerImage, options) {
		upperImage = $(upperImage);
		lowerImage = $(lowerImage);
		options = options || {};
		
		// assuming upperImage at full opacity
		upperImage.style.zIndex = 1002;
		upperImage.style.position = 'absolute';
		upperImage.style.left = '0';
		
		lowerImage.style.zIndex = 1001;
		
		// this line causes images to be in the wrong order on the NHH homepage and its map to disappear
		// lowerImage.style.position = 'static';
		
		// slideshow.containerElement.style.height = lowerImage.offsetHeight + 'px';
		
		lowerImage.show();
		Element.setOpacity(lowerImage, 1);
		
		this.log('crossFade', upperImage, lowerImage, options);
		
		options.to = options.to || 0.001; // don't allow full transparency, as Fade hides the element entirely, causing things to jump
		new Effect.Fade(upperImage, options);
		// new Effect.Appear(lowerImage);
	},

	playing: false,

	topImageIndex: 0,
	afterFadeComplete: null,

	hold: function () {
		if (this.playing) {
			setTimeout(afterHold.bind(this), this.holdDuration * 1000);
		}
		
		function afterHold() {
			if (this.playing) this.fadeToNext();
		}
	},

	wrap: function (value, size) {
		// value is forced into 0 ... size - 1, wrapping if necessary
		
		// JS % is some sort of remainder, not modulus, so ensure value is non-negative
		while (value < 0) value += size;
		
		return value % size;
	},

	fadeToNext: function () {
		this.fadeTo(this.topImageIndex + 1);
	},

	fadeToPrevious: function () {
		this.fadeTo(this.topImageIndex - 1);
	},

	fadeTo: function (nextImageIndex) {
		if (this.duringFade) return;
		
		nextImageIndex = this.wrap(nextImageIndex, this.imageCount);
	
		var topImage = this.imageElements[this.topImageIndex];
		var nextImage = this.imageElements[nextImageIndex];
	
		this.log('fadeToNext', topImage, nextImage, nextImageIndex);
		
		var slideshow = this;
	
		this.duringFade = true;
		
		this.crossFade(topImage, nextImage, {duration: this.fadeDuration, afterFinish: fadeFinished});
		
		function fadeFinished() {
			Element.hide(topImage)
			slideshow.duringFade = false;
			slideshow.topImageIndex = nextImageIndex;
			if (slideshow.afterFadeComplete) slideshow.afterFadeComplete();
			slideshow.hold();
		}
	},
	
	start: function () {
		if (!this.playing) {
			this.playing = true;
			this.hold();
		}
	},

	play: function () {
		if (!this.playing) {
			this.playing = true;
			if (!this.duringFade) this.fadeToNext();
		}
		if (this.onPlay) this.onPlay();
	},

	stop: function () {
		this.playing = false;
		if (this.onStop) this.onStop();
	},
	
	pause: function () {
		this.stop();
	},
	
	stepToNext: function () {
		this.stop();
		this.fadeToNext();
	},
	
	stepToPrevious: function () {
		this.stop();
		this.fadeToPrevious();
	}
});

