function  slideshow(inImageTransition, inDuration, inSustain, inRandFlag) {


  var itsSlideIndex=0;
  var itsSlides=new Array(20);
  var itsNumOfSlides=0;
  var isInPlay=false;

  var itsSlideshowTimeoutID;
  var itsIndexUpdateTimeoutID;
  var itsTextUpdateTimeoutID;
  var self = this;

  //need these globals because setInterval fails to pass vars to callback func in IE?
  var itsTextIndex=0;
  var itsIndexStep=0;

  function getNextIndex(inStep) {
    var theIndex=itsSlideIndex+inStep;

    if(typeof inRandFlag != 'undefined' && inRandFlag == 1)
         theIndex=Math.round(Math.random()*(itsNumOfSlides-1));

    if(theIndex<0)
      theIndex=itsNumOfSlides-1;
    if(theIndex>=itsNumOfSlides)
      theIndex=0;

    return theIndex;
  };

  this.updateSlideIndex =  function() {
    itsSlideIndex=getNextIndex(itsIndexStep);
  };

  this.showSlide =  function() {
    itsSlides[itsTextIndex].show()
  };


  this.rotate = function() {
    self.playNextSlide(1);
    itsSlideshowTimeoutID=window.setTimeout(self.rotate,inSustain*1000);
  };

  this.addSlide = function(inSlide) {
    itsSlides[itsNumOfSlides]=inSlide;
    itsNumOfSlides++;

  };

  this.clearSlides = function() {
    itsNumOfSlides=0;
    itsSlides=new Array();
  };


    this.playNextSlide = function(inStep) {
    itsTextIndex=getNextIndex(inStep);
    itsIndexStep=inStep;   //set new slideshow direction
    //need a phase shift for showing the text and updating the index (sync for next and prev buttons)
    itsSlides[getNextIndex(inStep)].transition(inImageTransition, inDuration); // NOW uses callbak to update index and text part.
    //itsTextUpdateTimeoutID=window.setTimeout(self.showSlide,inDuration*500);
   // itsIndexUpdateTimeoutID=window.setTimeout(self.updateSlideIndex,inDuration*1300);//small lag after end of transition to update the slideshow index
  };

  this.displayNextSlide = function(inStep) {
    window.clearTimeout(itsSlideshowTimeoutID);
    window.clearTimeout(itsTextUpdateTimeoutID);
    window.clearTimeout(itsIndexUpdateTimeoutID);
    //preserve slideshow direction
    tmp=itsIndexStep;
    itsIndexStep=inStep;
    self.updateSlideIndex(inStep);
    itsIndexSep=tmp;
    itsSlides[itsSlideIndex].stop(inImageTransition);
    if(isInPlay)
      itsSlideshowTimeoutID=window.setTimeout(self.rotate,inSustain*1000);
  };



  this.stop = function() {
    window.clearTimeout(itsSlideshowTimeoutID);
   isInPlay=false;
  };

  this.start = function() {
    itsSlides[itsSlideIndex].stop(inImageTransition);
    inImageTransition.setCallbacks(self.showSlide,self.updateSlideIndex);
    itsSlideshowTimeoutID=window.setTimeout(self.rotate,inSustain*500);
    isInPlay=true;
  };


  this.toggleStartStop = function(inImgObj,inImgSrcStart,inImgSrcStop) {
	if(isInPlay)
	   self.stop();
	else
	   self.start();

	if(inImgObj!=null)
	  if(isInPlay)
		inImgObj.src=inImgSrcStop;
	  else
 		inImgObj.src=inImgSrcStart;
  };

};


function genericSlide() {

  this.itsNumOfElements=0;
  this.itsElements = new Array();
  var self=this;

  this.add = function(inElement) {
    self.itsElements[self.itsNumOfElements]= inElement;
    self.itsNumOfElements++;
  };

  this.getElement = function(i) {
   return  self.itsElements[i];
  };

 this.clear = function() {
    self.itsElements= new Array();
    self.itsNumOfElements=0;
  };

  this.show = function(inTransition,inDuration) {
    var i;
    for (i=0;i<self.itsNumOfElements;i++)
      self.itsElements[i].show(inTransition,inDuration);
  };

  this.stop = function(inTransition) {
    var i;
    for (i=0;i<self.itsNumOfElements;i++)
      self.itsElements[i].stop(inTransition);
  };

  this.transition = function(inTransition, inDuration) {
    var i;
    for (i=0;i<self.itsNumOfElements;i++)
      self.itsElements[i].transition(inTransition,inDuration);
 };

};


//Convenience class to make three slide elements: text, href, image
function imageCaptionLinkSlide (inHTMLObjects,inValues) {

  this.caption= new Object();
  this.hlink=new Object();
  this.image=new Object();

  this.caption.obj=inHTMLObjects[0];
  this.hlink.obj=inHTMLObjects[1];
  this.image.obj=inHTMLObjects[2];

  this.caption.value=inValues[0];
  this.hlink.value=inValues[1];
  this.image.value=inValues[2];

  var self = this;

  //Non-transition show methods
  this.caption.show = function() {
    self.caption.obj.innerHTML=self.caption.value;
  };

  this.hlink.show = function() {
    self.hlink.obj.href=self.hlink.value;
  };

  this.image.show = function() {
  };

  //Transition methods
  this.caption.transition = function() {
  };

  this.hlink.transition = function() {
  };
  this.image.transition = function(inTransition, inDuration) {
    inTransition.start(self.image.value, self.image.obj, inDuration, self.caption.value);
  };

  //Stop methods
  this.caption.stop = function() {
    self.caption.show();
  };
  this.hlink.stop = function() {
    self.hlink.show();
  };

  this.image.stop = function(inTransition) {
    inTransition.stop(self.image.value, self.image.obj);
  };

  //Add to the generic slide
  this.addToGenericSlide = function(inGenericSlide) {
    inGenericSlide.add(self.caption);
    inGenericSlide.add(self.hlink);
    inGenericSlide.add(self.image);
  };

};


//Convenience class to make three slide elements: text, href, image
function imageTitleCaptionLinkSlide (inHTMLObjects,inValues) {

  this.title= new Object();
  this.caption= new Object();
  this.hlink=new Object();
  this.hlink2=new Object();
  this.image=new Object();
  this.background=new Object();

  this.title.obj=inHTMLObjects[0];
  this.caption.obj=inHTMLObjects[1];
  this.hlink.obj=inHTMLObjects[2];
  this.hlink2.obj=inHTMLObjects[3];
  this.image.obj=inHTMLObjects[4];
  this.background.obj=inHTMLObjects[5];

  this.title.value=inValues[0];
  this.title.color=inValues[1];
  this.caption.value=inValues[2];
  this.caption.color=inValues[3];
  this.hlink.value=inValues[4];
  this.hlink2.value=inValues[5];
  this.image.value=inValues[6];
  this.background.color=inValues[7];

  var self = this;

  //Non-transition show methods
  this.background.show = function() {
    self.background.obj.bgColor=self.background.color;
  };

 this.title.show = function() {
    self.title.obj.innerHTML=self.title.value;
    self.title.obj.color=self.title.color;
  };

  this.caption.show = function() {
    self.caption.obj.innerHTML=self.caption.value;
    self.caption.obj.color=self.caption.color;
  };

  this.hlink.show = function() {
    self.hlink.obj.href=self.hlink.value;
  };

   this.hlink2.show = function() {
    self.hlink2.obj.href=self.hlink2.value;
  };

  this.image.show = function() {
  };

  //Transition methods
  this.background.transition= function() {};

  this.title.transition = function() {
  };

  this.caption.transition = function() {
  };

  this.hlink.transition = function() {
  };
  this.hlink2.transition = function() {
  };
  this.image.transition = function(inTransition, inDuration) {
    inTransition.start(self.image.value, self.image.obj, inDuration, self.caption.value);
  };

  //Stop methods


 this.title.stop = function() {
    self.title.show();
 };
  this.caption.stop = function() {
    self.caption.show();
  };
  this.hlink.stop = function() {
    self.hlink.show();
  };
  this.hlink2.stop = function() {
    self.hlink2.show();
  };

  this.image.stop = function(inTransition) {
   inTransition.stop(self.image.value, self.image.obj);
  };

 this.background.stop = function() {
    self.background.show();
 };


  //Add to the generic slide
  this.addToGenericSlide = function(inGenericSlide) {
    inGenericSlide.add(self.title);
    inGenericSlide.add(self.caption);
    inGenericSlide.add(self.hlink);
    inGenericSlide.add(self.hlink2);
    inGenericSlide.add(self.image);
    inGenericSlide.add(self.background);
  };
};




function imageSlide (inHTMLObjects,inValues) {

  this.image=new Object();
  this.image.obj=inHTMLObjects[0];
  this.image.value=inValues[0];

  var self = this;

  //Non-transition show methods
  this.image.show = function() {
  };

  //Transition methods
 this.image.transition = function(inTransition, inDuration) {
    inTransition.start(self.image.value, self.image.obj, inDuration, "slideshow");
  };

  this.image.stop = function(inTransition) {
    inTransition.stop(self.image.value, self.image.obj);
  };

  //Add to the generic slide
  this.addToGenericSlide = function(inGenericSlide) {
    inGenericSlide.add(self.image);
  };

};


function imageCaptionImageSlide (inHTMLObjects,inValues) {


  this.image=new Object();
  this.caption= new Object();
  this.image2=new Object();

  this.image.obj=inHTMLObjects[0];
  this.caption.obj=inHTMLObjects[1];
  this.image2.obj=inHTMLObjects[2];

  this.image.value=inValues[0];
  this.caption.value=inValues[1];
  this.image2.value=inValues[2];

  var self = this;

  //Non-transition show methods
  this.caption.show = function() {
    self.caption.obj.innerHTML=self.caption.value;
  };

  this.image2.show = function() {
    self.image2.obj.src=self.image2.value;
  };

  this.image.show = function() {
  };

  //Transition methods
  this.caption.transition = function() {
  };

  this.image2.transition = function() {
  };
  this.image.transition = function(inTransition, inDuration) {
    inTransition.start(self.image.value, self.image.obj, inDuration, self.caption.value);
  };

  //Stop methods
  this.caption.stop = function() {
    self.caption.show();
  };
  this.image2.stop = function() {
    self.image2.show();
  };

  this.image.stop = function(inTransition) {
    inTransition.stop(self.image.value, self.image.obj);
  };

  //Add to the generic slide
  this.addToGenericSlide = function(inGenericSlide) {
    inGenericSlide.add(self.caption);
    inGenericSlide.add(self.image2);
    inGenericSlide.add(self.image);
  };

};


