var Slide = new Class({
	image: null,
	
	initialize: function(slideshow, index, nextSlide, src) {
		this.slideshow = slideshow;
		this.index = index;
		this.nextSlide = nextSlide;
		this.src = src;
	},
	
	isLoaded: function() { return (this.loaded == true); },
	isSuccessful: function() { return (this.successful == true); },
	
	load: function(loadNext) {
		this.loadNext = loadNext;
		if (!this.isLoaded()) {
			if (!this.image)
				this.image = new Element('img', { src: this.src, alt: 'slide' }).addEvent('error', this.onError.bindWithEvent(this)).addEvent('load', this.onLoad.bindWithEvent(this));
		}
		else
			this.loadNextSlide();
		return this;
	},
	
	loadNextSlide: function() {
		if (this.loadNext != false && this.nextSlide) this.nextSlide.load();
	},
	
	setCallback: function(callback) { this.callback = callback; return this; },
	notify: function() {
		try { if (this.callback) this.callback(this.slideshow, this); }
		catch (ignore) {}
	},
	
	onError: function() { this.loaded = true; this.successful = false; this.notify(); this.loadNextSlide(); },
	onLoad: function() { this.loaded = true; this.successful = true; this.notify(); this.loadNextSlide(); }
});

var Slideshow = {
	initialize: function() {
		$$('div.slideshow').each(Slideshow.setup);
	},
	
	setup: function(slideshow) {
		var images = slideshow.get('text').trim().split(',');
		slideshow.set('text', '');
		if (images.length < 2) return;
		
		var dir = images.shift();
		var numSlides = images.length;
		var size = slideshow.getSize();
		
		var slides = new Array(numSlides);
		var circles = new Array(numSlides);
		var nextSlide = null;
		for (var i = numSlides - 1; i >= 0; i--) {
			nextSlide = slides[i] = new Slide(slideshow, i, nextSlide, dir + images[i]);
		}
		
		slideshow.store('slides', slides);
		slideshow.store('circles', circles);
		slideshow.store('loaded', false);
		slideshow.store('curSlide', null);
		
		var navbarWidth = 104 + numSlides * 20;
		var gotoSlide = function(index) {
			return function() {
				Slideshow.gotoSlide(slideshow, index);
			};
		};
		
		var navbar = new Element('div', { 'class': 'navbar', styles: { display: (numSlides > 1 ? 'block' : 'none'), width: navbarWidth, left: Math.round((slideshow.getSize().x - navbarWidth) / 2) } });
		var left = new Element('div', { 'class': 'left' }).addEvent('click', function() { Slideshow.prevSlide(slideshow); }).inject(navbar);
		for (i = 0; i < numSlides; i++) {
			circles[i] = new Element('div', { 'class': 'circle' }).addEvent('click', gotoSlide(i)).inject(navbar);
		}
		var right = new Element('div', { 'class': 'right' }).addEvent('click', function() { Slideshow.nextSlide(slideshow); }).inject(navbar);
		navbar.inject(slideshow);
		
		var loader = new Element('div', { 'class': 'loadingsymbol', styles: { visibility: 'hidden', opacity: 0 } }).set('tween', { duration: 100 });
		loader.inject(slideshow).setStyle('top', Math.round((size.y - loader.getSize().y) / 2)).setStyle('left', Math.round((size.x - loader.getSize().x) / 2));
		
		slides[0].setCallback(Slideshow.slideLoaded).load(false);
		Slideshow.showLoader(slideshow);
		
		if (numSlides > 1) {
			var hideTimeout = null;
			var hidden = false;
			var stopHideTimeout = function() {
				if (hideTimeout != null) {
					clearTimeout(hideTimeout);
					hideTimeout = null;
				}
			};
			var hideNavBar = function() { (!Browser.Engine.trident ? navbar.fade(0) : navbar.hide()); hidden = true; stopHideTimeout(); };
			var startHideTimeout = function() {
				stopHideTimeout();
				hideTimeout = setTimeout(hideNavBar, 4000);
			};
			var showNavBar = function() { (!Browser.Engine.trident ? navbar.fade(1) : navbar.show()); hidden = false; startHideTimeout(); };
			
			slideshow.addEvent('mouseenter', showNavBar).addEvent('mousemove', function() { if (hidden) showNavBar(); else startHideTimeout(); }).addEvent('mouseleave', hideNavBar);
			startHideTimeout();
		}
	},
	
	gotoSlide: function(slideshow, index) {
		var slides = slideshow.retrieve('slides');
		if (index < 0) return;
		if (index >= slides.length) index = 0;
		var curSlide = slideshow.retrieve('curSlide');
		if (!slideshow.retrieve('loaded')) Slideshow.loadSlides(slideshow, slides);
		if (!curSlide || curSlide.index == index) return;
		var newSlide = slides[index];
		if (!newSlide.isLoaded()) {
			newSlide.setCallback(Slideshow.slideLoaded);
			Slideshow.showLoader(slideshow);
		}
		else
			Slideshow.slideLoaded(slideshow, newSlide);
	},
	
	prevSlide: function(slideshow) {
		var curSlide = slideshow.retrieve('curSlide');
		if (curSlide)
			Slideshow.gotoSlide(slideshow, curSlide.index - 1);
	},
	
	nextSlide: function(slideshow) {
		var curSlide = slideshow.retrieve('curSlide');
		if (curSlide)
			Slideshow.gotoSlide(slideshow, curSlide.index + 1);
	},
	
	loadSlides: function(slideshow, slides) {
		slides[0].load();
		slideshow.store('loaded', true);
	},
	
	slideLoaded: function(slideshow, slide) {
		Slideshow.hideLoader(slideshow);
		
		var circles = slideshow.retrieve('circles');
		var curSlide = slideshow.retrieve('curSlide');
		var onComplete = function() { this.removeEvents('complete'); if (curSlide.isSuccessful()) curSlide.image.dispose(); };
		
		if (curSlide)
			circles[curSlide.index].removeClass('selected');
		if (slide.isSuccessful()) {
			circles[slide.index].addClass('selected');
			var fx = slide.image.inject(slideshow).setStyle('opacity', 0).fade(1).get('tween');
			if (curSlide && curSlide.isSuccessful())
				fx.addEvent('complete', onComplete);
		}
		else if (curSlide && curSlide.isSuccessful())
			curSlide.image.fade(0).addEvent('complete', onComplete);
		
		if (slide.index > 0)
			slideshow.getElement('div.left').removeClass('disabled');
		else
			slideshow.getElement('div.left').addClass('disabled');
		if (slide.index < slideshow.retrieve('slides').length - 1)
			slideshow.getElement('div.right').removeClass('return');
		else
			slideshow.getElement('div.right').addClass('return');
		
		slideshow.store('curSlide', slide);
	},
	
	showLoader: function(slideshow) {
		var loader = slideshow.getElement('div.loadingsymbol');
		if (!loader) return;
		loader.fade(1);
		var interval = slideshow.retrieve('loaderInterval', null);
		if (interval == null) {
			var pos = 0;
			slideshow.store('loaderInterval', setInterval(function() { loader.setStyle('backgroundPosition', '0px ' + pos + 'px'); pos -= 20; if (pos <= -240) pos = 0; }, 50));
		}
	},
	
	hideLoader: function(slideshow) {
		var loader = slideshow.getElement('div.loadingsymbol');
		if (!loader) return;
		loader.fade(0);
		var interval = slideshow.retrieve('loaderInterval', null);
		if (interval != null) {
			clearInterval(interval);
			slideshow.store('loaderInterval', null);
		}
	}
};

window.addEvent('domready', Slideshow.initialize);