(function () {

// "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'),

                // show all images
                // computed below
                preview_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,

                play_suspended = false;

/*

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

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

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

/*

  +----------------------------------------+
  | +----------+ +----------+ +----------+ |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | +----------+ +----------+ +----------+ |
  |                                        |
  | +----------+ +----------+ +----------+ |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | +----------+ +----------+ +----------+ |
  |                                        |
  | +----------+ +----------+ +----------+ |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | |          | |          | |          | |
  | +----------+ +----------+ +----------+ |
  |                                        |
  | +----------+ +----------+              |
  | |          | |          |              |
  | |          | |          |              |
  | |          | |          |              |
  | |          | |          |              |
  | |          | |          |              |
  | +----------+ +----------+              |
  +----------------------------------------+
*/

               var show_preview = function () {
                       var thumb_size = (images_container.offsetWidth - 6*10) / 3;
                       for (var i=0; i<images.length; ++i) {
                               var image = images[i];
                               if (image.offsetHeight > image.offsetWidth) {
                                       console.log('showing tall preview', thumb_size, image.offsetWidth, 'x', image.offsetHeight)
                                       image.style.width = thumb_size + 'px';
                               } else {
                                       console.log('showing wide preview', thumb_size, image.offsetWidth, 'x', image.offsetHeight)
                                       image.style.height = thumb_size + 'px';
                               }
                               image.classList.add('thumbnail');
                       }
               }

               // 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 (suspended()) 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 (suspended()) 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);

               // g.querySelector('.preview').addEventListener('click', function () {
               //      show_preview();
               // });

               window.addEventListener('resize', function () {
                       adjust_height(selected_index);
               });

               // 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);
       }

})();