/* whSlideshow
   $CVSHeader: blexplayground/whslideshow/whslideshow.js,v 1.3 2009/05/29 12:15:49 mark Exp $

   public api:

   whSlideshow(settings)
     settings:
       imagelist: initial image list)

   setImageList(imagelist)

   gotoSlide(slidenum)

   getCurrentSlidePosition
     returns slidenum
*/


function whSlideshow(settings)
{
  this.container = settings.container;
  this.setImageList(settings.imagelist);

  if(!settings.loadfirstimage)
    this.currentpos = settings.initialpos + 1; //skip ahead an image
  else
    this.currentpos = settings.initialpos;

  this.effect = settings.effect ? settings.effect : 'west';
  this.algorithm = settings.algorithm;
  this.algorithm_factor = settings.algorithm_factor;
  this.animationinterval = settings.animationinterval ? settings.animationinterval : 10;
  this.animationspeed = settings.animationspeed ? settings.animationspeed : 1;
  this.waitinterval = settings.waitinterval ? settings.waitinterval : 1000;
  this.onfinishslide = settings.onfinishslide;

  var localthis = this;
  this.imgload_callback = function(){localthis.gotslideinimage();}
  this.endwait_callback = function(){localthis.endwait();}
  this.interval_callback = function(){localthis.intervalfunc();}

  if(settings.loadfirstimage && this.imagelist.length > 0)
  {
    this.skipnextanimation=true;
    this.startslidein(this.currentpos);
  }
  else
    this.startwait();
}
whSlideshow.prototype.setImageList = function whSlideshow_setImageList(imagelist)
{
  this.imagelist = imagelist;
}
whSlideshow.prototype.startwait = function whSlideshow_startwait()
{
  //console.log('start this.betweenimgtimer');
  this.betweenimgtimer = window.setTimeout(this.endwait_callback, this.waitinterval);
}
whSlideshow.prototype.endwait = function whSlideshow_endwait()
{
  this.betweenimgtimer = null;
  this.startslidein(this.currentpos);
}
whSlideshow.prototype.startslidein = function whSlideshow_startslidein(pos)
{
  this.currentpos = pos % this.imagelist.length;

  var img = document.createElement('img');
  this.incomingcontainer = img;

  img.style.width = this.container.offsetWidth + 'px';
  img.style.height = this.container.offsetHeight + 'px';
  img.style.position = 'absolute';
  img.style.zIndex = 2;

  switch(this.effect) //ADDME share first step calculation with the later step code
  {
    case 'west':
      this.imgwidth = this.container.offsetWidth;

      img.style.top = '0px';
      img.style.left = this.imgwidth + 'px';
      break;

    case 'fade':
      img.style.opacity = 0;
      img.style.filter = 'alpha(opacity=0)';

      img.style.top = '0px';
      img.style.left = '0px';
      break;
  }

  //assuming right-to-left slide
  this.container.insertBefore(this.incomingcontainer, this.container.firstChild);

  img.onload = this.imgload_callback;
  img.src = this.imagelist[this.currentpos].src;
  }
whSlideshow.prototype.getCurrentSlidePosition = function whSlideshow_getCurrentSlidePosition()
{
  return this.currentpos;
}
whSlideshow.prototype.gotslideinimage = function whSlideshow_gotslideinimage()
{
  //console.log('load!');
  if(this.skipnextanimation)
  {
    this.skipnextanimation = false;
    this.currentstep = 1000;
    this.intervalfunc();
    return;
  }

  //now start moving it in
  this.currentstep = 0;
  this.currentloader = window.setInterval(this.interval_callback, this.animationinterval);
}
whSlideshow.prototype.finishanimation = function whSlideshow_finishanimation()
{
  var currentfactor = 1000;
  window.clearInterval(this.currentloader);
  this.currentloader = null;

  //destroy unused nodes. as we inserted ourself before firstChild, we just delete everything else
  while(this.container.childNodes.length>1)
  {
    this.container.removeChild(this.container.lastChild);
  }

  this.incomingcontainer.style.zIndex = 1; //move it to the standard zindex so the next image can move in
  this.incomingcontainer.style.position = 'static';

  return currentfactor;
}
whSlideshow.prototype.update = function whSlideshow_update(factor)
{
  switch(this.effect)
  {
    case 'west':
      this.incomingcontainer.style.left = parseInt( (1 - factor/1000) * this.imgwidth) + 'px';
      break;
    case 'fade':
      this.incomingcontainer.style.opacity = factor / 1000;
      this.incomingcontainer.style.filter = 'alpha(opacity=' + factor / 10 + ')';
      break;
  }
}
whSlideshow.prototype.intervalfunc = function whSlideshow_intervalfunc()
{
  var currentfactor;

  this.currentstep = this.currentstep + this.animationspeed;
  var finished = this.currentstep >= 1000;
  if(!finished)
  {
    switch(this.algorithm)
    {
      case 'sinus':
        //scale 0 .. maxstep to 0 .. 0.5pi
        currentfactor = 1000 * Math.pow(Math.sin( (this.currentstep / 1000.0) * ( 0.5 * Math.PI ) ), this.algorithm_factor);
        break;

      default: //linear
        currentfactor = this.currentstep;
        break;
    }
  }
  else //finished animation
  {
    currentfactor = this.finishanimation();
    if(this.onfinishslide)
      this.onfinishslide(this.currentpos);
  }

  //console.log(currentfactor + ' ' + this.currentstep);
  this.update(currentfactor);
  if(finished)
  {
    this.currentpos = this.currentpos + 1;
    this.startwait();
  }
}
whSlideshow.prototype.abortimageload = function whSlideshow_abortimageload()
{
  window.clearTimeout(this.betweenimgtimer);
  if(this.incomingcontainer)
  {
    //console.log('clear onload');
    this.incomingcontainer.onload = null;
  }
}
whSlideshow.prototype.gotoSlide = function whSlideshow_gotoSlide(pos)
{
  // don't attempt if there are no images in the list
  if (this.imagelist.length == 0)
    return;

  this.abortimageload();
  if(this.currentloader)
    this.finishanimation();

  pos %= this.imagelist.length;

  this.skipnextanimation = true;
  this.startslidein(pos);
}