var SlideShow = Class.create();
SlideShow.prototype = {
	initialize: function(container, images, options) {
		Object.extend(this.options, options);
		this.container = $(container);
		this.load(images);
	},
	
	// The options for a slide show
	options: {
		delay: 0, //The number of seconds to delay before starting
		path: '', // The path to prepend to each image in the array passed.
		duration: 3, // The time in seconds for each image to be displayed.
		currentIndex: 0, // The current image index.
		step: 1, // The direction and number of images to move each step.
		fullsize: [], // An array of the full-size images
		fullsizePanel: null, //The id of the panel to use for displaying fullsize images.
		captions: [], // The captions to display beneath the images.
		label: null // The id of the place to store captions.
	},
	
	// Loads the images in the images array and calls start
	load: function(images) {
		this.label = $(this.options.captionId);
		this.images = [];
		var starter = this.start.bind(this);
		var delay = this.options.delay * 1000;
		for (var i=0; i<images.length; i++) {
			this.images[i] = new Image();
			// Start when the first image is loaded.
			if (i == 0) {Event.observe(this.images[i], 'load', function() {setTimeout(starter, delay);});}
			Event.observe(this.images[i], 'error', function(e) {alert('Error loading image.');});
			this.images[i].src = this.options.path + images[i];
		}
	},
	
	// Gets the current image
	currentImage: function() {
		return this.images[this.options.currentIndex];
	},
	
	// Gets the current caption
	currentCaption: function() {
		var index = this.options.currentIndex;
		var captions = this.options.captions;
		return (captions.length > 0 && index >= 0 && index < captions.length) ?
			captions[index] :
			'';
	},
	
	// Starts the slide show
	start: function() {
		if (this.interval) {this.stop();}
		if (!this.image) {
			this.nextImage = new Image();
			this.nextImage.id = this.container.id + '_nextImage';
			Element.setStyle(this.nextImage, {position: 'absolute'});
			Element.hide(this.nextImage);

			this.image = new Image();
			this.image.id = this.container.id + '_image';
			this.image.src = this.currentImage().src;

			Element.setStyle(this.container, {
					display: 'block',
					position: 'static',
					width: this.currentImage().width, 
					height: this.currentImage().height
				}
			);
			
			if (this.options.fullsize.length > 0) {
				Element.setStyle(this.nextImage, {cursor: 'hand'});
				Element.setStyle(this.image, {cursor: 'hand'});
			}

			Event.observe(this.image, 'click', this.openFullsize.bind(this));
			Event.observe(this.nextImage, 'click', this.openFullsize.bind(this));
			
			this.container.appendChild(this.nextImage);
			this.container.appendChild(this.image);
			if (this.options.delay) {
				Element.hide(this.image);
				new Effect.Appear(this.image, {duration: this.options.duration / 2});
			}
		}
		this.updateLabel();
		this.interval = window.setInterval(this.scroll.bind(this), this.options.duration * 1000);
	},
	
	// Opens a full size image, if applicable
	openFullsize: function(e) {
		var full = -1;
		var img = Event.element(e);
		for (var i=0; i<this.images.length; i++) {
			if (this.images[i].src == img.src) {
				full = i;
				break;
			}
		}
		if (full >= 0 && full < this.options.fullsize.length) {
			var src = this.options.path + this.options.fullsize[full];
			var name = this.currentCaption();
			var img = new Image();
			img.src = src;

			img.onload = function() {
				var win = window.open('', '_new', 'toolbars=0,menubar=0,width=' + img.width + ',height=' + img.height);
				if (win) {
					win.document.open();
					win.document.write('<html><head><title>' + name + '</title></head><body><img src="' + src + '" /></body></html>');
					Element.setStyle(win.document.body, {margin: '0'});
					win.document.close();
					win.focus();
				} else {
					alert('It seems like you have a pop-up blocker enabled.\n\n Try disabling the blocker for this site or holding the "Ctrl" key while clicking on an image.');
				}
			}
		}		
	},
	
	// Updates the label
	updateLabel: function() {
		if (this.options.label) {
			Element.update(this.options.label, this.currentCaption());
			Element.setStyle(this.options.label, {width: Element.getStyle(this.container, 'width')});
			Element.setOpacity(this.options.label, 1.0);
		}
	},
	
	// Swaps the next image with the current one
	swap: function(effect) {
		this.image.src = this.currentImage().src;
		Element.setOpacity(this.image, 1.0);
		Element.hide(this.nextImage);
//		this.updateLabel();
	},
	
	// Sets the image.
	show: function() {
		// Fade the current image
		if (Element.visible(this.image)) {
			Effect.Fade(this.image, {
					duration: this.options.duration / 2, 
					from: 1.0,
					to: 0.01
				}
			);
			if (this.options.label) {
				Effect.Fade(this.options.label, {
						duration: this.options.duration / 2,
						from: 1.0,
						to: 0.01,
						afterFinish: this.updateLabel.bind(this)
					}
				);
			}
		}
		// Show the next image
		this.nextImage.src = this.currentImage().src;
		Effect.Appear(this.nextImage, {
				duration: this.options.duration / 2, 
				afterFinish: this.swap.bind(this)
			}
		);
	},
	
	// Scrolls to the next image.
	scroll: function() {
		this.increment(this.options.step);
		if (this.currentImage() && this.currentImage().complete) {
			this.show();
		} else {
			this.stop();
			Event.observe(this.image, 'load', this.start.bind(this));
		}
	},
	
	// Stops the slide show
	stop: function() {
		window.clearInterval(this.interval);
	},
	
	// Increments the current index the specified amount
	increment: function(amount) {
		this.options.currentIndex += amount;
		if (this.options.currentIndex >= this.images.length) {
			this.options.currentIndex = 0;
		} else if (this.options.currentIndex < 0) {
			this.options.currentIndex = this.images.length - 1;
		}
	}
}
