/**
 * This script is free, create by Rigas Parathyras @ http://www.rigasp.com
 * You can use the script but please keep the credentials.
 * 
 * This script reads an xml file with the photos data and displays them.
 * It uses AJAX to load the xml file. Navigation is in the same url. 
 * 
 * Some instructions on how to use it as well as a sample photo album configuration are included in
 * http://www.rigasp.com/blog/2006/12/ajax-photo-album.html
 */

// --------------------------------------------------
var debug = true;
var maxPhotosPerPage = maxPhotosPerRow * maxRowsPerPage; 
var mode; // values 'album' or 'photo'

var album; // Global current album index 
var index; // Global current photo index in the album
var page = 0; // current page if more than 1

var slideShowIsPlaying = false; // flag for slide show default no slideshow
var timeoutId = 0; // default no slideshow

/* Load everything. This is the starting point and the public function. */
function loadPhotoAlbums () {
  loadXml();
}

/* Initialize the parameters from the url. 
 * The url can have the parameters:
 * album: can take values 0 .. albums length
 *  if ommited the first album is considered
 * index: can take values 0 .. max index in the album
 * photo: Instead of specifying the photo by index we can specify by
 * its name without the jpg extension
 * slideshow: can be 'true' or 'false'
 */
function initParamsFromUrl() {
  var query_vars = read_querystring_Ajax();
  // This is if we want to pass a photo by name	
  var photo = query_vars['photo'];
  if (photo != undefined && photo != 'undefined') {
    if (setupPhoto(photo)) {
      return; // album and index are setup
	}
  }
  var albumValue = query_vars['album'];
  if (albumValue == undefined) { // no var passed
    album = 0;
  } else {
    try {
      album = Number(albumValue);
    } catch (e) {
      album = 0;
    }
  }
  var indexValue = query_vars['index'];
  if (indexValue == undefined) { // no var passed
    index = 0;
	mode = 'album';
  } else {
    try {
      index = Number(indexValue);
	  mode = 'photo';
    } catch (e) {
      index = 0; 
    }
  }
  var slideshowValue = query_vars['slideshow'];
  if (slideshowValue == undefined) { // no var passed
    slideShowIsPlaying = false;
  } else if (slideshowValue == 'true') {
    slideShowIsPlaying = true;
  } else { // other wrong value
    slideShowIsPlaying = false;
  }
}

/* Called every time we update the view so that the url is bookmarkable */
function updateUrl() {
  var hashString = "album=" + album;
  if (mode == 'photo' || slideShowIsPlaying) {
	hashString += "&index=" + index;
  }
  if (page != 0 && mode == 'album') {
    hashString += "&page=" + page;
  }
  if (slideShowIsPlaying) {
    hashString += "&slideshow=" + slideShowIsPlaying;
  }
  //window.location.hash = hashString; // works only in FF
  hashListener.setHash(hashString);
  //display(); // if not use hashListener
}

/** Calculates the album and the index given the photo name */
function setupPhoto(photoName) {
  var albums = getXmlDocument().getElementsByTagName('album');
  for (album = 0; album < albums.length; album++) {
    var photos = albums[album].getElementsByTagName('photo');
	for (index = 0; index < photos.length; index++) {
	  if (photos[index].getAttribute("name") == photoName) {
	    return true;
      }
	}
  }
}

/** Called after the xml data has been loaded in order to display them. */
function display() {
  initParamsFromUrl();
  if (!slideShowIsPlaying && timeoutId > 0) {
    // Clear potentially started slide show 	
	stopSlideShowAction();
  } 
  if (slideShowIsPlaying) {
    loadPhoto();
    startSlideShowAction();
  } else if (mode == 'album') {
    loadAlbum();
	preloadNextAlbum();
	preloadPreviousAlbum();
  } else {
    loadPhoto();
	preloadNextPhoto();
	preloadPreviousPhoto();
  }
}

/* Called after having set the album variable in order to load the album */
function changeAlbum() {
  mode = 'album';
  updateUrl();
  loadAlbum();
}  

function loadAlbum() {  
  var tableHtml = "<table cellpadding=4>";
  var albumSize = getAlbumSize(album);
  var albumPages = getAlbumPages(album);
  var rows = Math.floor((albumSize - page * maxPhotosPerPage)/ maxPhotosPerRow);
  if (rows > maxRowsPerPage) {
    rows = maxRowsPerPage;
  }
  var photoIndex = page * maxPhotosPerPage;
  for (var row = 0; row < rows; row ++) {
    tableHtml += "<tr>";
    for (var column = 0; column < maxPhotosPerRow && photoIndex < albumSize; column++) {
      tableHtml += thumbnail(album, photoIndex);
      photoIndex++;
    }
    tableHtml += "</tr>";
  }
  if (page == albumPages - 1) { // last page
    var extraPhotos = (albumSize % maxPhotosPerRow);
    if (extraPhotos > 0) {
      tableHtml += "<tr>";
      for (var column = 0; column < maxPhotosPerRow ; column++) {
        if (extraPhotos > 0) {
          tableHtml += thumbnail(album, photoIndex);
          photoIndex++;
        } else {
          tableHtml += "<td></td>";
        }
        extraPhotos --;
      }
      tableHtml += "</tr>"
    }
  }	
  tableHtml += "</table><br/><br/>";
  // Change album description
  var albumDescription = getAlbumDescription(album);
  document.getElementById('thumbnailstable').innerHTML = tableHtml;
  document.getElementById('albumDescription').innerHTML = albumDescription;
  document.getElementById('photopanel').style.display = 'none';
  document.getElementById('thumbnailstable').style.display = 'inline';
  preloadAlbumPhotos(album);
//  document.getElementById("upLink").style.visibility = "hidden";
}

/* Change the photo to the one in the global album and index. */
function changePhoto(selectedIndex) {
  mode = 'photo';
  if (selectedIndex >= 0) {
    index = selectedIndex;
  }
  updateUrl();
  loadPhoto();
}

function loadPhoto(selectedIndex) {
  var photoname = getPhotoName(album, index);
  var photoDescription = getPhotoDescription(album, index);
  var albumDescription = getAlbumDescription(album);
  var photoSource = getPhotoSource(album, index)
  var html = "<img id=\"photo\" name=\"photo\" " + 
  	"src=\"" + photoSource + "\"title=\"" + photoDescription + "\"alt=\"" + photoDescription + "\" />" + 
   	"<br/>" + 
   	"<span class=\"caption\" id=\"photoDescription\" >" + photoDescription + "</span>" + 
   	"<br/><br/>";
  document.getElementById('albumDescription').innerHTML = albumDescription;
  document.getElementById('photopanel').innerHTML = html;
  document.getElementById('photopanel').style.display = 'inline';
  document.getElementById('thumbnailstable').style.display = 'none';
}


/* Returns the code to write a <td> in the thumbnails table */
function thumbnail(anAlbum, anIndex) {
  var photoname = getPhotoName(anAlbum, anIndex);
  var photoDescription = getPhotoDescription(anAlbum, anIndex);
  var str ;
  str = '<td  class="phototable" align="center" valign="middle">' + 
        '<a onclick="changePhoto(' + anIndex + ')"> ' + 
  	    '<img style="cursor:pointer" ';
  if (!useThumbnailsDir || resizeThumbnails) {
    str += 'width="' + defaultThumbnailWidth +'" ';
    str += 'height="' + defaultThumbnailHeight +'" ';
  }  
  str += 'src="' + getThumbnailSource(anAlbum, anIndex) + '"' +
        'border=0 title="' +  photoDescription + '" ' +
        'alt="' + photoDescription + '"/></a></td>';
  return str;
} 

/* Called when next album button is pressed */
function nextAlbum() {
  if (page < getAlbumPages(album) - 1) {
    page++;
    changeAlbum();
  } else if (album < getPhotoAlbumsSize() - 1) {
    album++;
    page = 0;
    changeAlbum();
  } else {
    if (confirmNav ('End of albums. Start from beginning?')) {
      index = 0;
      album = 0;
      page = 0;
      changeAlbum();
    }
  }  
  preloadNextAlbum();
}

/* Called when previous album button is pressed */
function previousAlbum() {
  if (page > 0) {
    page--;
    changeAlbum();
  } else if (album > 0) {
    album--;
    page = getAlbumPages(album) - 1;
    changeAlbum();
  } else {
    alertNav ('This is the beginning of the albums');
  }  
  preloadPreviousAlbum();
}

/* Called when next photo button is pressed */
function nextPhoto() {
  if (index < getAlbumSize(album) - 1) {
    index ++;
    page = getPage(index);
  } else {
    if (album < getPhotoAlbumsSize() - 1) {
      if (confirmNav ('End of album. Proceed to next one (' + getAlbumDescription(album+1) + ')?')) {
        index = 0;
        album ++;
        page = 0;
      }
    } else {
      if (confirmNav ('End of albums. Start from beginning?')) {
        index = 0;
        album = 0;
        page = 0;
      }
    }
  }
  changePhoto();
  preloadNextPhoto();
}

/* Called when previous photo button is pressed */
function previousPhoto() {
  if (index > 0) {
    index --;
    page = getPage(index);
  } else {
    if (album > 0) {
      if (confirmNav ('Proceed to previous album (' + getAlbumDescription(album-1) + ')?')) {
        index = getAlbumSize(album - 1) - 1;
        album --;
        page = getPage(index);
      }
    } else {
      alertNav ('This is the beginning of the photo albums');
    }
  }
  changePhoto();
  preloadPreviousPhoto()
}

// ------------------------------------Slide show related  ----------------------------------------

function slideShow() {
  if (slideShowIsPlaying) {
    nextPhoto();
    preloadNextPhoto();
  }
}

function displaySlideShowLink(startStop) {
  var stopSlideShowElement = document.getElementById("stopSlideShow");
  var startSlideShowElement = document.getElementById("startSlideShow");
  var rollingElement = document.getElementById("rolling");
  var presentationElement = document.getElementById("presentation");
  
  if (startStop == 'start') { // display the start
    if (stopSlideShowElement) stopSlideShowElement.style.display = "none";
    if (startSlideShowElement) startSlideShowElement.style.display = "inline";
	if (rollingElement) rollingElement.style.display = "none";
	if (presentationElement) presentationElement.style.display = "inline";
  } else if (startStop == 'stop') {
    if (startSlideShowElement) startSlideShowElement.style.display = "none";
    if (stopSlideShowElement) stopSlideShowElement.style.display = "inline";
	if (rollingElement) rollingElement.style.display = "inline";
	if (presentationElement) presentationElement.style.display = "none";
  }
}

function startSlideShowAction() {
  slideShowIsPlaying = true;
  mode = 'photo';
  if (timeoutId == 0) {
    timeoutId = window.setInterval("slideShow()", 5000); 
  }
  displaySlideShowLink('stop');
}

function stopSlideShowAction() {
  slideShowIsPlaying = false;
  window.clearInterval(timeoutId);
  timeoutId = 0;
  displaySlideShowLink('start');
}

// ------------------------------------Button Events ----------------------------------------

/* Button event. Called when start slide show is pressed */
function startSlideShow() {
  slideShowIsPlaying = true;
  updateUrl();
}

/* Button event. Called when stop slide show is pressed */
function stopSlideShow() {
  slideShowIsPlaying = false;
  updateUrl();
}

/* Button event. Next photo or album or page*/
function next() {
  if (slideShowIsPlaying) {
    stopSlideShowAction();
  }
  if (mode == 'album') {
    nextAlbum();
  } else { // mode == 'photo'
    nextPhoto();
  }
}

/* Button event. Previous photo or album or page */
function previous() {
  if (slideShowIsPlaying) {
    stopSlideShowAction();
  }
  if (mode == 'album') {
    previousAlbum();
  } else { // mode == 'photo'
    previousPhoto();
  }
}

/* Button event. Up to album or up to parent directory */
function up() {
  if (slideShowIsPlaying) {
    stopSlideShowAction();
  }
  if (mode == 'photo') {
    changeAlbum();
  } else { // mode == 'album'
    window.location = homeUrl;
  }
}
// ------------------------------------------ Data ----------------------------------------

var xmlDoc;

/* Does an AJAX call to load the xml document. */
var req;
function loadXml() {
  req = getXMLHttpRequest();
  req.onreadystatechange=postLoadXml;
  req.open("GET", fileName, true);
  req.send("");
}

/* Callback function after the xml has been loaded. */
function postLoadXml() {
  if (req.readyState==4 || req.readyState=="complete") {
    xmlDoc = getXMLDocumentFromString(req.responseText);
    display();
    return true;
  } else {
    return false;
  }
}

function getXmlDocument() {
  if (xmlDoc == null) { 
    alert('Error initializing data!');	
  } 
  return xmlDoc;
}

function getThumbnailSource(anAlbum, anIndex) {
  var photoName = getPhotoName(anAlbum, anIndex);
  if (!useThumbnailsDir) {
	thumbnailsDir = photoDir;
  }
  var thumbSource = thumbnailsDir + '/' + thumbnailsPrefix + photoName;
  if (useCommonPhotosExtension) {
    thumbSource += "." + commonPhotosExtension;
  }  
  return thumbSource;
}

/* Return the photo source - src attribute. */
function getPhotoSource(anAlbum, anIndex) {
  var photoName = getPhotoName(anAlbum, anIndex);
  var photoSource = photoDir + '/' + photoName ;
  if (useCommonPhotosExtension) {
    photoSource += "." + commonPhotosExtension;
  }  
  return photoSource;
}

/* Return the name of the photo given the album and index number */
function getPhotoName(anAlbum, anIndex) {
  var album = getXmlDocument().getElementsByTagName('album')[anAlbum];
  var photo = album.getElementsByTagName('photo')[anIndex];
  return photo.getAttribute("name");
}

/* Return the description of the photo given the album and index number */
function getPhotoDescription(anAlbum, anIndex) {
  var album = getXmlDocument().getElementsByTagName('album')[anAlbum];
  var photo = album.getElementsByTagName('photo')[anIndex];
  return photo.getAttribute("description");
}

/* Return the description of an album */
function getAlbumDescription(anAlbum) {
  var album = getXmlDocument().getElementsByTagName('album')[anAlbum];
  return album.getAttribute("description");
}

/* Return the size of the current album */
function getAlbumSize(anAlbum) {
  var album = getXmlDocument().getElementsByTagName('album')[anAlbum];
  return album.getElementsByTagName('photo').length;
}

/* Return the number of albums in the collection. */
function getPhotoAlbumsSize() {
  return getXmlDocument().getElementsByTagName('album').length;
}

/* Returns the number of pages that an album contains. */
function getAlbumPages(anAlbum) {
  var albumSize = getAlbumSize(album);
  var albumPages = Math.ceil(albumSize / maxPhotosPerPage);
  return albumPages;
}

/* Returns the page index of the photo in an album. */
function getPage(anIndex) {
  var aPage = Math.floor(anIndex / maxPhotosPerPage);
  return aPage;
}


// --------------------------------- Preloading Functions for performance ----------------------------------------

function preloadNextAlbum() {
  var nextAlbum = album;
  if (album < getPhotoAlbumsSize() - 1) {
    nextAlbum++;
  } else {
    nextAlbum = 0;
  }
  preloadAlbumThumbnails(nextAlbum);
}

function preloadPreviousAlbum() {
  var previousAlbum = album;
  if (album < getPhotoAlbumsSize() - 1) {
    previousAlbum++;
  } else {
    previousAlbum = 0;
  }
  preloadAlbumThumbnails(previousAlbum);
}

function preloadAlbumThumbnails(anAlbum) {
  var preloadedPhoto;
  var thumbSource; 
  for (var i = 0; i < getAlbumSize(anAlbum); i++) {
    thumbSource= getThumbnailSource(anAlbum, i);
    preloadedPhoto = new Image();
    preloadedPhoto.src = thumbSource;
  }
}

function preloadAlbumPhotos(anAlbum) {
  var preloadedPhoto;
  var thumbSource; 
  for (var i = 0; i < getAlbumSize(anAlbum); i++) {
    thumbSource= getPhotoSource(anAlbum, i);
    preloadedPhoto = new Image();
    preloadedPhoto.src = thumbSource;
  }
}

/* Preloads the next photo */
function preloadNextPhoto() {
  var preloadedAlbum = album;
  var preloadedIndex = index;
  if (index < getAlbumSize(album) - 1) {
    preloadedIndex++;
  } else {
    if (album < getPhotoAlbumsSize() - 1) {
      preloadedIndex = 0;
      preloadedAlbum++;
    } else {
      preloadedIndex = 0;
      preloadedAlbum = 0;
    }
  }
  var preloadedPhoto = new Image();
  var source = getPhotoSource(preloadedAlbum, preloadedIndex);
  preloadedPhoto.src = source;
}

/* Preloads the next photo */
function preloadPreviousPhoto() {
  var preloadedAlbum = album;
  var preloadedIndex = index;
  if (index > 0) {
    preloadedIndex --;
  } else {
    if (album > 0) {
      preloadedIndex = getAlbumSize(album - 1) - 1;
      preloadedAlbum --;
    }
  }
  var preloadedPhoto = new Image();
  var source = getPhotoSource(preloadedAlbum, preloadedIndex);
  preloadedPhoto.src = source;
}


// ----------------------- Confirm and Alert disabled in slideshow -----------------------------------------

/* Alert function - displayed only if not in slide show view */
function alertNav(text) {
  if (!slideShowIsPlaying) {
    alert(text);
  }
}

/* Confirm function - displayed only if not in slide show view */
function confirmNav(text) {
  if (!slideShowIsPlaying) {
    return confirm(text);
  } else {
    return true;
  }
}

