/* slideshow.js
 *
 * Copyright 2008 Hubert Chathi <hubert@uhoreg.ca>
 *
 *   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 3 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, see <http://www.gnu.org/licenses/>.
 *
 */

var verticalPadding = 6, horizontalPadding = 0;
var imageVerticalPadding = 6, imageHorizontalPadding = 6;

var animSteps = 3;
var animDuration = 1000; // in milliseconds
var slideTimeout = 5000; // in milliseconds

var width = -1, height = -1;
var images = new Array(0);
var curImageNum = 0;
var curImageContainer = 0;
var toosmall = 0;
var nextSlideTimer = null;
var transitionTimer = null;
var transition = null;

//                                                ___________________________
// ______________________________________________/ Image loading and display \_

/* Resize the image container (height) to take up as much space as possible.
 */
function resizeImageContainer()
{
  // fetch window display size, based on
  // http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  if (window.innerWidth != null)
  { //Non-IE
    width = window.innerWidth;
    height = window.innerHeight;
  }
  else if (document.documentElement
           && (document.documentElement.clientWidth
	       || document.documentElement.clientHeight))
  { //IE 6+ in 'standards compliant mode'
    width = document.documentElement.clientWidth;
    height = document.documentElement.clientHeight;
  }
  else if (document.body
           && (document.body.clientWidth || document.body.clientHeight))
  { //IE 4 compatible
    width = document.body.clientWidth;
    height = document.body.clientHeight;
  }
  else
  {
    document.body.innerHTML = 'Sorry, your browser does not support the necessary functions for the slideshow.';
    return;
  }

  // set the height of the image container to fit the window
  navigation = document.getElementById('navigation');
  imagecontainer = document.getElementById('imagecontainer');
  thumbnailbar = document.getElementById('thumbnailbar');
  containerheight = height - navigation.offsetHeight - thumbnailbar.offsetHeight - verticalPadding
  toosmall = 0;
  if (containerheight < 10)
  {
    document.getElementById('image0').style.display = 'none';
    document.getElementById('image1').style.display = 'none';
    document.getElementById('sizeerror').style.display = null;
    toosmall = 1;
    imagecontainer.style.height = null;
    return;
  }
  document.getElementById('sizeerror').style.display = 'none';
  imagecontainer.style.height = containerheight + 'px';

  // scale the image to fit the image container, as big as possible
  image = document.getElementById('image' + curImageContainer);
  image.style.display = null;
  sizes = calculateImageSize(curImageNum);
  image.setAttribute('width', sizes[0]);
  image.setAttribute('height', sizes[1]);

  // centre the image
  image.style.left = (imagecontainer.clientWidth - sizes[0] - imageHorizontalPadding) / 2 + 'px';
  image.style.top = (imagecontainer.clientHeight - sizes[1] - imageVerticalPadding) / 2 + 'px';
}

/* calculate the size of the image to be as big as possible to fit in the
 * container.
 */
function calculateImageSize(num)
{
  imagecontainer = document.getElementById('imagecontainer');
  scalex = (imagecontainer.clientWidth - imageHorizontalPadding) / images[num][1];
  scaley = (imagecontainer.clientHeight - imageVerticalPadding) / images[num][2];
  scale = scalex < scaley ? scalex : scaley;
  return [images[num][1]*scale, images[num][2]*scale];
}

var imagepre = null; // for image preloading

function setOpacity(element, opacity)
{
  element.style.opacity = opacity;
  element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')'; // for IE
}

function loadImage(num, nopause)
{
  if (toosmall)
    return;
  if (!nopause)
    pause();
  if (imagepre)
  { // stop any previous image switching
    imagepre.onload = null;
    imagepre = null;
  }
  if (transition)
  {
    transition.setProgress(animSteps);
  }
  direction = num < curImageNum ? 0 : 1;
  if (curImageNum == num)
  {
    return;
  }

  oldImage = document.getElementById('image' + curImageContainer);
  curImageContainer = curImageContainer ? 0 : 1;
  image = document.getElementById('image' + curImageContainer);

  imagepre = new Image();
  imagepre.src = images[num][0];
  imagepre.onload = displayMe(num, image, direction, oldImage);
}

function displayMe(num, image, direction, oldImage)
{
  imagepre.onload = null;
  image.src = images[num][0];
  imagepre = null;
  curImageNum = num;

  sizes = calculateImageSize(num);
  image.setAttribute('width', sizes[0]);
  image.setAttribute('height', sizes[1]);

  imagecontainer = document.getElementById('imagecontainer');
  image.style.left = (imagecontainer.clientWidth - sizes[0] - imageHorizontalPadding) / 2 + 'px';
  image.style.top = (imagecontainer.clientHeight - sizes[1] - imageVerticalPadding) / 2 + 'px';

  // Don't animate for now.  It's too slow...
  oldImage.style.display = 'none';
  image.style.display = null;
  return;

  progress = 0;
  transition = this;

  function timerFunc()
  {
    setProgress(++progress);
  }

  this.fade = function(progress)
  {
    if (progress >= animSteps)
    {
      clearInterval(transitionTimer);
      transitionTimer = null;
      transition = null;
      oldImage.style.display = 'none';
      oldImage.src = null;
      setOpacity(image, 1);
      return;
    }
    setOpacity(image, progress / animSteps);
    setOpacity(oldImage, 1 - (progress / animSteps));
  }

  this.sweep = function(progress)
  {
    if (progress >= animSteps)
    {
      clearInterval(transitionTimer);
      transitionTimer = null;
      transition = null;
      oldImage.style.display = 'none';
      oldImage.src = null;
      image.style.left = (imagecontainer.clientWidth - image.offsetWidth) / 2 + 'px';
      setOpacity(image, 1);
      return;
    }
    setOpacity(image, progress / animSteps);
    setOpacity(oldImage, 1 - (progress / animSteps));
    if (direction)
    {
      startleft = imagecontainer.clientWidth;
      endleft = (imagecontainer.clientWidth - image.offsetWidth) / 2;
      image.style.left = startleft + (endleft - startleft) * progress / animSteps + 'px';
    }
    else
    {
      startleft = (imagecontainer.clientWidth - oldImage.offsetWidth) / 2;
      endleft = -(oldImage.offsetWidth + imageHorizontalPadding);
      oldImage.style.left = startleft + (endleft - startleft) * progress / animSteps + 'px';
    }
  }

  this.pageflip = function(progress)
  {
    if (progress >= animSteps)
    {
      clearInterval(transitionTimer);
      transitionTimer = null;
      transition = null;
      oldImage.style.display = 'none';
      oldImage.src = null;
      image.style.left = (imagecontainer.clientWidth - image.offsetWidth) / 2 + 'px';
      setOpacity(image, 1);
      return;
    }
    setOpacity(image, progress / animSteps);
    setOpacity(oldImage, 1 - (progress / animSteps));
    if (direction)
    {
      startleft = (imagecontainer.clientWidth - oldImage.offsetWidth) / 2;
      endleft = -(oldImage.offsetWidth + imageHorizontalPadding);
      oldImage.style.left = startleft + (endleft - startleft) * progress / animSteps + 'px';
    }
    else
    {
      startleft = -(image.offsetWidth + imageHorizontalPadding);
      endleft = (imagecontainer.clientWidth - image.offsetWidth) / 2;
      image.style.left = startleft + (endleft - startleft) * progress / animSteps + 'px';
    }
  }

  this.scroll = function(progress)
  {
    if (progress >= animSteps)
    {
      clearInterval(transitionTimer);
      transitionTimer = null;
      transition = null;
      oldImage.style.display = 'none';
      oldImage.src = null;
      image.style.left = (imagecontainer.clientWidth - image.offsetWidth) / 2 + 'px';
      setOpacity(image, 1);
      return;
    }
    setOpacity(image, progress / animSteps);
    setOpacity(oldImage, 1 - (progress / animSteps));
    if (direction)
    {
      startleft = (imagecontainer.clientWidth - oldImage.offsetWidth) / 2;
      endleft = -(oldImage.offsetWidth + imageHorizontalPadding);
      oldImage.style.left = startleft + (endleft - startleft) * progress / animSteps + 'px';
      startleft = imagecontainer.clientWidth;
      endleft = (imagecontainer.clientWidth - image.offsetWidth) / 2;
      image.style.left = startleft + (endleft - startleft) * progress / animSteps + 'px';
    }
    else
    {
      startleft = -(image.offsetWidth + imageHorizontalPadding);
      endleft = (imagecontainer.clientWidth - image.offsetWidth) / 2;
      image.style.left = startleft + (endleft - startleft) * progress / animSteps + 'px';
      startleft = (imagecontainer.clientWidth - oldImage.offsetWidth) / 2;
      endleft = imagecontainer.clientWidth;
      oldImage.style.left = startleft + (endleft - startleft) * progress / animSteps + 'px';
    }
  }

  this.setProgress = this.scroll;

  setProgress(0);
  image.style.display = null;

  transitionTimer = setInterval(timerFunc, animDuration/animSteps);
}

//                                                     ______________________
// ___________________________________________________/ Navigation functions \_

function next()
{
  if (curImageNum + 1 < images.length)
    loadImage(curImageNum + 1);
}

function prev()
{
  if (curImageNum > 0)
    loadImage(curImageNum - 1);
}

function first()
{
  loadImage(0);
}

function last()
{
  loadImage(images.length - 1);
}

//                                                                ___________
// ______________________________________________________________/ Slideshow \_

function play()
{
  if (toosmall)
    return;
  document.getElementById('navplaypause').href="javascript:pause()";
  icon = document.getElementById('navplaypauseicon')
  icon.src = 'http://icons.uhoreg.ca/actions/media-playback-pause.png';
  icon.setAttribute('alt', 'pause');
  icon.setAttribute('title', 'pause the slide show');
  if (nextSlideTimer || images.length <= 1)
  { // already playing, or nothing to play: don't do anything
    return;
  }
  if (curImageNum >= images.length - 1)
    loadImage(0, true); // at last image, so go back to beginning
  nextSlideTimer = setInterval(timedNext, slideTimeout);
}

function pause()
{
  document.getElementById('navplaypause').href="javascript:play()";
  icon = document.getElementById('navplaypauseicon')
  icon.src = 'http://icons.uhoreg.ca/actions/media-playback-start.png';
  icon.setAttribute('alt', 'play');
  icon.setAttribute('title', 'play the slide show');
  clearInterval(nextSlideTimer);
  nextSlideTimer = null;
}

function timedNext()
{
  if (curImageNum >= images.length - 1)
  {
    pause();
    return;
  }
  preload = -1;
  if (curImageNum + 2 < images.length)
  {
    preload = curImageNum + 2;
  }
  loadImage(curImageNum + 1, true);

  if (preload >= 0)
  {
    image = new Image();
    image.src = images[preload][0];
  }
}

function onload()
{
  resizeImageContainer();
  if (images.length > 1)
  {
    preimage = new Image();
    preimage.src = images[1][0];
    play();
  }
}

/* end of slideshow.js */

