/*
	sfSlideshow v1.2, requires MooTools 1.2.
	(c)2008 Andrew Buckman
	http://www.stormyfrog.com/mootools/sfSlideshow/
	
	When crossfading, easeIn is recommended with your transition or linear
	otherwise, easeOut is recommended with your transition
*/
var sfSlideshow = new Class({
	Implements: [Options, Events],
	options: {
		captions: false,
		crossfade: false,
		duration: 300,
		linkNext: false,
		linkPrev: false,
		loop: false,
		scrollOffset: 0,
		scrollToMain: false,
		setActive: true,
		start: 0,
		transition: Fx.Transitions.linear,
		onChange: Class.empty,
		onFaded: Class.empty
	},
	initialize: function(fullsizeDiv, thumbsDiv, options) {
		// assign div wrapping main photo to this.main
		this.main = $(fullsizeDiv);
		this.main.setStyle('overflow', 'hidden');

		// assign first photo inside this.main to this.mainpic, this should be the large photo
		this.mainpic = this.main.getElement('img');

		// setup array of thumbnail links (should be a set of A with IMGs inside)
		switch($type(thumbsDiv)) {
			case 'element':
				this.thumbs = thumbsDiv.getElements('a');
				break;
			case 'string':
				this.thumbs = $$('#' + thumbsDiv + ' a');
				break;
			case 'array':
				this.thumbs = thumbsDiv;
				break;
		}

		// process options passed in
		this.setOptions(options);

		// setup captions
		if (this.options.captions) {
			this.caption = $(this.options.captions);
		}

		// create reusable preloader
		this.preloader = new Element('img');
		this.preloader.addEvent('load', function() {
			this.preloaded = true;
			this.swap('preloaded');
		}.bind(this));

		// setup internal variables
		this.current = this.options.start;
		this.swapped = true;
		this.usingalt = false;

		// tag starting thumbnail as active
		if (this.options.setActive) {
			this.thumbs.each(function(t) {
				t.removeClass('active');
			});
			this.thumbs[this.current].addClass('active');
		}

		// override thumbnail links
		this.thumbs.each(function (t, i) {
			t.addEvent('click', function(e) {
				e = new Event(e);
				e.stop();
				this.change(i);
			}.bind(this));
		}, this);

		// override next link
		if (this.options.linkNext) {
			this.options.linkNext.addEvent('click', function(e) {
				e = new Event(e).stop();
				this.next();
			}.bind(this));
		}

		// override previous link
		if (this.options.linkPrev) {
			this.options.linkPrev.addEvent('click', function(e) {
				e = new Event(e).stop();
				this.previous();
			}.bind(this));
		}

		// setup secondary image for crossfade
		if (this.options.crossfade) {
			this.mainalt = new Element('img');
			this.main.setStyles({
				position: 'relative'
			});
			this.mainalt.setStyles({
				position: 'absolute',
				top: 5,
				left: 5
			});
			this.mainalt.setOpacity(0);
			this.mainalt.injectInside(this.main);
		}
		
		// setup effects
		this.fx = {
			scroller: Class.empty,
			resizer: new Fx.Tween(this.main, { property: 'height', duration: this.options.duration, transition: this.options.transition }),
			fadeoutMain: new Fx.Tween(this.mainpic, {
				property: 'opacity',
				duration: this.options.duration, 
				transition: this.options.transition, 
				onComplete: function() {
					this.faded = true;
					this.fireEvent('onFaded');
					this.swap('faded');
				}.bind(this)
			}),
			fadeoutAlt: new Fx.Tween(this.mainalt, {
				property: 'opacity',
				duration: this.options.duration,
				transition: this.options.transition, 
				onComplete: function() {
					this.faded = true;
					this.fireEvent('onFaded');
					this.swap('faded');
				}.bind(this)
			}),
			fadeinMain: new Fx.Tween(this.mainpic, {
				property: 'opacity',
				duration: this.options.duration,
				transition: this.options.transition,
				onComplete: function() {
					this.swapped = true;
				}.bind(this)
			}),
			fadeinAlt: new Fx.Tween(this.mainalt, {
				property: 'opacity',
				duration: this.options.duration,
				transition: this.options.transition,
				onComplete: function() {
					this.swapped = true;
				}.bind(this)
			})
		};
		if (Fx.Scroll) this.fx.scroller = new Fx.Scroll(window, { offset: { 'x': 0, 'y': this.options.scrollOffset } });
	},
	next: function() {
		// change to next picture
		this.change(this.current+1);
		return this;
	},
	previous: function() {
		// change to previous picture
		this.change(this.current-1);
		return this;
	},
	change: function(to) {
		// change to specified picture (referenced from thumbs array)
		if (!this.swapped) return false;
		if (this.options.loop) {
			// if new image is outside bounds, loop around to opposite end
			if (to >= this.thumbs.length) to = 0;
			if (to < 0) to = this.thumbs.length-1;
		} else {
			// if new image is outside bounds, use applicable extreme
			if (to >= this.thumbs.length) to = this.thumbs.length-1;
			if (to < 0) to = 0;
		}
		if (this.current==to) return false;
		this.current = to;
		this.faded = false;
		this.preloaded = false;
		this.swapped = false;
		// mark new thumb as active
		if (this.options.setActive) {
			this.thumbs.each(function(t) {
				t.removeClass('active');
			});
			this.thumbs[to].addClass('active');
		}
		// scroll to main photo
		if (this.options.scrollToMain) this.fx.scroller.toElement(this.main);
		// fade out old image
		var useme = (this.usingalt) ? this.fx.fadeoutAlt : this.fx.fadeoutMain;
		useme.start(0);
		// preload image
		this.preloader.src = this.thumbs[to].getProperty('href');
		// swap caption
		if (this.caption) this.caption.set('html', this.getCaption(this.thumbs[to]));
		this.fireEvent('onChange', to);
		return this;
	},
	swap: function(why) {
		// swaps new photo in when ready (preloaded / faded out if applicable)
		var useme,usefx;
		if (this.options.crossfade && why=='preloaded') {
			useme = (this.usingalt) ? this.mainpic : this.mainalt;
			usefx = (this.usingalt) ? this.fx.fadeinMain : this.fx.fadeinAlt;
			this.usingalt = !this.usingalt;
		} else if (!this.options.crossfade && this.preloaded && this.faded) {
			useme = this.mainpic;
			usefx = this.fx.fadeinMain;
		} else {
			return false;
		}
		if (this.main.getStyle('height').toInt() != this.preloader.height) {
			if (this.faded) {
				this.fx.resizer.start(this.preloader.height).chain(function() {
					useme.src = this.preloader.src;
					usefx.start(1);
				}.bind(this));
			} else {
				// attach to onFaded event
				this.addEvent('onFaded', this.swapafter.pass([useme, usefx], this));
			}
		} else {
			useme.src = this.preloader.src;
			usefx.start(1);
		}
		return this;
	},
	swapafter: function(useme, usefx) {
		this.fx.resizer.start(this.preloader.height).chain(function() {
			useme.src = this.preloader.src;
			usefx.start(1);
		}.bind(this));
		this.removeEvents('faded');
	},
	getCaption: function(link) {
		// returns the caption for the image inside the specified thumb link
		return $(link).getElement('img').getProperty('alt');
	}
});