// code to execute when the DOM is ready
$(function() {
	slideshow();
});


// These functions create slideshows that cross-fade images.
// They can be triggered by the presence of a global variable called "sl" that contains a list of houses and photos
//   or they can be triggered by the presence of the actual HTML for the slides.
// JSON is preferred for Our Work so the slides don't all load at once. HTML is used on the homepage

function slideshow() {
	// look for a global variable called "sl" (a JSON object create by PHP that has a list of houses and photos: see /_php/functions.php)
	if (typeof sl != 'undefined') {
		
		// build the table of contents
		// there have to be at least 12 list items to fit the design, but they can be blank if there are fewer houses
		if ($('#slideshow-toc')) {
			var toc = $('#slideshow-toc').get(0);
			var j = sl.houses.length;
			if (j<12) j=12; // create at least 12 items in the TOC, since that's what the design calls for
			for (var i=0; i<j; i++) {
				// create a list item, initially empty
				var li = document.createElement('li');
				$(li).addClass('slideshow-toc-' + (i + 1)); // a class to style individual boxes
				toc.appendChild(li);
				// if there are still houses left, put a link and thumbnail in this list item
				// (otherwise the li is left empty, for design purposes)
				if (sl.houses[i]) {
					var house = sl.houses[i];
					house.toc = toc;
					li.a = document.createElement('a');
					li.appendChild(li.a);
					house.thumbLink = li.a;
					li.a.house = house;
					li.a.href = '#' + house.houseName;
					li.a.img = document.createElement('img');
					li.a.appendChild(li.a.img);
					li.a.img.src = sl.base + '/' + house.houseName + '/' + house.thumbnail;
					
					// initialize link to switch slideshows
					$(li.a).bind('click',function(event) {
						event.preventDefault();
//						var id = this.href.substring(this.href.indexOf('#')+1);
						slideshow_select(this.house);
					});
				}
				else {
					// a class to style empty boxes
					$(li).addClass('slideshow-toc-empty');
				}
			}
			
			// enable scrolling if there are more than 12 houses
			if (j>12) {
				var down = document.createElement('div');
				$(toc).parent().append(down);
				toc.down = down;
				down.toc = toc;
				down.className = 'slideshow-toc-down';
				down.innerHTML = 'More';
				$(down).bind('click',function() {
					var toc = this.toc;
					var scrollRange = $(toc).height() - $(toc).parent().height();
					var top = 0;
					if ($(toc).css('top') != 'auto') {
						top = parseInt($(toc).css('top'));
					}
					var rows = Math.round((j-12)/2);
					var rowHeight = scrollRange/rows;
					if ((scrollRange + top) > 0) {
						if (!$(toc).is(':animated')) {
							$(toc).animate({'top': '-' + (rowHeight - top) + 'px'},500,function() {
								showUpDown(this);
							});
						}
					}
				});
				
				var up = document.createElement('div');
				$(toc).parent().append(up);
				toc.up = up;
				up.toc = toc;
				up.className = 'slideshow-toc-up';
				up.innerHTML = 'More';
				$(up).bind('click',function() {
					var toc = this.toc;
					var scrollRange = $(toc).height() - $(toc).parent().height();
					var top = 0;
					if ($(toc).css('top') != 'auto') {
						top = parseInt($(toc).css('top'));
					}
					var rows = Math.round((j-12)/2);
					var rowHeight = scrollRange/rows;
					if (top < 0) {
						if (!$(toc).is(':animated')) {
							$(toc).animate({'top': (rowHeight + top) + 'px'},500,function() {
								showUpDown(this);
							});
						}
					}
				});
				
				showUpDown(toc);
			}
			
			// start the first slideshow
			slideshow_select(sl.houses[0]);
		}
		
	}
	// if there is no "sl" variable, look for a hard-coded slideshow
	else {
		$('.slideshow').each(function() {
			var slideshow = $(this).get(0);
			slideshow.slides = [];
			$(slideshow).find('.slideshow-slide').each(function() {
				slideshow.slides.push($(this).get(0));
				if (slideshow.slides.length > 1) {
					// fading slide out apparently allows it to briefly render, making the first transition smoother
					$(this).fadeTo(0,0,function() {
						// hiding it is necessary so "Back" control works correctly on first run
						$(this).hide();
					});
				}
			});
			slideshow.currentSlideShow = setInterval( function() { slideshow_slideChange(slideshow); }, 5000);
		});
	}
}

// shows or hides 'more' buttons at beginning and end of TOC scroll depending on whether there are actually more items
function showUpDown(toc) {
	var top = $(toc).css('top');
	var scrollRange = $(toc).parent().height() - $(toc).height();
	
	if (top == 'auto' || parseInt(top) == 0) {
		$(toc.up).fadeOut('medium');
	}
	else {
		$(toc.up).fadeIn('medium');
	}
	
	if (parseInt(top) == scrollRange) {
		$(toc.down).fadeOut('medium');
	}
	else {
		$(toc.down).fadeIn('medium');
	}
}

// highlight a houses's thumbnail and starts its slideshow
function slideshow_select(house) {
	$(sl.houses).each(function() {
		if (this != house) {
			// if this isn't the current house, remove highlight from thumbnail
			$(this.thumbLink).removeClass('toc_current');
			// and stop/hide the slideshow
			if (this.slideshow) {
				slideshow_stop(this.slideshow);
			}
		}
		else {
			// add highlight to current thumbnail
			$(house.thumbLink).addClass('toc_current');
			
			// if no slideshow exists yet, create it
			if (!house.slideshow) {
				house.slideshow = document.createElement('div');
				var slideshow = house.slideshow;
				slideshow.house = house;
				$('#slideshows').append(house.slideshow);
				// hide by default so it can be faded in later
				slideshow.className = 'slideshow';
				slideshow.id = house.houseName;
				slideshow.slides = [];
				// create the slides
				for (var i in house.photos) {
					var slide = document.createElement('div');
					slideshow.appendChild(slide);
					slideshow.slides.push(slide);
					slide.className = 'slideshow-slide';
					slide.style.zIndex = (house.photos.length - i) + 1000;
					var photo = house.photos[i];
					// create an image element for this slide's photo
					// the image element is hidden by the stylsheet, but it's good for usability
					slide.img = document.createElement('img');
					slide.appendChild(slide.img);
					slide.img.src = sl.base + '/' + house.houseName + '/' + photo;
					// setting image as background helps in transitions
					slide.style.backgroundImage = 'url(' + slide.img.src + ')';
					// hide very slide but the first one
					if (i != 0) {
						// fading it out apparently allows it to briefly render, making the first transition smoother
						$(slide).fadeTo(0,0,function() {
							// hiding it is necessary so "Back" control works correctly on first run
							$(slide).hide();
						});
					}
				}
				// create HTML for forward/back/play/pause controls
				var controls = document.createElement('div');
				$(slideshow).append(controls);
				controls.className = 'slideshow-controls';
				var ul = document.createElement('ul');
				controls.appendChild(ul);
				var controlNames = {
					'back':'Back'
					,'play':'Play'
					,'pause':'Pause'
					,'forward':'Forward'
				};
				for (controlName in controlNames) {
					var li = document.createElement('li');
					ul.appendChild(li);
					var a = document.createElement('a');
					li.appendChild(a);
					a.className = 'slideshow-controls-' + controlName;
					a.href = '#' + controlName;
					a.innerHTML = controlNames[controlName];
					a.slideshow = $(slideshow)[0];
					$(a).bind('click', function(event) {
						event.preventDefault();
						this.blur();
					});
					// initialize behavior of buttons on click
					switch(controlName) {
						case 'back':
						$(a).bind('click', function(event) {
							slideshow_slideChange(this.slideshow,-1,500);
							clearTimeout(this.slideshow.house.toc.currentSlideShow);
						});
						break;
						
						case 'play':
						$(a).bind('click', function(event) {
							clearTimeout(this.slideshow.house.toc.currentSlideShow);
							var slideshow = this.slideshow;
							slideshow_slideChange(this.slideshow,1,1000);
							slideshow.house.toc.currentSlideShow = setInterval( function() { slideshow_slideChange(slideshow); }, 5000);
						});
						break;
						
						case 'pause':
						$(a).bind('click', function(event) {
							clearTimeout(this.slideshow.house.toc.currentSlideShow);
						});
						break;
						
						case 'forward':
						$(a).bind('click', function(event) {
							slideshow_slideChange(this.slideshow,1,500);
							clearTimeout(this.slideshow.house.toc.currentSlideShow);
						});
						break;
					}
				}
			}
			// show/start this houses slideshow
			slideshow_start(house.slideshow);
		}
	});
}

// fades in the selected slideshow and starts the cross-fading animation every five seconds
function slideshow_start(slideshow) {
	$(slideshow).fadeIn('fast');
	if (slideshow.house.toc.currentSlideShow) {
		clearTimeout(slideshow.house.toc.currentSlideShow);
	}
	slideshow.house.toc.currentSlideShow = setInterval( function() { slideshow_slideChange(slideshow); }, 5000);
}

// fades out the old slideshow
function slideshow_stop(slideshow) {
	$(slideshow).fadeOut('fast');
}

// changes slide forward or backward (forward one slide by default) for indicated slideshow
//  - direction is a positive or negative integer (except zero) that is less than the number of slides
//  - positive integer skips forward in slide order, negative skips backward
// speed is how long the fade takes, in milliseconds (1000 / 1 second by default)
function slideshow_slideChange(slideshow,direction,speed) {
	// set direction if none has been specified
	if (!direction) {
		var direction = 1;
	}
	// set fade speed if none has been specified
	if (!speed) {
		var speed = 1000;
	}
	// find out which slide, if any, is currently visible
	var cSi = 0; // will represent current slide's index in slideshow.slides array
	var sL = slideshow.slides.length;
	for (var i=0;i<sL;i++) {
		if ($(slideshow.slides[i]).is(':visible')) {
			cSi = i;
			break;
		}
	}
	// hide current slide
	$(slideshow.slides[cSi]).animate({opacity: 0},speed,function(){$(slideshow.slides[cSi]).css({display: 'none'})});
	
	// determine index of next slide
	var nSi = cSi + direction;
	if (nSi < 0) { // if the current slide is the first one and the direction is backward...
		nSi = sL -1; // ...loop around to the last slide in the list
	}
	else if (nSi >= sL) { // if the current slide is the last one and the direction is forward...
		nSi = 0; // ...loop around to the beginning slide in the list
	}
	// show next slide
	$(slideshow.slides[nSi]).css({display: 'block'}).animate({opacity: 1},speed);
}