// JavaScript Document

/*

Author:

	Gilles Hooghe, <ghooghe [at] gmail.com>

Class

	SimpleImageViewer

Options:

	autoPlay: slideshow

	autoPlayDuration: speed of the slideshow

	captions: TODO

	duration: duration of the show/hide image effect

	loop: when last image is reached, restart at first image

	transition: transition for the show/hide effect

	wrapperSelector: the selector containing the links/images

	imageViewerSelector: the selector inside which the large image will be displayed

	

TODO: inject optional captions below images

*/ 

var SimpleImageViewer = new Class({

	

	options: {

		autoPlay: true,

		autoPlayDuration: 2500,

		captions: true,

		duration: 500,

		imageViewerSelector: '#image',

		loop: true,

		transition: Fx.Transitions.Sine.easeOut,

		wrapperSelector: '#Anzeiger'

	},



	initialize: function(options) {

		this.setOptions(options);



		this.buildLibrary();

		

		this.setupEvents();

		

		// Start

		window.addEvent('load', function() {

			this.next();

			if (this.options.autoPlay) {

				this.autoPlay();

			}

		}.bind(this));

	},



	/* Parse the links and images contained inside the wrapperSelector element */

	buildLibrary: function() {

		this.library = {};

		this.library.current = -1;

		this.library.links = $$(this.options.wrapperSelector + ' a');

	},

	

	autoPlay: function() {

		this.periodical = (function(){ this.next(); }).periodical(this.options.autoPlayDuration, this);

	},

	

	setupEvents:  function() {

		this.imageViewer = $E(this.options.imageViewerSelector);

		

		$each(this.library.links, function(el, idx) {

			el.addEvent('click', function(evt) {

				new Event(evt).stop();

				

				// Stop running slideshow and restart a while later

				if (this.options.autoPlay) {

					$clear(this.periodical);

					this.autoPlay.delay(this.options.autoPlayDuration, this);

				}

				

				this.library.current = idx;

				

				this.display(el);

			}.bind(this));

		}.bind(this));

		

		document.addEvent('keydown', function(event){

		    event = new Event(event);

			if (event.key == 'right') {

				this.next();

			} else if (event.key == 'left') {

				this.previous();

			}

		}.bind(this));

	},

	

	display: function(clicked) {

		this.setActive(clicked);

				

		if (this.imageHandleCurrent === this.imageHandle0) {

			this.imageHandle1 = new Asset.images([clicked.getProperty('href')], {

				onComplete: function() {

					this.imageHandleCurrent = this.imageHandle1;

								

					// Hide/Show

					if ($defined(this.imageHandle0)) {

						this.hide(this.imageHandle0, this.imageHandleCurrent);

					} else {

						this.show(this.imageHandleCurrent);

					}

				}.bind(this)

			})[0];

		} else {

			this.imageHandle0 = new Asset.images([clicked.getProperty('href')], { 

				onComplete: function() {

					this.imageHandleCurrent = this.imageHandle0;

					

					// Hide/Show

					if ($defined(this.imageHandle1)) {

						this.hide(this.imageHandle1, this.imageHandleCurrent);

					} else {

						this.show(this.imageHandleCurrent);

					}

				}.bind(this)

			})[0];

		}

	},

	

	next: function() {

		if (this.library.current < this.library.links.length - 1) {

			this.library.current = this.library.current + 1;

			this.display(this.library.links[this.library.current]);

			if (this.library.current < this.library.links.length - 1) {

				// Preload next image...

				new Asset.image(this.library.links[this.library.current+1].getProperty('href'));

			}

		} else if (this.options.loop) {

			this.library.current = 0;

			this.display(this.library.links[this.library.current]);

		}

	},

	

	previous: function() {

		if (this.library.current > 0) {

			this.library.current = this.library.current - 1;

			this.display(this.library.links[this.library.current]);

		} else if (this.options.loop) {

			this.library.current = this.library.links.length - 1;

			this.display(this.library.links[this.library.current]);

		}

	},

	

	show: function(el) {

		var fx = new Fx.Style(el, 'opacity', { duration: this.options.duration, transition: this.options.transition }).set(0);

		el.injectInside(this.imageViewer);

		fx.start(1);

		return this;

	},

	

	hide: function(oldEl, newEl) {

		var fx = new Fx.Style(oldEl, 'opacity', { 

			duration: this.options.duration / 2, 

			onComplete: function() {

				oldEl.remove();

				this.show(newEl);

			}.bind(this) 

		}).start(0);

		return this;

	},

	

	setActive: function(elem) {

		$each(this.library.links, function(el, idx) {

			if (elem === el) {

				el.addClass('active');

			} else {

				el.removeClass('active');

			}

		});

	}



});



SimpleImageViewer.implement(new Chain, new Options, new Events);
