/* $Id: slideshow.jquery.js,v 1.1.2.1 2008/01/17 19:26:06 bpontius Exp $

Unobtrusive Accessible jQuery 1.2.1 Slideshow.

Supports:
	Slideshow for images (default) or other nodes via the slideSelector param
	Note: slides fade in on top of old slides.

Usage:
	<div class="slideshow">
		<ul>
			<li><img .../></li>
			...
		</ul>
	</div>

	$('.slideshow').slideshow({wait: 3000, fade: 'normal', slideSelector: 'li'});

Author:
	gburns

TODO:
	Documentation
*/

jQuery.fn.slideshow = function(settings) {
	var options = jQuery.extend({
		wait: 6000,
		fade: 'slow',
		prepend: 'slideshow',
		slideSelector: 'img',
		controls: true
	}, settings || {});

	return this.each(function() {
		var current = null;
		var time_out = null;
		var fading = false;

		$this = $(this)
			.css({position: 'relative'})
			.addClass(options.prepend + 'Main');

		$slides = jQuery(options.slideSelector, this);

		if ( jQuery.browser.safari ) {
			$slides
				.bind('load', function() {
					this.complete = true;
				});
		}

		$slides.css({position: 'absolute', top: 0, left: 0, display: 'none'});
		jQuery($slides[0]).show();

		var next = function() {
			if ( fading ) return;
			var prev = null;
			if ( current === null ) {
				current = 0;
			} else if ( current == $slides.length-1 ) {
				current = 0;
				prev = $slides.length-1;
			} else {
				prev = current;
				current++;
			}

			if ( prev !== null ) {
				var $slide = jQuery($slides[current]).css({zIndex: 1});
				var $imgs;
				var complete = false;
				if ( $slides[current].nodeName == 'IMG' ) {
					if ( $slides[current].complete ) complete = true;
				} else {
					$imgs = jQuery('img', $slide);
					if ( $imgs[0] ) {
						complete = true;
						$imgs.each(function() {
							if ( !this.complete ) {
								complete = false;
								return;
							}
						});
					}
				}

				if ( !complete ) {
					current--;
				} else {
					jQuery($slides[prev]).css({zIndex: 0});
					fading = true;
					$slide.fadeIn(options.fade, function() {
						jQuery($slides[prev]).hide();
						fading = false;
					});
				}
			}
		};

		var previous = function() {
			if ( fading ) return;
			var prev = null;
			if ( current === null ) {
				current = 0;
			} else if ( current == 0 ) {
				current = $slides.length-1;
				prev = 0;
			} else {
				prev = current;
				current--;
			}

			if ( prev !== null ) {
				var $slide = jQuery($slides[current]).css({zIndex: 100});
				var $imgs;
				var complete = false;
				if ( $slides[current].nodeName == 'IMG' ) {
					if ( $slides[current].complete ) complete = true;
				} else {
					$imgs = jQuery('img', $slide);
					if ( $imgs[0] ) {
						complete = true;
						$imgs.each(function() {
							if ( !this.complete ) {
								complete = false;
								return;
							}
						});
					}
				}

				if ( !complete ) {
					current++;
				} else {
					jQuery($slides[prev]).css({zIndex: 0});
					fading = true;
					$slide.fadeIn(options.fade, function() {
						jQuery($slides[prev]).hide();
						fading = false;
					});
				}
			}
		};

		/*var pause = function() {
			clearTimeout(time_out);
			time_out = null;
		};*/
		var pause = function() {  
		if ( click_pause )
			$this.addClass(options.prepend + 'Paused'); 
			$('.slideshowPause').attr("style", "display:none;");
			$('.slideshowPlay').attr("style", "display:block;");
			clearTimeout(time_out);  
			time_out = null;  
		};  
  
		var unpause = function() {  
			$this.removeClass(options.prepend + 'Paused');
			$('.slideshowPause').attr("style", "display:block;");
			$('.slideshowPlay').attr("style", "display:none;");
			time_out = setTimeout(run, options.wait);  
		};

		var showing_all_slides = false;
		var view_all_toggle = function() {
			if ( !showing_all_slides ) {
				click_pause = true;
				pause();
				$slides.css({
					position: 'relative',
					top: null,
					left: null
					})
					.show('fast');
				$this.addClass(options.prepend + 'ViewingAll');
				showing_all_slides = true;
			} else {
				showing_all_slides = false;
				$slides.css({position: 'absolute', top: 0, left: 0, display: 'none'});
				jQuery($slides[current]).css({display: 'block'});
				$this.removeClass(options.prepend + 'ViewingAll');
				click_pause = false;
				unpause();
			}
		};

		$slides
			.bind('mouseover', function() {
				if ( !click_pause ) pause();
			})
			.bind('mouseout', function() {
				if ( !click_pause ) unpause();
			});

		var click_pause = false;

		if ( options.controls ) {
			$previous_link = jQuery('<a href="javascript:;">Previous Image</a>')
				.bind('mouseover', function() {
					jQuery(this).addClass('hover');
				})
				.bind('mouseout', function() {
					jQuery(this).removeClass('hover');
				})
				.bind('mousedown', function() {
					is_clicking = true;
				})
				.bind('mouseup', function() {
					is_clicking = false;
				})
				/*.bind('mouseout', function() {
					jQuery(this).removeClass('hover');
				})*/
				.bind('focus', function() {
					if ( !is_clicking ) jQuery(this).addClass('focus');
				})
				/*.bind('focus', function() {
					jQuery(this).addClass('focus');
				})*/
				.bind('blur', function() {
					jQuery(this).removeClass('focus');
				})
				.bind('click', previous);

			$previous_container = jQuery('<p/>')
				.addClass(options.prepend + 'Previous')
				.append($previous_link);

			$pause_link = jQuery('<a href="javascript:;">Pause</a>')
				.bind('mouseover', function() {
					jQuery(this).addClass('hover');
				})
				.bind('mouseout', function() {
					jQuery(this).removeClass('hover');
				})
				.bind('focus', function() {
					jQuery(this).addClass('focus');
				})
				.bind('blur', function() {
					jQuery(this).removeClass('focus');
				})
				.bind('click', function() {
					if ( time_out ) {
						click_pause = true;
						pause();
					} else {
						click_pause = false;
						unpause();
					}
				});

			$pause_container = jQuery('<p/>')
				.addClass(options.prepend + 'Pause')
				.append($pause_link);

			$play_link = jQuery('<a href="javascript:;">play</a>')
				.bind('mouseover', function() {
					jQuery(this).addClass('hover');
				})
				.bind('mouseout', function() {
					jQuery(this).removeClass('hover');
				})
				.bind('focus', function() {
					jQuery(this).addClass('focus');
				})
				.bind('blur', function() {
					jQuery(this).removeClass('focus');
				})
				.bind('click', function() {
					if ( time_out ) {
						click_pause = true;
						pause();
					} else {
						click_pause = false;
						unpause();
					}
				});

			$play_container = jQuery('<p/>')
				.addClass(options.prepend + 'Play')
				.append($play_link);
				
			$next_link = jQuery('<a href="javascript:;">Next Image</a>')
				.bind('mouseover', function() {
					jQuery(this).addClass('hover');
				})
				.bind('mouseout', function() {
					jQuery(this).removeClass('hover');
				})
				.bind('mousedown', function() {
					is_clicking = true;
				})
				.bind('mouseup', function() {
					is_clicking = false;
				})
				.bind('focus', function() {
					if ( !is_clicking ) jQuery(this).addClass('focus');
				})
				.bind('blur', function() {
					jQuery(this).removeClass('focus');
				})
				.bind('click', next);

			$next_container = jQuery('<p/>')
				.addClass(options.prepend + 'Next')
				.append($next_link);


			$this
				//.append($view_all_container)
				.append($previous_container)
				.append($play_container)
				.append($pause_container)
				.append($next_container);
		}

		var run = function() {
			next();
			time_out = setTimeout(run, options.wait);
		};

		time_out = setTimeout(run, 0);
	});
}