var Slideshow = Class.create();

Slideshow.prototype = {

	initialize: function ( nav_container, image_container, image_container_left, image_container_right, thumb_container, play, pause, prev, next  )
	{
		this.containers = { nav: $(nav_container), image: $(image_container), image_left: $(image_container_left), image_right: $(image_container_right), thumb: $(thumb_container) };
		this.buttons = { play: $(play), pause: $(pause), prev: $(prev), next: $(next) };
		this.options = {};
		this.images = [];
		this.setOptions ( { playDelay: 2000 } );

		this.current_index = -1;
		this.previous_index = -1;
		this.playing = false;
		this.play_timer = new Timer();
	},

	setOptions: function ( options )
	{
		Object.extend ( this.options, options || {} );
	},

	addImage: function ( id, name, url, small_thumb, large_thumb )
	{
		small_thumb = str_replace ( '&amp;', '&', small_thumb );
		large_thumb = str_replace ( '&amp;', '&', large_thumb );
		this.images.push ( {
			image_id: id,
			image_name: name,
			image_url: url,
			image_small_thumb: small_thumb,
			image_large_thumb: large_thumb,
			image_object: null
		} );
	},

	display: function ( )
	{
		// Register buttons
		this.buttons.play.onclick = this.play.bind ( this );
		this.buttons.pause.onclick = this.pause.bind ( this );
		this.buttons.prev.onclick = this.prev.bind ( this );
		this.buttons.next.onclick = this.next.bind ( this, true );
		this.buttons.play.onmousedown = this.buttons.pause.onmousedown = this.buttons.prev.onmousedown = this.buttons.next.onmousedown = function ( ) { return false; }
		this.buttons.pause.style.display = 'none';

		// Show small thumbnails
		for ( var index = 0; index < this.images.length; ++index )
		{
			var image_info = this.images[index];
			var thumb_link = this.containers.thumb.appendChild ( document.createElement ( 'div' ) );
			thumb_link.className = 'thumb_link';
			var thumb_image = thumb_link.appendChild ( new Image ( ) );
			thumb_image.src = image_info.image_small_thumb;
			thumb_image.onclick = function (self, index) { self.pause(); self.showImage ( index ); }.bind ( null, this, index );
			thumb_image.onmouseover = function ( ) { Element.setOpacity ( this, 120 ); }
			thumb_image.onmouseout = function ( ) { Element.fade ( this, 120, 50, 5 ); }
			Element.setOpacity ( thumb_image, 50 );
		}
		var spacer = this.containers.thumb.appendChild ( document.createElement ( 'div' ) );
		spacer.className = 'spacer';

		this.showImage ( 0 );
		this.play();
	},

	showImage: function ( index )
	{
		if ( index < 0 || index >= ( this.images.length ) || this.current_index == index ) return false;
		var image_info = this.images[index];
		this.previous_index = this.current_index;
		this.current_index = index;

		// stop the play timer to let the image load
		this.play_timer.stop();

		if ( image_info.image_object == null )
		{
			// image has not been loaded
			var thumb_image = this.containers.image_left.appendChild ( new Image() );
			thumb_image.onclick = function ( ) { window.open(image_info.image_url); };
			image_info.image_object = thumb_image;
			thumb_image.onload = this.largeThumbLoaded.bind ( this, thumb_image, index );
			Element.setOpacity ( thumb_image, 0 );
			Object.extend ( thumb_image.style, { position: 'absolute', top: '0px', left: '0px', visibility: 'hidden', display: 'none', cursor: 'pointer' } );
			thumb_image.src = image_info.image_large_thumb;
		}
		else
		{
			// image loaded before
			var thumb_image = image_info.image_object;
			this.largeThumbLoaded ( thumb_image, index );
		}
	},

	hideImage: function ( index )
	{
		if ( index < 0 || index >= ( this.images.length ) || this.current_index == index ) return false;
		var image_info = this.images[index];
		var thumb_image = image_info.image_object;

		if ( thumb_image )
		{
			thumb_image.onfadefinish = function ( )
			{
				this.onfadefinish = null;
				Object.extend ( this.style, { position: 'absolute', top: '0px', left: '0px', visibility: 'hidden', display: 'none' } );
			}
			// overlay with the current image
			Object.extend ( thumb_image.style, { position: 'absolute', top: '', left: '' } );

			// fade away
			Element.fade ( thumb_image, 100, 0, 5 );
		}
	},

	largeThumbLoaded: function ( thumb_image, index )
	{
		var image_info = this.images[index];

		// image loaded, continue playing
		if ( this.playing )
			this.play_timer.start ( this.next.bind ( this, false ), this.options.playDelay );

		// resize the image to fit within the container
		var box = Element.getOffset ( this.containers.image );
		var max_height = box.offsetHeight;
		var box = Element.getOffset ( this.containers.image_left );
		var max_width = box.offsetWidth;


		if ( thumb_image.height >= ( max_height - 10 ) )
		{
			var ratio = thumb_image.width / thumb_image.height;
			thumb_image.height = ( max_height - 30 );
			thumb_image.width = thumb_image.height * ratio;
			thumb_image.style.height = ( max_height - 30 );
			thumb_image.style.width = thumb_image.height * ratio;
		}

		if ( thumb_image.width >= ( max_width - 10 ) )
		{
			var ratio = thumb_image.height / thumb_image.width;
			thumb_image.width = ( max_width - 30 );
			thumb_image.height = thumb_image.width * ratio;
		}

		// hide previous image
		if ( this.previous_index >= 0 )
			this.hideImage ( this.previous_index );

		// fade image into view
		Object.extend ( thumb_image.style, { position: 'absolute', top: '', left: '', visibility: 'visible', display: 'inline' } );
		Element.fade ( thumb_image, 0, 120, 5 );

		// display image info on the right side
		this.containers.image_right.innerHTML = '<p><strong>' + image_info.image_name + '</strong><br /><br /><a href="'+image_info.image_url+'">View image</a></p>';
	},

	play: function ( )
	{
		this.buttons.pause.style.display = 'inline';
		this.buttons.play.style.display = 'none';

		if ( this.playing ) return true;
		this.playing = true;
		this.play_timer.start ( this.next.bind ( this, false ), this.options.playDelay );
	},

	pause: function ( )
	{
		this.play_timer.stop();
		this.playing = false;
		this.buttons.play.style.display = 'inline';
		this.buttons.pause.style.display = 'none';
	},

	prev: function ( )
	{
		if ( this.current_index <= 0 ) return false;
		this.pause();
		this.showImage ( this.current_index - 1 );
	},

	next: function ( do_pause )
	{
		if ( this.current_index >= ( this.images.length - 1 ) )
		{
			if ( this.playing ) this.pause();
			return false;
		}
		if ( do_pause ) this.pause();
		this.showImage ( this.current_index + 1 );
	}

};