$( function() {

	var autoAdvanceTimeout = null;

	var $screenOuter = $("#slideshow-screen-outer");
	var $screen = $("#slideshow-screen-inner");
	var $screenUl = $("#slideshow-screen-inner ul");
	var $slidesOuter = $("#slideshow-carousel-slides-outer");
	var $slides = $("#slideshow-carousel-slides-inner");
	var $slidesUl = $("#slideshow-carousel-slides-inner ul");
	
	var isHome = $screenOuter.hasClass("home");
	
	/**
	 * Set up the mouseovers on the large photos
	 */
	 
	// The stylesheet is set up to provide a functional interface for users
	// without JavaScript. We need to override a few of those styles to
	// achieve maximum sexiness. 
	
	$screen.removeClass( "noscript" );
	// See comments in main.css for an explanation of the multiple overflow
	// properties. 
	$slidesOuter.css( "overflow", "hidden" );
	$slidesOuter.css( "overflow-x", "hidden" );
	$slidesOuter.css( "overflow-y", "hidden" );
	//$slidesOuter.css( "overflow", "visible" );
	//$slidesOuter.css( "overflow-x", "visible" );
	//$slidesOuter.css( "overflow-y", "visible" );
	
	//$screenOuter.mouseenter( function( e ) {
	$( "li", $screenOuter ).hover(
		function( e ) {
			if ( !$slides.is(":animated") ) {
				suspendAutoAdvance();
				var $overlay = getOverlay(e);
				$overlay.stop();
				$overlay.animate( { left: "0px" }, 300 );
			}
		},
		function( e ) {
			var $overlay = getOverlay(e);
			$overlay.stop();
			$overlay.animate( { left: "-240px" }, 300 );
			resetAutoAdvance();
		}
	);
	
	function getOverlay( e ) {
		var $parent = $(e.target).parent();
		if ( $parent.is("a") ) {
			$parent = $parent.parent();
		}		
		return $parent.children("div");
	}
	
	/**
	 * Initialize the carousel selector
	 */
	 
	// store the heights of the two scrolling things prior to adding clones
	$screen.data( "originalHeight", $screen.height() );
	$slides.data( "originalHeight", $slides.height() );
	 
	// clone some of the slides to facilitate the wraparound effect
	
	// copy the first four slides and append them to the end of the list...
	var $slideEndClones =
		$( "li:eq(0),li:eq(1),li:eq(2),li:eq(3)", $slidesUl )
			.clone()
			.each( function() {
				var $this = $(this);
				var $link = $this.children("a");
				$link.attr( "href", $link.attr("href") );
				$this.attr( "id", $this.attr("id") + "-endclone" );
				$this.addClass("clone");
			} );
			
	// ...and copy the last slide and prepend it to the beginning
	var $slidePreClone = 
		$( "li:last", $slidesUl )
			.clone()
			.each( function() {
				var $this = $(this);
				var $link = $this.children("a");
				$link.attr( "href", $link.attr("href") );
				$this.attr( "id", $this.attr("id") + "-preclone" );
				$this.addClass("clone preclone");
			} );
	
	// before we actually insert these, we need to store a handle to the
	// first slide, so we can scroll the carousel to it after prepending
	var $firstSlide = $( "li:first", $slidesUl );	
	
	// do the insertion
	$slidesUl.prepend( $slidePreClone );
	$slidesUl.append( $slideEndClones );
	
	// ...and scroll
	$slides.data( "homeTop", 0 - $firstSlide.position().top );
	$slides.css( "top", $slides.data("homeTop") + "px" );
	
	// clone the corresponding projections so they have something to target
	
	var $projectionEndClones =
		$( "li:eq(0),li:eq(1),li:eq(2),li:eq(4)", $screenUl )
			.clone()
			.each( function() {
				var $this = $(this);
				$this.attr( "id", $this.attr("id") + "-endclone" );
				$this.addClass("clone"); 
			} );
			
	var $projectionPreClone = 
		$( "li:last", $screenUl )
			.clone()
			.each( function() {
				var $this = $(this);
				$this.attr( "id", $this.attr("id") + "-preclone" );
				$this.addClass("clone preclone");
			} );

	var $firstProjection = $( "li:first", $screenUl );
	
	// do the insertion
	$screenUl.prepend( $projectionPreClone );
	$screenUl.append( $projectionEndClones );

	// ...and scroll
	$screen.data( "homeTop", 0 - $firstProjection.position().top );
	$screen.css( "top", $screen.data("homeTop") + "px" );

	// register event handlers on the buttons	
	$("#slideshow-carousel-up").click( prev );
	$("#slideshow-carousel-down").click( next );
	
	// start the auto-advance
	resetAutoAdvance();
	
	function next() {
		if ( !$slides.is(":animated") ) {
			var $currentSlide = getCurrentSlide();
			var $newSlide = $currentSlide.next();
			jumpTo( $newSlide );
		}
		return false;
	}
	
	function prev() {
		if ( !$slides.is(":animated") ) {
			var $currentSlide = getCurrentSlide();
			var $newSlide = $currentSlide.prev();
			jumpTo( $newSlide );
		}
	}
	
	function jumpTo( $li ) {
		
		if ( !$slides.is(":animated") ) {
		
			resetAutoAdvance();

			// animate the slides

			var slidesTop = $slides.css("top").removePx();
			//slidesTop = slidesTop.substr( 0, slidesTop.length - 2 );

			var liTop = $li.position().top;
			
			$slides.animate(
				{
					top: "-" + liTop + "px"
				},
				{
					duration: 500,
					complete: function() {
						if ( $li.hasClass("clone") ) {
							var slidesTop = parseInt( $slides.css("top").removePx(), 10 );
							var originalHeight = parseInt( $slides.data("originalHeight") );
							var newTop = 0;
							
							if ( $li.hasClass("preclone") ) {
								var homeTop = parseInt( $slides.data("homeTop") );
								newTop = 0 - ( slidesTop + originalHeight );
							} else {
								newTop = slidesTop + originalHeight;
							}
							
							$slides.css( "top", newTop + "px" );
						}
					}
				}
			);
			
			// animate the screen, if we're on the home page
			
			if ( isHome ) {
			
				//var $projection = $( extractAnchor( $li.children("a").attr("href") ) );
				//alert( "#projection-" + $li.attr("id").substr(6) );
				var $projection = $( "#projection-" + $li.attr("id").substr(6) );
				var projectionTop = $projection.position().top;
				
				$screen.animate(
					{ 
						top: "-" + projectionTop + "px"
					},
					{
						duration: 500,
						complete: function() {
							if ( $li.hasClass("clone") ) {
								var screenTop = parseInt( $screen.css("top").removePx(), 10 );
								var originalHeight = parseInt( $screen.data("originalHeight") );
								var newTop = 0;
								
								if ( $li.hasClass("preclone") ) {
									var homeTop = parseInt( $screen.data("homeTop") );
									newTop = 0 - ( screenTop + originalHeight );
								} else {
									newTop = screenTop + originalHeight;
								}
								
								$screen.css( "top", newTop + "px" );
							}
						}
					}
				);
				
			}
		
		}
		
	}
	
	function getCurrentSlide() {
		// this is ghetto as hell
		var slidesTop = Math.abs( $slides.position().top );
		var $theSlide = null;
		$( "li", $slidesUl ).each( function() {
			if ( $(this).position().top == slidesTop ) {
				$theSlide = $(this);
				return false; // to break the loop
			}
		} );
		return $theSlide;
	}
	
	function resetAutoAdvance() {
		suspendAutoAdvance();
		autoAdvanceTimeout = window.setTimeout( next, 5000 );
	}
	
	function suspendAutoAdvance() {
		window.clearTimeout( autoAdvanceTimeout );
	}
	
	/**
	 * Extracts the #anchor portion of a relative or absolute URI
	 * @param  uri String
	 * @return     String
	 */
	function extractAnchor( uri ) {
		return uri.substr( uri.lastIndexOf("#") );
	}
	
	/**
	 * Intercept clicks on the thumbnails
	 */
	
	// 2009-11-16
	// ...or don't. They want them to simply click through to the target page.
	/*
	$slidesUl.click( function( e ) {
		e.preventDefault();
		jumpTo( $(e.target).parents("li") );		
	} );
	*/

} );

String.prototype.removePx = function() {
	return this.substr( 0, this.length - 2 );
};
