//     This file is part of the XML Photo Gallery Project
//     by Philip J. Guo (Created August 2005)
//     Copyright 2005 Philip J. Guo
//     http://web.mit.edu/pgbovine/www/
//
//       based on the People Photo Gallery Project
//       by Philip J. Guo (Created January 2005)
//       Copyright 2005 Philip J. Guo
//
//     This program is free software; you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation; either version 2 of the License, or
//     (at your option) any later version.

//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.

//     You should have received a copy of the GNU General Public License
//     along with this program; if not, write to the Free Software
//     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


// This is the JavaScript file which provides dynamic functionality to 
// the HTML pages generated by the xml_gal.xml XSLT stylesheet


// GUI Elements
var title;
var photoDescription;
var date;
var MainDisplayPanel;
var ThumbnailsPanel;
var ToggleThumbnailsLink;
var GalleryAdvancedSearchTitle;

var selectedImage;
var photoSlider;
var picIndex;
var totalPicNum;
var GalleryTitle;


// Global variables:

var MainDisplayPanelShown = true;

var numImages = 0;
var images = new Array(); // Initialize to array of MyImage objects

var galleryName = '';
var folderName = ''; // Initialize when processing XML files
// (The "directoryName" field within the Image class overrides this global one)

var thumb_folder = 'thumbnails/';
var image_folder = 'images/';

var size_multiplier = 1;

// The index of the image currently displayed in full
var currentIndex=0;

// The index of the previous image which you visited
// right before this one (useful for loading the data
// from the image at previousIndex to currentIndex)
var previousIndex=0;

// The index of the image currently in the center of the slider
// (this may or may not be equal to currentIndex)
var centerIndex=0;

// The absolute horizontal position of the slider strip
// Do not insert this directly into the 'span'
var horizontalPos = 0;

// The total width occupied by an image in the slider, including spacing and margins
var totalImageWidth = 150;

//Specify the slider's width and height (in pixels)
// Note that these are NOT used to draw the slider on the page -
// Now it is hardcoded into #SliderWrapper in the HTML file
var sliderwidth=(5 * totalImageWidth) + "px";
var sliderheight= "142px";


// Initialize in InitializeSlider():
var actualwidth = 0;

//Specify the slider's slide speed (larger is faster 1-10 - needs to be multiple of 5)
var slidespeed=10;
	  
var timerVal;
var buttonHeldDown = false;
var isSliding = false; // Don't allow anything to be done while the slider is sliding
var mod = 0;

var jumptime;
var slideCount = 1;

// This WILL change if totalImageWidth changes or the jump methods won't work properly
var rapidSlideSpeed = (2 * 15);


window.onresize = checkBrowserWidth;


// Super-simple implementation of the MyImage class:

// MyImage object methods

// "filename" is a String
function Image_getFilename() {
  return this.filename;
}

// "title" is a String
function Image_getTitle() {
  return this.title;
}

// "description" is a String
// "description" isn't required to have content - it may be left blank
function Image_getDescription() {
  return this.description;
}

function Image_getMonth() {
  return this.month;
}

// "year" is an int (4 digits)
function Image_getYear() {
  return this.year;
}

// "width" is an int
function Image_getWidth() {
  return this.width;
}

// "height" is an int
function Image_getHeight() {
  return this.height;
}

// Returns a string that replaces " with \"
function sanitize_quotes(str) {
  return str.replace(/"/g, '\\\"');
}

// Ok, this is REALLY IMPORTANT!  DO NOT name this class Image, because
// when it used to be named Image, Safari TOTALLY BARFED!  Apparently, there is 
// already a built-in Image class, and all other browsers override it with my
// custom-defined Image class ... except for Safari!  Thus, the moral of the
// hour is to not name your classes the same thing as built-in classes :)
// (Of course, Safari could've issued me some sort of warning, but oh well)

// Constructor for MyImage object
function MyImage(fn, titl, desc, m, y, w, h) {

  this.filename = fn;
  this.title = titl;
  this.description = desc;
  this.month = m;
  this.year = y;
  this.width = w;
  this.height = h;

  this.directoryName = "";
}

// Forces prototype object to be created:
new MyImage("", "", "", 0, 0, 0, 0);

// Define methods of Image class via an object prototype:
MyImage.prototype.getFilename = Image_getFilename;
MyImage.prototype.getTitle = Image_getTitle;
MyImage.prototype.getDescription = Image_getDescription;

MyImage.prototype.getMonth = Image_getMonth;
MyImage.prototype.getYear = Image_getYear;

MyImage.prototype.getWidth = Image_getWidth;
MyImage.prototype.getHeight = Image_getHeight;



function InitGallery() {
  // Initialize GUI elements
  selectedImage = document.getElementById ? 
    document.getElementById("selectedImage") : 
    document.all.selectedImage;

  photoSlider = document.getElementById ? 
    document.getElementById("SliderContents") : 
    document.all.SliderContents;

  picIndex = document.getElementById ? 
    document.getElementById("picIndex") : 
    document.all.picIndex;

  totalPicNum = document.getElementById ? 
    document.getElementById("totalPicNum") : 
    document.all.totalPicNum;

  GalleryTitle = document.getElementById ? 
    document.getElementById("GalleryTitle") : 
    document.all.GalleryTitle;

  title = document.getElementById ? 
    document.getElementById("title") : 
    document.all.title;
  photoDescription = document.getElementById ? 
    document.getElementById("photoDescription") : 
    document.all.photoDescription;
  date = document.getElementById ? 
    document.getElementById("date") : 
    document.all.date;
  MainDisplayPanel = document.getElementById ? 
    document.getElementById("MainDisplayPanel") : 
    document.all.MainDisplayPanel;
  ThumbnailsPanel = document.getElementById ? 
    document.getElementById("ThumbnailsPanel") : 
    document.all.ThumbnailsPanel;
  ToggleThumbnailsLink = document.getElementById ? 
    document.getElementById("ToggleThumbnailsLink") : 
    document.all.ToggleThumbnailsLink;

  MainDisplayPanelShown = false;
  MainDisplayPanel.style.display = "none";
  GalleryTitle.style.display = "none";

  InitData();

  // Load the first image so that there is something always displayed
  // in selectedImage
  if (numImages)
    LoadImage(images[0].getFilename(), 0);
}


function ReturnMonth(num) {
  if (num == 1)
    return "Jan.";
  else if (num == 2)
    return "Feb.";
  
  switch (num) {
  case 1: return "Jan.";
  case 2: return "Feb.";
  case 3: return "Mar.";
  case 4: return "Apr.";
  case 5: return "May";
  case 6: return "June";
  case 7: return "July";
  case 8: return "Aug.";
  case 9: return "Sep.";
  case 10: return "Oct.";
  case 11: return "Nov.";
  case 12: return "Dec.";
  default: return "";
  }
}

// This text displays while the selected image is loading
function DisplayImageLoadingText() {
  title.innerHTML = "Please wait ... Loading current image ...";
  date.innerHTML = "";
  photoDescription.innerHTML = "";
}

function LoadText(ind) {
  title.innerHTML = images[ind].getTitle();
  photoDescription.innerHTML = images[ind].getDescription();
  if (images[ind].getMonth() > 0) {
    date.innerHTML = '(' + ReturnMonth(images[ind].getMonth()) + ' ' + images[ind].getYear() + ')';
  }
  picIndex.innerHTML = (ind + 1);
}

function ToggleThumbnailPanel() {
  if (MainDisplayPanelShown) {
    MainDisplayPanel.style.display = "none";
    GalleryTitle.style.display = "none";
    ThumbnailsPanel.style.display = "block";
    ToggleThumbnailsLink.innerHTML = "Show Large Images";
    MainDisplayPanelShown = false;
  }
  else {
    MainDisplayPanel.style.display = "block";
    GalleryTitle.style.display = "block";
    ThumbnailsPanel.style.display = "none";
    ToggleThumbnailsLink.innerHTML = "Show Thumbnails";
    MainDisplayPanelShown = true;
  }
}

function SkipToImage(filename, index) {
  ToggleThumbnailPanel();
  LoadImage(filename, index, true);
}

function checkBrowserWidth() {
  var theWidth = getBrowserWidth();

  // We really don't want to shrink the image because it looks quite ugly,
  // so only do it if the browser window is way small
  if (theWidth > 800) {
    size_multiplier = 1;
  }
  else {
    size_multiplier = 0.75;
  }

  // Resize the current image
  selectedImage.width = (images[currentIndex].getWidth() * size_multiplier);
  selectedImage.height = (images[currentIndex].getHeight() * size_multiplier);

  return true;
}

function getBrowserWidth() {
  if (window.innerWidth) {
    return window.innerWidth;
  }
  else if (document.documentElement && document.documentElement.clientWidth != 0) {
    return document.documentElement.clientWidth;
  }
  else if (document.body) {
    return document.body.clientWidth;
  }
	
  return 0;
}

function LoadImage(fileName, index, abruptJump /*optional - true for JumpToCenterImage()*/) {
    
    if (centerIndex != index) {
    if (abruptJump) {
      JumpToCenterImage(index, centerIndex);
    }
    else {
      SlideToCenterImage(index, centerIndex);
    }
    
    previousIndex = currentIndex;
    currentIndex = index;
    centerIndex = index;
  }

  var folder = (images[index].directoryName ? 
		images[index].directoryName : 
		folderName);

  selectedImage.src="one.gif";
//  selectedImage.src="";

  DisplayImageLoadingText();

// We want to load the actual image after a tiny delay
// so that we have enough time to display the blank 'one.gif'
// image.  This way, we can avoid the unsightly effect
// where the previous image shrinks/distorts before the
// next image loads:
// (sanitize quotes to prevent problems when there are
// double-quotes in the title)
  setTimeout('LoadImageAfterDelay("' + folder + '/' + image_folder + fileName + '", "' + sanitize_quotes(images[index].title) +'", "' + (images[index].getWidth() * size_multiplier) + '", "' + (images[index].getHeight() * size_multiplier) + '")', 100);

//  selectedImage.src = folder + '/' + image_folder + fileName;
//  selectedImage.alt = images[index].title;
//  selectedImage.width = (images[index].getWidth() * size_multiplier);
//  selectedImage.height = (images[index].getHeight() * size_multiplier);

  LoadText(index);
}

function LoadImageAfterDelay(mySrc, myAlt, myWidth, myHeight) {
  selectedImage.src = mySrc;
  selectedImage.alt = myAlt;
  selectedImage.width = myWidth;
  selectedImage.height = myHeight;
}


function CenterOnCurrentImage() {
  photoSlider.style.left=(-1 * currentIndex * totalImageWidth) + "px";
  centerIndex = currentIndex;
}

function SelectCenterImage() {
  previousIndex = currentIndex;
  currentIndex = centerIndex;
  LoadImage(images[currentIndex].getFilename(), currentIndex);
}

function slideleft() {
  if ((-1 * parseInt(photoSlider.style.left)) + parseInt(sliderwidth) < (actualwidth - horizontalPos)) {
    photoSlider.style.left=parseInt(photoSlider.style.left)-slidespeed+"px"

      mod = (parseInt(photoSlider.style.left) % totalImageWidth);

    if (mod == 0) {
      if (currentIndex < (numImages - 1))
	previousIndex = currentIndex;
	currentIndex += 1;
        centerIndex += 1;

      if (!buttonHeldDown) {
	clearInterval(timerVal);
	LoadImage(images[currentIndex].getFilename(), currentIndex);
	isSliding = false;
      }
    }
  }
  else {
    clearInterval(timerVal);
    LoadImage(images[currentIndex].getFilename(), currentIndex);
    isSliding = false;
  }
}

function slideright() {
  if (parseInt(photoSlider.style.left) < (horizontalPos)) {
    photoSlider.style.left=parseInt(photoSlider.style.left)+slidespeed+"px"

      mod = (parseInt(photoSlider.style.left) % totalImageWidth);

    if (mod == 0) {
      if (currentIndex > 0)
	previousIndex = currentIndex;
	currentIndex -= 1;
        centerIndex -= 1;

      if (!buttonHeldDown) {
	clearInterval(timerVal);
	LoadImage(images[currentIndex].getFilename(), currentIndex);
	isSliding = false;
      }
    }
  }
  else {
    clearInterval(timerVal);
    LoadImage(images[currentIndex].getFilename(), currentIndex);
    isSliding = false;
  }
}

// Quickly jumps x pictures to the left
function jumpleft(x) {
  if ((-1 * parseInt(photoSlider.style.left)) + parseInt(sliderwidth) < (actualwidth - horizontalPos)) {
    photoSlider.style.left=parseInt(photoSlider.style.left)-rapidSlideSpeed+"px"

      mod = (parseInt(photoSlider.style.left) % totalImageWidth);

    if (mod == 0) {
      if (slideCount >= x) {
	clearInterval(jumptime);
	isSliding = false;
      }
      else
	slideCount++;
    }
  }
  else {
    clearInterval(jumptime);
    isSliding = false;
  }
}

function shiftCenterIndex(x) {
  centerIndex += x;

  if (centerIndex < 0) 
    centerIndex = 0;

  if (centerIndex >= numImages) 
    centerIndex = numImages - 1;
}

// Quickly jumps x pictures to the right
function jumpright(x) {
  if (parseInt(photoSlider.style.left) < (horizontalPos)) {
    photoSlider.style.left=parseInt(photoSlider.style.left)+rapidSlideSpeed+"px"

      mod = (parseInt(photoSlider.style.left) % totalImageWidth);

    if (mod == 0) {
      if (slideCount >= x) {
	clearInterval(jumptime);
	isSliding = false;
      }
      else
	slideCount++;
    }
  }
  else {
    clearInterval(jumptime);
    isSliding = false;
  }
}

function SlideToCenterImage(index, centerIndex) {
  var deltaPos = index - centerIndex;

  slideCount = 1;
  clearInterval(jumptime); 
  if (deltaPos > 0) {
    jumptime=setInterval("jumpleft(" + deltaPos + ")", 30);
  }
  else if (deltaPos < 0) {
    jumptime=setInterval("jumpright(" + (-1 * deltaPos) + ")", 30);
  }
}

// Abruptly jumps to the center index
function JumpToCenterImage(index, centerIndex) {
  var photoSliderLeft = parseInt(photoSlider.style.left);

  // Remember the 'px' or it won't work with XHTML!!!
  photoSlider.style.left = 
    (photoSliderLeft - ((index - centerIndex) * totalImageWidth)) + "px";
}

function PrevPicHandler() {
  if (!isSliding) {
    CenterOnCurrentImage(); 
    isSliding = true;
    clearInterval(timerVal); 
    timerVal=setInterval("slideright()", 25);
    buttonHeldDown = true;
  }
}

function NextPicHandler () {
  if (!isSliding) {
    CenterOnCurrentImage(); 
    isSliding = true;
    clearInterval(timerVal); 
    timerVal = setInterval("slideleft()", 25);
    buttonHeldDown = true;
  }
}

function JumpRightHandler() {
  if (!isSliding) { // Prevents repeated quick clicks from screwing things up
    slideCount = 1; 
    isSliding = true;
    clearInterval(jumptime);
    shiftCenterIndex(5);
    jumptime = setInterval("jumpleft(5)",10);
  }
}

function JumpLeftHandler() {
  if (!isSliding) { // Prevents repeated quick clicks from screwing things up
    slideCount = 1; 
    isSliding = true;
    clearInterval(jumptime); 
    shiftCenterIndex(-5);
    jumptime = setInterval("jumpright(5)",10);
  }
}
