function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

function Slideshow()
{
  /* Settings */
  this.duration=750;
  this.steps=50;
  this.slideDuration=4000;
  this.loadingTimeout=500;
  this.photoUrls=new Array();
  this.loop = true;
  this.elementBaseName="";
  this.ref = "";
  this.name = "";
  this.fadeOver = false;

  /* Working variables */
  this.currentPhoto = -1;
  this.nextPhotoIndex = 0;

  this.currentImage = "picture1";

  this.fadeInElement = null;
  this.fadeOutElement = null;
  this.fadeInElementOpacity = 0;
  this.fadeOutElementOpacity = 1;

  this.changeInProgress = false;
  this.runSlideShow = false;
  this.nextTask = null;
  this.nextTaskIn = 0;
  this.slideshowPhoto1 = null;
  this.slideshowPhoto2 = null;
  this.nextPhotoSrc = null;

  /* Methods */
  this.startStopSlideShow = function()
  {
    if ( !this.runSlideShow )
    {
      timeout = this.slideDuration;
      if (this.currentPhoto == this.photoUrls.length - 1)
      {
        this.gotoPhoto(0);
      }
      this.runSlideShow = true;
      this.nextSlide();
      if (document.getElementById(this.elementBaseName+"slideshow") != null) 
      {
        document.getElementById(this.elementBaseName+"slideshow").innerHTML="Pause Slideshow";
      }
    }
    else
    {
      this.runSlideShow = false;
      if (document.getElementById(this.elementBaseName+"slideshow") != null) 
      {
        document.getElementById(this.elementBaseName+"slideshow").innerHTML="Continue Slideshow";
      }
    }
  }

  this.nextSlide = function()
  {
    if (!this.runSlideShow) return;
    if ((this.currentPhoto < this.photoUrls.length - 1 || this.loop) && this.runSlideShow == true)
    {
      this.nextTask = this.ref+".nextSlide.apply("+this.ref+")";
      this.nextTaskIn = this.slideDuration;
    }
    else if ( this.runSlideShow == true && this.currentPhoto == this.photoUrls.length - 1 )
    {
      if (document.getElementById(this.elementBaseName+"slideshow") != null) 
      {
        document.getElementById(this.elementBaseName+"slideshow").innerHTML="Restart Slideshow";
      }
    }
    this.nextPhoto();
  }

  this.gotoPhoto = function(photoIndex)
  {
    //alert( "GotoPhoto hit ref "+this.ref );
    if (this.changeInProgress) return;
    this.currentPhoto = photoIndex;
    this.nextPhotoIndex = this.currentPhoto + 1;
    this.swapImages();
   
    if (document.getElementById(this.elementBaseName+"link"+this.currentPhoto) != null) 
    {
      document.getElementById(this.elementBaseName+"link"+this.currentPhoto).className = "index current";
    }
    for (x = 0; x<this.photoUrls.length; x++)
    {
      if (x != this.currentPhoto)
      {
        if (document.getElementById(this.elementBaseName+"link"+x) != null) 
        {
          document.getElementById(this.elementBaseName+"link"+x).className = "index";
        }
      }
    }
  }

  this.nextPhoto = function()
  {
    //alert( "NextPhoto hit ref "+this.ref );
    if (this.currentPhoto < this.photoUrls.length - 1)
    {
      this.gotoPhoto( this.currentPhoto + 1 );
    }
    else if (this.loop)
    {
      this.gotoPhoto( 0 );
    }
  }

  this.prevPhoto = function()
  {
    //alert( "PrevPhoto hit ref "+this.ref );
    if (this.currentPhoto > 0)
    {
      this.gotoPhoto( this.currentPhoto - 1 );
    }
  }

  this.swapImages = function()
  {
    //alert( "SwapImages hit ref "+this.ref );
    this.changeInProgress = true;
    if (this.currentImage == "picture1")
    {
      this.fadeOutElement = this.slideshowPhoto1; //document.getElementById("picture1");
      this.slideshowPhoto1 = document.createElement("img");
      this.slideshowPhoto1.className = "slideshowPhoto";
      this.slideshowPhoto1.style.display = "none";
      this.slideshowPhoto1.src = this.photoUrls[this.nextPhotoIndex];
      if (this.slideshowPhoto2 == null || this.slideshowPhoto2.src != this.photoUrls[this.currentPhoto])
      {
        this.slideshowPhoto2 = document.createElement("img");
        this.slideshowPhoto2.src = this.photoUrls[this.currentPhoto];
        this.slideshowPhoto2.className = "slideshowPhoto";
        this.slideshowPhoto2.style.display = "none";
      }
      document.getElementById(this.elementBaseName + "pictureplaceholder1").appendChild( this.slideshowPhoto2 );
      this.fadeInElement = this.slideshowPhoto2; // document.getElementById("picture2");
      this.currentImage = "picture2";
    }
    else
    {
      this.fadeOutElement = this.slideshowPhoto2; //document.getElementById("picture1");
      this.slideshowPhoto2 = document.createElement("img");
      this.slideshowPhoto2.className = "slideshowPhoto";
      this.slideshowPhoto2.style.display = "none";
      this.slideshowPhoto2.src = this.photoUrls[this.nextPhotoIndex];
      if (this.slideshowPhoto1 == null || this.slideshowPhoto1.src != this.photoUrls[this.currentPhoto])
      {
        this.slideshowPhoto1 = document.createElement("img");
        this.slideshowPhoto1.src = this.photoUrls[this.currentPhoto];
        this.slideshowPhoto1.className = "slideshowPhoto";
        this.slideshowPhoto1.style.display = "none";
      }
      document.getElementById(this.elementBaseName + "pictureplaceholder1").appendChild( this.slideshowPhoto1 );
      this.fadeInElement = this.slideshowPhoto1; // document.getElementById("picture2");
      this.currentImage = "picture1";
    }
    if (this.fadeOutElement != null)
    {
      this.fadeOut();
      window.setTimeout( this.ref+".fadeIn.apply("+this.ref+")", this.duration);
    }
    else
    {
      this.fadeIn();
    }
  }

  this.fadeIn = function(){
    if (this.fadeOutElement != null && this.fadeOver == false)
    {
      this.fadeOutElement.style.display = "none";
    }
    if (!this.fadeInElement.complete)
    {
      document.getElementById(this.elementBaseName+"loadingSign").style.display = "block";
      this.fadeInElement.style.display = "none";
      window.setTimeout( this.ref+".fadeIn.apply("+this.ref+")", this.loadingTimeout);
      return;
    }
    else
    {
      document.getElementById(this.elementBaseName+"loadingSign").style.display = "none";
      this.setOpacityIn(0);
      this.fadeInElement.style.display = "block";
      this.fadeInElement.style.width = this.fadeInElement.width;
      this.fadeInElement.style.height = this.fadeInElement.height;
      this.fadeInElement.style.position = "absolute";
      this.fadeInElement.style.top = "0px";
      var parentWidth = document.getElementById(this.elementBaseName + "pictureplaceholder1").offsetWidth;
      //alert ( document.getElementById(this.elementBaseName + "pictureplaceholder1").parentNode.innerHTML );
      //alert( "P:" + parentWidth +" E: " +this.fadeInElement.width +" Es: "+ this.fadeInElement.style.width );
      //alert( ((parentWidth - this.fadeInElement.width)/2) + "px" );
      this.fadeInElement.style.left = ((parentWidth - this.fadeInElement.width)/2) + "px";
      //this.fadeInElement.style.marginLeft = (0 - (this.fadeInElement.width / 2)) + "px";
    }
    for (i = 0; i <= 1; i += (1 / this.steps)) {
      window.setTimeout( this.ref+".setOpacityInStep.apply("+this.ref+")", i * this.duration);
    }
    window.setTimeout( this.ref+".setOpacityInFinish.apply("+this.ref+")", this.duration);
    if (this.nextTask != null)
    {
      window.setTimeout(this.nextTask, this.nextTaskIn);
      this.nextTask = null;
    }
    window.setTimeout( this.ref+".unsetChangeInProgress.apply("+this.ref+")", this.duration);
  }
  
  this.unsetChangeInProgress = function()
  {
    this.changeInProgress = false;
  }

  this.fadeOut = function() 
  {
    if ( this.fadeOver == true )
    {
      return;
    }
    
    this.setOpacityOut(1);
    for (i = 0; i <= 1; i += (1 / this.steps)) {
      window.setTimeout( this.ref+".setOpacityOutStep.apply("+this.ref+")", i * this.duration);
    }
    window.setTimeout( this.ref+".setOpacityOutFinish.apply("+this.ref+")", this.duration);
  }

  /* set the opacity of the element (between 0.0 and 1.0) */
  this.setOpacityInStep = function()
  {
    this.setOpacityIn( this.fadeInElementOpacity + (1 / this.steps) );
  }

  this.setOpacityInFinish = function()
  {
    this.setOpacityIn( 1 );
  }

  this.setOpacityIn = function(level) {
    this.fadeInElementOpacity = level;
    this.fadeInElement.style.opacity = level;
    this.fadeInElement.style.MozOpacity = level;
    this.fadeInElement.style.KhtmlOpacity = level;
    this.fadeInElement.style.filter = "alpha(opacity=" + (level * 100) + ");";
  }

  this.setOpacityOutStep = function()
  {
    this.setOpacityOut( this.fadeOutElementOpacity - (1 / this.steps) );
  }

  this.setOpacityOutFinish = function()
  {
    this.setOpacityOut( 0 );
  }

  this.setOpacityOut = function(level) 
  {
    this.fadeOutElementOpacity = level;
    this.fadeOutElement.style.opacity = level;
    this.fadeOutElement.style.MozOpacity = level;
    this.fadeOutElement.style.KhtmlOpacity = level;
    this.fadeOutElement.style.filter = "alpha(opacity=" + (level * 100) + ");";
  }
}
