function showImageNum(imagenum) {
// displays the specified image number from the gallery index
  if ((imagenum >= 0) && (imagenum < galleryimages.length)) {
    loadImage(galleryimages.eq(imagenum));
    scrollToPanel(galleryimages.eq(imagenum).parents('.panel'));
  }
}

function showNextImage() {
// displays the next image from the gallery index
// if the last image is currently displayed, do nothing
  var nextimage = parseInt($('#gallery-currentimage IMG').attr('rel')) + 1;
  showImageNum(nextimage);
}

function showPrevImage() {
// displays the previous image from the gallery index
// if the first image is currently displayed, do nothing
  var previmage = parseInt($('#gallery-currentimage IMG').attr('rel')) - 1;
  showImageNum(previmage);
}

function handleGalleryIndexClick(event) {
// Event handler for gallery index images
     // check if the click was on a gallery index image
     if ($(event.target).parent().andSelf().filter("A[rel='show']").length) {
          // stop event propogation
          event.preventDefault();
          
          // get the actual image link
          var img = $(event.target).parents('LI').find("A[rel='show']").eq(0);
          
          // call the function to display the image
          loadImage(img);
      }          
}

function loadImage(img) {
// Hides the current image (replacing it with a "loading" message),
// tells the image loader to start loading up the specified image,
// and updates the gallery index to highlight the selected image and dehighlight previous image.

          // the main viewing pane
          var displaybox = $("#gallery-currentimage IMG");
          
          // look up the (previous) image currently being displayed and
          // indicate in the gallery index that it's no longer the selected image
          galleryimages.eq(displaybox.attr('rel')).removeClass('selected');

          // update the new image index to indicate that it is selected
          img.addClass('selected');
          
          // show the loading image (by hiding the viewing pane
          displaybox.addClass('loading');
          
          // mark which gallery index spot is being loaded up
          displaybox.attr('rel',galleryimages.index(img));
          
          // start loading the new image in the off-screen image loading vessel
          galleryimageloader.attr({
                 'src':img.attr('href'),
                 'title':img.attr('title') });
                 
          // update the title under the viewing pane to say "loading"
          document.getElementById("gallery-currenttitle").innerHTML = 'loading';
          // jquery version of this code removed because it was causing crash in safari 1.9
          //       $("#gallery-currenttitle").html('loading');
}

function displayLoadedImage() {
// Event handler for a newly loaded image.
// Displays the new image in the gallery.
          var displaybox = $("#gallery-currentimage IMG");
          displaybox.attr({
                 'src':galleryimageloader.attr('src'),
                 'title':galleryimageloader.attr('title') });
          displaybox.removeClass('loading');
         // removed -- causing crash in safari
         //           $("#gallery-currenttitle").html(galleryimageloader.attr('title'));
         // for safari:
         document.getElementById("gallery-currenttitle").innerHTML = galleryimageloader.attr('title');
}

function updateProgressBar(status, total) {
// While the gallery is initializing, progress is displayed on a progress bar.
// Update that element based on the ratio of status to total.
   var progress = 100 * status / total;
   var progressbar = $('#gallery-progressbar');
   
   progressbar.children().css('width',progress + '%');
   if (progress == 100) { progressbar.removeClass('loading'); }
}


function initializeGallery() {
// Do the javascript processing on the gallery to make it look nice and
// give it it's functionality.
//
// This includes creating click events for each gallery index item,
// displaying the image titles in the index,
// organizing the items on gallery index panels,
// and then calling functions to arrange those panels.
// Also includes adding click events to the 'next' and 'previous' arrows.

    // create global object to point to gallery thumbnail images
    galleryimages = $("A[rel='show']");
    
    // initialize the display box for images
    $('#gallery-currentimage').append('<img />');

    // create placeholder for loading new images offscreen
    var img = '<img />';
    img = $(img);
    // configure placeholder image so that, once the image loads,
    // it gets shown in the display box
    galleryimageloader = img.load(displayLoadedImage);
    // add functionality to prev and next buttons
    $('#gallery').find('#previmage').click(
       function(event) { this.blur(); showPrevImage(); event.preventDefault(); });
    $('#gallery').find('#nextimage').click(
       function(event) { this.blur(); showNextImage(); event.preventDefault(); });
    
    // add keyboard left/right navigation
    // doesn't appear to work in Safari or IE, but doesn't break either.
    $(document).keypress(function(e) {
        var key_code = e.keyCode;
	    switch (key_code){
	        case 37: // arrow left
	            showPrevImage();
	            e.preventDefault();
	            break;
		    case 39: // arrow right
                showNextImage();
                e.preventDefault();
                break;
        }
    });


    //////////
    // Function to run through each gallery index item adding click events and image titles,
    // and figure out where to break the gallery into panels.
    // 
    // In order to keep from locking the browser, and to display a progress bar,
    // an internal function will repeatedly call itself using setTimeout
    function processImages() {
      // initialize local variables
      var gi = galleryimages;                               // local copy to speed up access
      var i = gi.length-1;                                  // image counter
      var firstpanel = $('#gallery-index').find('.panel');  // the first gallery index panel
      var lastbreak = gi.length;                            // the first image on the next panel
      
      // internal function
      (function () {
        // initialize timer so we know when to take breaks
        var start = new Date().getTime();
        
        // loop through images from last to first
        // we start at the end so we don't have to move so many images at once
        // as we rearrange the DOM
        for (;i >= 0; i--) {
          var implain = gi[i]
          var im = $(implain);
              
          // update progress bar
          updateProgressBar(gi.length-i, gi.length);
                    
          // fix the width of each gallery index item, then add the image title below
          im.parent('li').css('width',im.width())

          // JQuery DOM manipulation in Safari was bunk, so do this with basic JS
          implain.appendChild(document.createElement('br'));
          implain.appendChild(document.createTextNode(im.attr('title')));
          // this was removed -- im.after("<br />" + im.attr('title'));
      
          // For old versions of safari, add dummy onclick handler
          // to prevent the links from linking.
          if (jQuery.browser.safari) {
             im.attr('onClick','return false');
          }

          if ((i > 0) && (im.offset().left < gi.eq(i-1).offset().left)) {
            firstpanel.after('<div class="panel"><ul></ul></div>');
            firstpanel.next().children(':first').append(gi.parent().slice(i,lastbreak));
            lastbreak = i;
          }
      
          if (new Date().getTime() - start > 40) {
            i--;
            setTimeout(arguments.callee, 0);
            return true;
          }          
        }
        
        // add click functionality to gallery images (delegated to the document)
        $(document).click(handleGalleryIndexClick);
        
        // rearrange the gallery index panels and add navigation
        arrangePanels();
        
        $('#gallery').removeClass('notloaded'); // show the gallery
        loadImage(galleryimages.eq(0));  // select the first image
  
     })();}
     processImages();
     
};

function scrollToPanel(panel) {
// Move the gallery panels so that the indicated panel is visible
  var belt = $('.belt');
  belt.animate(
        {top: belt.offset().top-panel.offset().top + 'px'},
        'normal')
}

function handlePanelNavigationClick(event) {
// Handle click event on panel navigationlinks
// Move to the panel specified in the 'rel' attribute of the link
  var newpanelnum = $(this).attr('href').slice(-1) - 1;
  var newpanel = panels.eq(newpanelnum);
  scrollToPanel(newpanel);
  event.preventDefault();
}

function arrangePanels() {
/// Add navigation to the gallery panels

  // get gallery index panels (and initialize global variable
  panels = $('#gallery-index').find('.panel');
  var numpanels = panels.length;
  
  // set gallery index to appropriate height
  $('#gallery-index').css('height',panels.height());

  // add navigation to each gallery index panel
  $(panels).each( function(n) {

    //build the navigation
    var navigation = $('<div class="gallery-navigation"><h2>Portfolio</h2></div>');    

/*  UNCOMMENT THIS SECTION TO ADD PAGE NUMBERS.

    for (var i = 0; i < numpanels; i++) {
      if (i==n) { navigation.append("<h2>Page " + (i+1) + "</h2>"); }
      else {
        var link = $('<a href="#' + (i+1) + '" onclick="return false">Page ' + (i+1) + '</a>');
        navigation.append(link.click(handlePanelNavigationClick));
      }
    }
*/

    // build left and right arrows
    var leftarrow = "<a href='#' onclick='this.blur(); return false'>&nbsp;</a>";
    var rightarrow = leftarrow;
    if (n > 0) {
      leftarrow = $('<a href="#' + (n) + '">&laquo;</a>')
        .click(handlePanelNavigationClick);
    }
    if (n < (numpanels-1)) {
      rightarrow = $('<a href="#' + (n+2) + '">&raquo;</a>')
        .click(handlePanelNavigationClick);
    }
    navigation.prepend(leftarrow).append(rightarrow);
    
    // add navigation to the panel
    $(this).prepend(navigation);
    
    // resize panel panel, so that it's centered
    var panelUL = $(this).find('UL');
    var panelLastImage = $(this).find('LI:last');
    panelUL.width(panelLastImage.offset().left - panelUL.offset().left
                    + panelLastImage.width() + parseInt(panelLastImage.css('margin-left')) + 10);
    
  });
 
}

$(window).load(initializeGallery);
