function  slideshow(inImageTransition, inDuration, inSustain, inRandFlag)
{
	var self = this;
	var itsSlideIndex = 0;
	var itsSlides = new Array(20);
	var itsNumOfSlides = 0;
	var isInPlay = false;
	var itsSlideshowTimeoutID;
	var itsIndexUpdateTimeoutID;
	var itsTextUpdateTimeoutID;

	//need these globals because setInterval fails to pass vars to callback 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);
		this.startInterval = setInterval(this.doStart,500);
	};

	this.doStart = function()	{
		var isAllReady = true;
		for (var i=0; i < itsSlides.length && typeof itsSlides[i] == 'object'; i++)
		{
			if (!itsSlides[i].isReady())
				isAllReady = false;
		}
		if(isAllReady) {
			inImageTransition.setCallbacks(self.showSlide,self.updateSlideIndex);
			itsSlideshowTimeoutID=window.setTimeout(self.rotate,inSustain*500);
			isInPlay=true;
			clearInterval(self.startInterval);
		}
	};

	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.isReady = function()
	{
		var isAllReady = true;
		for (var i=0; i < self.itsNumOfElements; i++)
			if (!self.itsElements[i].isReady())
				isAllReady = false;

		return isAllReady;
	};

	this.transition = function(inTransition, inDuration) {
		var i;
		for (i=0;i<self.itsNumOfElements;i++)
			self.itsElements[i].transition(inTransition,inDuration);
	};

};



//Helper class to make three slide elements: text, href, image
function imageTitleCaptionLinkSlide (inHTMLObjects,inValues) {

	var self = this;
	this.isImageLoaded = false;
	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.imageBuffer = new Image();
	this.imageBuffer.onload = function() {self.isImageLoaded = true;};
	this.imageBuffer.src = inValues[6];
	this.background.color=inValues[7];


	//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() {
	};


	this.background.isReady = function() {
		return true;
	};

	this.title.isReady = function() {
		return true;
	};

	this.caption.isReady = function() {
		return true;
	};

	this.hlink.isReady = function() {
		return true;
	};

	this.hlink2.isReady = function() {
		return true;
	};

	this.image.isReady = function() {
		return self.isImageLoaded;
	};



	//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.imageBuffer.src, 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.imageBuffer.src, 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) {

	var self = this;
	this.isImageLoaded = false;
	this.image=new Object();
	this.image.obj=inHTMLObjects[0];
	this.imageBuffer = new Image();
	this.imageBuffer.onLoad = function() {self.isImageLoaded = true;};
	this.imageBuffer.src = inValues[0];

	//Non-transition show methods
	this.image.show = function() {
	};

	this.image.isReady = function() {
		return self.isImageLoaded;
	};

	//Transition methods
	this.image.transition = function(inTransition, inDuration) {
		var i=0;
		inTransition.start(self.imageBuffer.src, self.image.obj, inDuration, "slideshow");
	};

	this.image.stop = function(inTransition) {
		inTransition.stop(self.imageBuffer.src, self.image.obj);
	};

	//Add to the generic slide
	this.addToGenericSlide = function(inGenericSlide) {
		inGenericSlide.add(self.image);
	};

};


function imageCaptionImageSlide (inHTMLObjects,inValues) {

	var self = this;
	this.isImageLoaded = false;

	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.imageBuffer = new Image();
	this.imageBuffer.onload = function() {self.isImageLoaded = true;};
	this.imageBuffer.src = inValues[0];
	this.caption.value=inValues[1];
	this.image2.value=inValues[2];


	//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() {
	};

	this.caption.isReady = function() {
		return true;
	};

	this.image2.isReady = function() {
		return true;
	};

	this.image.isReady = function() {
		self.isImageLoaded;
	};

	//Transition methods
	this.caption.transition = function() {
	};

	this.image2.transition = function() {
	};
	this.image.transition = function(inTransition, inDuration) {
		inTransition.start(self.imageBuffer.src, 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.imageBuffer.src, self.image.obj);
	};

	//Add to the generic slide
	this.addToGenericSlide = function(inGenericSlide) {
		inGenericSlide.add(self.caption);
		inGenericSlide.add(self.image2);
		inGenericSlide.add(self.image);
	};

};

