Effect.Transitions.spring=function(pos)
{
	return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
}
var slideshow=Class.create();
slideshow.loadDescription=function(descriptionID)
{
	$('celebrityAbstract').update($('slideshow_description_'+descriptionID).innerHTML);
	new Effect.Highlight('celebrityAbstract');
	return;
}
slideshow.transitionLock=false;
slideshow.transition=function(hook,image,transitionMode,transitionDuration,caption,captionMoveLength)
{
	var theReturn=false;
	if (!transitionMode)transitionMode=slideshow.prototype.defaultConfig.transition.mode;
	if (!transitionDuration)transitionDuration=slideshow.prototype.defaultConfig.transition.duration;
	if (!captionMoveLength)captionMoveLength=slideshow.prototype.defaultConfig.captionMoveLength;
	if (transitionMode=='parallel')
	{
		//Only run if the transitioning is not locked.
		if (!slideshow.transitionLock)
		{
			//Lock the transition.
			slideshow.transitionLock=true;
			//Set a timer to unlock the transition.
			(
				function()
				{
					slideshow.transitionLock=false;
				}
			).delay(Math.round((transitionDuration*1.20)));
			//Make sure the transitioning element is absolutely positioned.
			Element.setStyle(hook,{position:'absolute'});
			//Create the parallel transitioning object if it hasn't already been created.
			if ($(hook.identify()+'B')==undefined)
			{
				hook.insert({after:'<img id="'+hook.identify()+'B" src="'+image+'" class="image" style="position:absolute;display:none;" />'});
			}
			//Define which element is fading out and which element is appearing.
			var fade=false;
			var appear=false;
			if (Element.hasClassName(hook.identify()+'B','current'))
			{
				Element.removeClassName(hook.identify()+'B','current');
				Element.addClassName(hook,'current');
				fade=$(hook.identify()+'B');
				appear=$(hook);
			}
			else
			{
				Element.removeClassName(hook,'current');
				Element.addClassName(hook.identify()+'B','current');
				fade=$(hook);
				appear=$(hook.identify()+'B');
			}
			var captionTransition=false;
			//Check to see if we need to generate a caption boxoverlay.
			if (caption!='' && caption!=undefined)
			{
				captionTransition=true;
				new Effect.Fade
				(
					'captionText',
					{
						duration: 1,
						queue: {scope: 'slideshowCaption', position: 'front',limit: 2},
						afterFinish: function()
						{
							$('captionText').update(caption);
						}
					}
				);
			}
			else if (caption=='' && $('captionText')!=undefined)
			{
				captionTransition=false;
				new Effect.Fade
				(
					'captionText',
					{
						duration: 1,
						queue: {scope: 'slideshowCaption', position: 'front',limit: 2},
						afterFinish: function()
						{
							$('captionText').update(caption);
						}
					}
				);
			}
			//Set the appearing element's src tag to the image that we want to display.
			appear.src=image;
			//Perform the transitioning effects.
			if (captionTransition)
			{
				new Effect.Appear
				(
					'captionText',
					{
						duration: 1,
						queue: {scope: 'slideshowCaption', position: 'end',limit: 2}
					}
				);
			}
			Effect.Fade
			(
				fade,
				{
					to: 0,
					duration: transitionDuration,
					queue: {scope: 'slideshow', position: 'parallel',limit: 2}
				}
			);
			Effect.Appear
			(
				appear,
				{
					from: 0,
					to: 1.0,
					duration: transitionDuration,
					queue: {scope: 'slideshow', position: 'parallel',limit: 2}
				}
			);
			theReturn=true;
		}
	}
	else if (transitionMode=='single')
	{
		Effect.Fade
		(
			hook,
			{
				queue: 'front',
				to: 0,
				duration: transitionDuration,
				afterFinish: function()
				{
					$(hook).src=image;
					Effect.Appear
					(
						hook,
						{
							queue: 'end',
							from: 0,
							to: 1.0,
							duration: transitionDuration
						}
					);
					return;
				}
			}
		);
		theReturn=true;
	}
	else
	{
		throw 'Slideshow Exception: Invalid transition mode. Only "parallel" and "single" are acceptible transition modes.';
	}
	return theReturn;
}
slideshow.autoShow=[];
slideshow.autoPE=false;
slideshow.prototype=
{
	autoTimerStatus: false,
	config:{},
	defaultConfig:
	{
		id: 'slideshow_'+common.randomString(),
		hook: false,
		transition:
		{
			mode:  'parallel',
			duration: 1.5
		},
		captions: true,
		captionMoveLength: 250,
		auto: false,
		autoDuration: 5.0,
		images: []
	},
	resetConfig: function()
	{
		this.config=
		{
			id: 'slideshow_'+common.randomString(),
			hook:  this.defaultConfig.hook,
			transition:
			{
				mode:  this.defaultConfig.transition.mode,
				duration: this.defaultConfig.transition.duration
			},
			captions: this.defaultConfig.captions,
			captionMoveLength: this.defaultConfig.captionMoveLength,
			auto: this.defaultConfig.auto,
			autoDuration:this.defaultConfig.autoDuration,
			images: []
		}
		return;
	},
	setConfig: function(overrideConfig)
	{
		if (overrideConfig)
		{
			if (overrideConfig.id!=undefined && overrideConfig.id!='')this.config.id=overrideConfig.id;
			if (overrideConfig.hook!=undefined && overrideConfig.hook!='')this.config.hook=overrideConfig.hook;
			if (overrideConfig.transition!=undefined)
			{
				if (overrideConfig.transition.mode!=undefined && overrideConfig.transition.mode!='')this.config.transition.mode=overrideConfig.transition.mode;
				if (overrideConfig.transition.duration!=undefined && overrideConfig.transition.duration!='')this.config.transition.duration=overrideConfig.transition.duration;
			}
			if (overrideConfig.captions!=undefined && overrideConfig.captions!='')this.config.captions=overrideConfig.captions;
			if (overrideConfig.captionMoveLength!=undefined && overrideConfig.captionMoveLength!='')this.config.captionMoveLength=overrideConfig.captionMoveLength;
			if (overrideConfig.auto!=undefined && overrideConfig.auto!='')this.config.auto=overrideConfig.auto;
			if (overrideConfig.autoDuration!=undefined && overrideConfig.autoDuration!='')this.config.autoDuration=overrideConfig.autoDuration;
			if (overrideConfig.images!=undefined && overrideConfig.images!='')this.config.images=overrideConfig.images;
		}
		return;
	},
	initialize: function(options)
	{
		if (typeof options!='object')
		{
			throw 'Slideshow Exception: No options given to constructor. You must give at least a JSON object as a data option.';
		}
		else
		{
			if (!options.hook)
			{
				throw 'Slideshow Exception: Nothing to hook onto. Provide a "hook" option.';
			}
			else
			{
				slideshow.autoShow[slideshow.autoShow.length]=this;
				this.resetConfig();
				this.setConfig(options);
				this.build();
				this.attachIDs();
				this.attachEvents();
				
				//Handle start captioning.
				if ($$('.slideshowImage .captionText').length && this.config.auto)
				{//document.viewport.getWidth()
					var captionText=$$('.slideshowImage .captionText')[0];
					new Effect.Parallel
					(
						[
							new Effect.Opacity
							(
								captionText,
								{
									from:		1,
									to:			0,
									duration:	(this.config.autoDuration/2),
									delay:		2.0
								}
							),
							new Effect.Move
							(
								captionText,
								{
									x:			this.config.captionMoveLength,
									y:			0,
									duration:	this.config.autoDuration
								}
							)
						],
						{
							duration:	this.config.autoDuration,
							afterFinish: function()
							{
								Element.setStyle
								(
									captionText,
									{
										left: '0px',
										opacity: 0
									}
								);
								return;
							}
						}
					);
				}
				//Handle auto transitioning.
				if (!slideshow.autoPE)
				{
					slideshow.autoPE=new PeriodicalExecuter
					(
						function(pe)
						{
							slideshow.autoShow.each
							(
								function(thisShow)
								{
									if (thisShow.config.auto)
									{
										if (!thisShow.autoTimerStatus)
										{
											thisShow.autoTimerStatus=true;
											(
												function()
												{
													thisShow.autoTimerStatus=false;
													$(thisShow.config.hook).down('.arrow_next').fire('slideshow:autoNext');
													return;
												}
											).delay(thisShow.config.autoDuration);
										}
									}
									return;
								}
							);
							return;
						},
						0.1
					);
				}
			}
			document.fire('slideshow:loaded');
		}
		return;
	},
	build: function()
	{
		var build='<div id="'+this.config.id+'" class="hook" style="display:none;">';
		var buildEnd='';
		build+='<ul>';
		for (i=0; i<this.config.images.length; i++)
		{
			/*
			if (this.config.captions)
			{
				var fragments=this.config.images[i].split('::',2);
				buildEnd+='<img src="'+fragments[0]+'" alt="" />';
			}
			else
			{
				var fragments=[this.config.images[i]];
				buildEnd+='<img src="'+this.config.images[i]+'" alt="" />';
			}
			if (!i)
			{
				build+='<li class="current">'+fragments[0]+'</li>';
			}
			else
			{
				build+='<li>'+fragments[0]+'</li>';
			}
			*/
			if (!i)
			{
				build+='<li class="current">'+this.config.images[i]+'</li>';
			}
			else
			{
				build+='<li>'+this.config.images[i]+'</li>';
			}
			if (this.config.captions)
			{
				var fragments=this.config.images[i].split('::',2);
				buildEnd+='<img src="'+fragments[0]+'" alt="" />';
			}
			else
			{
				buildEnd+='<img src="'+this.config.images[i]+'" alt="" />';
			}
		}
		build+='</ul><div>'+buildEnd+'</div>';
		build+='</div>';
		$(this.config.hook).insert({top:build});
		$(this.config.id).mode=this.config.transition.mode;
		$(this.config.id).duration=this.config.transition.duration;
		$(this.config.id).captions=this.config.captions;
		$(this.config.id).captionMoveLength=this.config.captionMoveLength;
		return;
	},
	attachIDs: function()
	{
		if ($(this.config.hook).down('.image').id==undefined)
		{
			throw 'Unable to hook. Image class was not found (specify class="image" on the image container).';
		}
		else
		{
			$(this.config.hook).down('.image').id=this.config.id+'_image';
		}
		$(this.config.hook).down('.arrow_previous').id=this.config.id+'_previous';
		$(this.config.hook).down('.arrow_next').id=this.config.id+'_next';
		return;
	},
	attachEvents: function()
	{
		Event.observe
		(
			$(this.config.hook).down('.arrow_previous'),
			'click',
			function(event)
			{
				var id=Event.element(event).id.gsub('_previous','');
				var current=$(id).down('ul li.current');
				var previous=$(id).down('ul li.current').previous();
				if (previous==undefined)
				{
					previous=$(id).down('ul li:last-child');
				}
				Element.removeClassName(current,'current');
				Element.addClassName(previous,'current');
				if ($(id).captions)
				{
					var fragments=previous.innerHTML.split('::',2);
					var image=fragments[0];
					var caption=fragments[1];
				}
				else
				{
					var image=previous.innerHTML;
					var caption='';
				}
				if (!slideshow.transition($(id+'_image'),image,$(id).mode,$(id).duration,caption,$(id).captionMoveLength))
				{
					Element.removeClassName(previous,'current');
					Element.addClassName(current,'current');
				}
				return;
			}
		);
		Event.observe
		(
			$(this.config.hook).down('.arrow_next'),
			'click',
			function(event)
			{
				var id=Event.element(event).id.gsub('_next','');
				var current=$(id).down('ul li.current');
				var next=$(id).down('ul li.current').next();
				if (next==undefined)
				{
					next=$(id).down('ul li:first-child');
				}
				Element.removeClassName(current,'current');
				Element.addClassName(next,'current');
				if ($(id).captions)
				{
					var fragments=next.innerHTML.split('::',2);
					var image=fragments[0];
					var caption=fragments[1];
				}
				else
				{
					var image=next.innerHTML;
					var caption='';
				}
				if (!slideshow.transition($(id+'_image'),image,$(id).mode,$(id).duration,caption,$(id).captionMoveLength))
				{
					Element.removeClassName(next,'current');
					Element.addClassName(current,'current');
				}
				return;
			}
		);
		Event.observe
		(
			$(this.config.hook).down('.arrow_next'),
			'slideshow:autoNext',
			function(event)
			{
				var id=Event.element(event).id.gsub('_next','');
				var current=$(id).down('ul li.current');
				var next=$(id).down('ul li.current').next();
				if (next==undefined)
				{
					next=$(id).down('ul li:first-child');
				}
				Element.removeClassName(current,'current');
				Element.addClassName(next,'current');
				if ($(id).captions)
				{
					var fragments=next.innerHTML.split('::',2);
					var image=fragments[0];
					var caption=fragments[1];
				}
				else
				{
					var image=next.innerHTML;
					var caption='';
				}
				if (!slideshow.transition($(id+'_image'),image,$(id).mode,$(id).duration,caption,$(id).captionMoveLength))
				{
					Element.removeClassName(next,'current');
					Element.addClassName(current,'current');
				}
				return;
			}
		);
		return;
	}
}