(function () {
	var hidden = function () {
		return document.hidden || document.msHidden || document.webkitHidden;
	}

	// "hydrate" div.gallery with play/pause and nav behaviors
	var process_gallery = function (g) {
		var
			// milliseconds to wait before switch to next slide
			NEXT_SLIDE_TIMEOUT = 5000;

		var 
			// will be resized to the height of currently selected image
			images_container = g.querySelector('.images'),

			// images in this gallery
			images = g.querySelectorAll('.images img'),

			// container for nav buttons
			gallery_nav = g.querySelector('nav'),
			
			// clickable buttons, one per image
			// computed below
			navs = [],

			// index of the currently selected image
			selected_index = 0,

			// play control consists of a label and a checkbox
			// defer computing because nav innerHTML gets clobbered
			play_checkbox,

			// handle to setInterval
			play_interval;

/*
 +--------+--------+--------+
 | image1 | image2 | image3 |
 |        |selected|        |
 +--------+--------+--------+
 */

 		var adjust_height = function (index) {
 			images_container.style.height = images[index].offsetHeight + 'px';
 		}

		// show image at index
		// update nav controls accordingly
		var select_image = function (index) {
			if (selected_index === index) return;

			var slide = function () {
				images[selected_index].classList.remove('transition');
				images[index].classList.remove('transition');

				navs[selected_index].classList.remove('selected');
				
				selected_index = index;
			}

			if (hidden()) return;
			images[selected_index].addEventListener('transitionend', slide, {once: true});

			navs[index].classList.add('selected');

			if (index < selected_index) {
				setTimeout(function () {
					images[index].classList.remove('right');
					images[index].classList.add('left');

					adjust_height(index);

					setTimeout(function () {
						images[index].classList.add('transition');
						images[selected_index].classList.add('transition');
						images[index].classList.remove('left');
						images[index].classList.add('center');
						images[selected_index].classList.add('right');
						images[selected_index].classList.remove('center');
					},1)
				},1)

			} else {
				setTimeout(function () {
					images[index].classList.remove('left');
					images[index].classList.add('right');

					adjust_height(index);

					setTimeout(function () {
						images[index].classList.add('transition');
						images[selected_index].classList.add('transition');
						images[index].classList.remove('right');
						images[index].classList.add('center');
						images[selected_index].classList.add('left');
						images[selected_index].classList.remove('center');
					},1);
				},1);

			}
		}

		// show next image
		var next_image = function () {
			if (hidden()) return;
			if (selected_index >= images.length-1) {
				select_image(0);
			} else {
				select_image(selected_index+1);
			}
		}

		// handler for nav buttons
		// selects an image corresponding to the clicked nav button
		var nav_to_image = function () {
			select_image(Array.from(navs).indexOf(this));
		}

		// play/pause slideshow
		var toggle_play = function () {
			if (play_checkbox.checked===true) {
				clearInterval(play_interval);
			} else {
				play_interval = setInterval(next_image, NEXT_SLIDE_TIMEOUT);
			}
		}

		// build nav bullets
		var navHtml = '';
		for (var i=0; i<images.length; ++i) {
			var image = images[i]
			image.addEventListener('click', next_image)
			navHtml += '<i class="' + (i===0? 'selected' : '') + '" data-target="' + image.id + '"></i>'
		}
		gallery_nav.innerHTML += navHtml;

		// attach nav bullet listeners
		navs = gallery_nav.querySelectorAll('i');
		for (var i=0; i<navs.length; ++i) {
			var nav = navs[i];
			nav.addEventListener('click', nav_to_image)
		}

		// play button
		play_checkbox = g.querySelector('.play input[type=checkbox]');
		play_checkbox.addEventListener('change', toggle_play);

		// resize image container when initial image loads
		if (images[selected_index].complete) {
			adjust_height(selected_index);
		} else {
			images[selected_index].addEventListener('load', function () {
				adjust_height(selected_index);
			});
			images[selected_index].addEventListener('error', function() {
				console.warn('error loading image', arguments, images[selected_index].src, images[selected_index])
			});
		}
	}

	var galleries = document.getElementsByClassName('gallery');

	for (var i=0; i<galleries.length; ++i) {
		var g = galleries[i];
		process_gallery(g);
	}
})();