/*
 * simple javascript slideshow.
 * last modified 2009-02-20 jej
 * 
 * requires: prototype.js
 *  
 * example: http://www.lib.uchicago.edu/e/crerar/exhibits/photofiles.html
 * 
 * notes:
 * In the html markup, the slideshow will be a <ul> and each slide will
 * be an <li> with an <img> inside. 
 *
 * lots of enhancements are possible here. 
 * Right now this doesn't display a loader graphic or captions. 
 * 
 */

var Slideshow = Class.create({
	/* 
	 * This executes when the dom has loaded, but
	 * before the images have loaded. It hides
	 * the slideshow div until every image has 
 	 * loaded, to avoid displaying all of the slides
	 * before the slideshow appears.
	 */
	initialize: function(div) {
		this.div = $(div);
		this.div.hide();
		Event.observe(window, 'load', this.loader.bind(this));
	},
	loader: function() {
		this.div.show();
		this.ul = this.div.select('ul')[0];
		this.ul.writeAttribute('id', 'slides');
		this.slides = $(this.ul).select('li').collect(function(li) {
			return new Slide(li);
		});
		this.thumbs = $(this.ul).select('li').collect(function(li, i) {
			return new Thumb(i, this);
		}.bind(this));
		this.index = 0;
		this.slides[this.index].show();
		this.resize();
		this.insertThumbnails();
		this.insertVcr();
		this.playlink.removeClassName('youarehere');
		this.stoplink.addClassName('youarehere');
		this.updateThumbs();
	},
	resize: function() {
		var maxh = this.slides.pluck('height').max();
		var maxw = this.slides.pluck('width').max();
		$(this.div).setStyle( {
			width: maxw + 'px'
		});
		$(this.ul).setStyle( {
			height:maxh + 'px',
			width:maxw + 'px'
		});
		$(this.ul).select('li').each(function(li) {li.setStyle({height: maxh+'px', width: maxw+'px'})});
		this.slides.each(function(s) { s.center(); });
	},
	insertVcr: function() {
		this.playlink = $(Builder.node('a', {'href': '#'}, 'play')).observe('click', this.play.bind(this));
		this.stoplink = $(Builder.node('a', {'href': '#'}, 'stop')).observe('click', this.stop.bind(this));
		$(this.ul).insert({
			after: Builder.node('ul',{'id': 'vcr'}, [
				Builder.node('li', {'id': 'play'}, this.playlink),
				Builder.node('li', {'id': 'stop'}, this.stoplink)])
		});
	},
	insertThumbnails: function() {
		$(this.ul).insert({after: Builder.node('ul', {'id': 'thumbs'}, this.thumbs.pluck('li'))});
	},
	next: function() {
		this.slides.each(function(e) { e.hide() });
		if (++this.index >= this.slides.length)
			this.index = 0;
		this.slides[this.index].show();
		this.updateThumbs();
	},
	play: function(e) {
		this.stop(e);
		this.next();
		this.player = new PeriodicalExecuter(this.next.bind(this), 3);
		this.playlink.addClassName('youarehere');
		this.stoplink.removeClassName('youarehere');
		this.updateThumbs();
	},
	stop: function(e) {
		if (this.player)
			this.player.stop();
		this.playlink.removeClassName('youarehere');
		this.stoplink.addClassName('youarehere');
		e.stop();
	},
	clickThumb: function(e) {
		var index = e.findElement('li').id.replace('thumb', '') - 1;
		this.stop(e);
		this.index = index;
		this.slides.each(function(e) { e.hide(); });
		this.slides[this.index].show();
		this.updateThumbs();
	},
	updateThumbs: function() {
		this.thumbs.each(function(t) { t.activate(); });
		this.thumbs[this.index].deactivate();
	}
});

var Slide = Class.create({
	initialize: function(li) {
		this.img = $(li).select('img')[0];
		this.li = $(li);
		this.width = $(this.img).getWidth();
		this.height = $(this.img).getHeight();
		this.hide();
	},
	hide: function() {
		this.li.hide();
	},
	show: function() {
		this.li.show();
	},
	center: function() {
		var top = (this.li.getHeight() - this.height) / 2;
		this.img.setStyle({paddingTop:top+'px'});
	}
});

var Thumb = Class.create({
	initialize: function(i, slideshow) {
		this.slideshow = $(slideshow);
		this.a = $(Builder.node('a', {'href': '#'}, i+1)).observe('click', slideshow.clickThumb.bindAsEventListener(slideshow));
		this.li = Builder.node('li', {'id': 'thumb' + (i+1)}, this.a);
		this.index = i;
	},
	activate: function() {
		this.a.removeClassName('youarehere');
	},
	deactivate: function() {
		this.a.addClassName('youarehere');
	}
});

