function billboardSlider(id) {
	// Constructor

	// Set id
	if (id) this.slideshowID=id;
	
	// Create self reference (needed for setTimeout())
	if (!billboardSlider.instances) billboardSlider.instances=[];
	this._index=billboardSlider.instances.length;
	billboardSlider.instances[this._index]=this;
	
}

billboardSlider.prototype={
	
	// Properties
	// Configuration:
	slideshowID: "slideshow",
	slideDuration: 6000,
	slideTransitionDuration: 1250,
	slideHeight: 0,
	slideIndex: 0,
	slideCount: 0,
	timer: null,
	autoplay: true,
	
	// For internal use only:
	_index: null,
	_isPlaying: false,
	
	// Methods
	init: function(){
	
		// Set some properties
		this.slideHeight=$("#"+this.slideshowID+" #slides").innerHeight();
		this.slideCount=$("#"+this.slideshowID+" #slides DIV.slide").size();
		
		// Store instance
		var instance=this;
		
		// Position
		$("#"+this.slideshowID+" #slides DIV.slide").each(function(index){
			$(this).css({
				"position"	: "absolute",
				"left"		: "0px",
				"top"		: index*instance.slideHeight+"px"
			});
		});
		
		// Triggers
		$("#"+this.slideshowID+" #slidenavs DIV.slidenav")
			.each(function(index){
				$(this).click(function(){
					instance.showSlide(index+1);
					instance.pause();
				});
			});
		
		// Begin
		this.showSlide(this.slideIndex+1);
		if (this.autoplay==true) this.play();
	
	},
	
	startTimer: function(){
		// This is a timeout, so that the transition time is not counted as part of the 
		// slide duration time. When the transition animation completes, it runs this
		// function again, thus mimicking setInterval(), but preventing the first slide
		// from d_isPlaying longer than the rest (since it gets no opening transition).
		// Also, we must clear the timer before setting it, in case it's already running
		// which occurs, for example, on init where this.showSlide() executes the
		// jQuery .animate() callback after this.play(), the next instruction, fires.
		// Without clearing the timer, it would cause a reduction of the next slide's
		// duration if you click() a navigation item before the initial slide finishes!
		this.clearTimer();
		this.timer=setTimeout("billboardSlider.instances["+this._index+"].showNextSlide()", this.slideDuration);
	},
	
	clearTimer: function(){
		clearTimeout(this.timer);
		this.timer=null;
	},
	
	play: function() {
		this._isPlaying=true;
		this.startTimer();
	},
	
	pause: function() {
		this._isPlaying=false;
		this.clearTimer();
	},
	
	showNextSlide: function(){
		var nextSlide=this.slideIndex+1;
		if (nextSlide > this.slideCount-1) nextSlide=0;
		this.showSlide(nextSlide+1);
	},
	
	showSlide: function(number){
	
		// Stop timer
		this.clearTimer();
		
		// Init
		var index=number-1;
		var instance=this;
		var top=0-index*this.slideHeight;

		// Animate
		$("#"+this.slideshowID+" #canvas").stop();
		$("#"+this.slideshowID+" #canvas").animate(
			{
				top: top+"px"
			},
			{
				duration: this.slideTransitionDuration, 
				easing: 'easeInOutCubic',
				complete: function(){
					if (instance._isPlaying) instance.startTimer();
				}
			}
		);

		// Mark navigation
		$("#"+this.slideshowID+" #slidenavs DIV.slidenav").removeClass("selected");
		$("#"+this.slideshowID+" #slidenavs DIV.slidenav").eq(index).addClass("selected");
		
		// Set
		this.slideIndex=index;
		
	}
	
};
