function Jsslideshow(prefix, msec, max)
// Initialises a slide show - you only need to call this if you want to have more than one on a page, or if you need to change the id-prefix of the elements
{
	this.prefix = prefix ? prefix : "myJsslideshow";
	this.default_interval = msec ? parseInt(msec) : 3500;
	this.selected = 0;
	this.max = max ? parseInt(max) : 12;
	
	this.fadeInDelay = 200; // Setting this to 0 will suppress fade out. Positive values will issue fade in this amount of milliseconds after starting fade out.
	this.opacitySteps = 10; // 5 or 10 steps
	this.fadeInTime = 200; // Total time to fade in in milliseconds
	this.fadeOutTime = 400; // Total time to fade out in milliseconds
	
	this.autoSlide = false;
}

Jsslideshow.prototype.getElem = function(i)
{
	var elem = document.getElementById(this.prefix + ":" + i);
	return elem ? elem : false;
}

Jsslideshow.prototype.getVisible = function()
{
	for (var i = 0; i <= this.max; i++)
	{
		var elem = this.getElem(i);
		if (elem && !hasClass(elem, "hidden"))
		{
			return i;
		}
	}
	return false;
}

Jsslideshow.prototype.exists = function()
{
	for (var i = 0; i <= this.max; i++)
	{
		var elem = this.getElem(i);
		if (elem)
			return true;
	}
	return false;
}

Jsslideshow.prototype.autoStart = function(msec)
// Starts the slideshow
// msec (optional) is the interval in milliseconds. Defaults to the value specified at the top
// NOTE: If the slideshow is already started, it will essentially continue, but with the new msec interval
{
	if (!this.exists())
	{
		return;
	}
	this.selected = this.getVisible();
	
	if (this.timer)
		this.autoStop();

	if (msec)
		this.default_interval = msec;
		
	this.autoSlide = true;
	
	this.autoNext();

}

Jsslideshow.prototype.autoNext = function()
{
	if (this.autoSlide)
		this.timer = setTimeout(this.prefix + ".showNext()", this.default_interval);
}

Jsslideshow.prototype.autoStop = function()
// Stops the slideshow
{
	if (this.timer)
		this.timer = clearTimeout(this.timer);
	this.autoSlide = false;
}

Jsslideshow.prototype.autoToggle = function()
// Starts or stops the slideshow
{
	if (this.autoSlide)
		this.autoStop();
	else
		this.autoStart();
}

Jsslideshow.prototype.showPrev = function(i)
// Shows the previous slide
{
	if (i == undefined)
		i = this.selected;
	else if (i == this.selected)
		return;
		
	if (i == 0)
		i = this.max;
	else
		i--;	
	
	if (!this.getElem(i))
		setTimeout(this.prefix + ".showPrev("+i+")", 10); 
	else
		this.show(i);
}

Jsslideshow.prototype.showNext = function(i)
// Shows the next slide
// Rewinds to the beginning when reaching the end
{
	if (i == undefined)
	{
		if (this.selected == undefined)
			this.selected = this.getVisible();
		i = this.selected;
	}
	else if (i == this.selected)
		return;
		
	if (i == this.max)
		i = 0;
	else
		i++;

	if (!this.getElem(i))
		setTimeout(this.prefix + ".showNext("+i+")", 10); 
	else
		this.show(i);
}

Jsslideshow.prototype.show = function(i)
// Shows a specific slide (fades in)
{
	if (i == this.selected)
		return;
	var elem = this.getElem(i);
	if (elem)
	{	
		if (this.fadeInDelay > 0)
			this.fadeOut(this.selected);
		setTimeout(this.prefix + ".fadeIn("+i+")", this.fadeInDelay);
		
		var nav_elem = document.getElementById("jsslideshow_navbar_select:" + this.selected);
		if (nav_elem)
			removeClass(nav_elem, "selected");
			
		var nav_elem = document.getElementById("jsslideshow_navbar_select:" + i);
		if (nav_elem)
			addClass(nav_elem, "selected");
	}
}

Jsslideshow.prototype.hide = function(i)
// Hides a specific slide (immediately)
{
	var elem = this.getElem(i);
	if (elem)
	{	
		if (!hasClass(elem, "hidden"))
			addClass(elem, "hidden");
	}
}

Jsslideshow.prototype.fadeIn = function(i)
{
	var elem = this.getElem(i);
	if (elem)
	{
		var opacity_match = elem.className.match(/opacity([^\s]+)/i);

		if (!opacity_match) // Starting fade in
		{
			addClass(elem, "opacity0");
			removeClass(elem, "hidden");
			addClass(elem, "on_top");
			this.fadeIn(i);
			return;
		}

		var opacity_class = opacity_match[0];
		var opacity = parseInt(opacity_match[1]);

		if (opacity > 90)	// Ending fade in
		{
			this.hide(this.selected);
	 		this.selected = i;
	 		removeClass(elem, opacity_class);
	 		removeClass(elem, "on_top");
	 		this.autoNext();
			return;
		}

		opacity = opacity + parseInt(100 / this.opacitySteps);
		addClass(elem, "opacity" + opacity);
		removeClass(elem, opacity_class);

		setTimeout(this.prefix + ".fadeIn("+i+")", parseInt(this.fadeInTime / this.opacitySteps));
	}			 	
}

Jsslideshow.prototype.fadeOut = function(i)
{
	var elem = this.getElem(i);
	if (elem)
	{
		var opacity_match = elem.className.match(/opacity([^\s]+)/i);

		if (!opacity_match) // Starting fade out
		{
			addClass(elem, "opacity100");
			this.fadeOut(i);
			return;
		}

		var opacity_class = opacity_match[0];
		var opacity = parseInt(opacity_match[1]);
		
		if (opacity < 10)
		{
			removeClass(elem, opacity_class);
			this.hide(i);
			return;
		}

		opacity = opacity - parseInt(100 / this.opacitySteps);
		addClass(elem, "opacity" + opacity);
		removeClass(elem, opacity_class);

		setTimeout(this.prefix + ".fadeOut("+i+")", parseInt(this.fadeOutTime / this.opacitySteps));
	}			 	
}

myJsslideshow = new Jsslideshow("myJsslideshow");