var oTransitions = {
	NONE: 1,
	FADE: 2,
	SLIDEL: 4,
	SLIDER: 8,
	SLIDED: 16,
	SLIDEU: 32
};

function oSlideshow( id, album, width, height, duration, transition )
{
	// initialize the member function references for the class prototype
	if(typeof(_oSlideshow_prototype_called) == 'undefined')
	{
		// set oSlideshow prototypes as defined
		_oSlideshow_prototype_called = true;
		
		// set up oSlideshow prototype methods
		oSlideshow.prototype.ele				= ele ;
		oSlideshow.prototype.resize				= resize ;
		oSlideshow.prototype.setEvent			= setEvent ;
		oSlideshow.prototype.clearEvents		= clearEvents ;
		oSlideshow.prototype.moveCursor			= moveCursor ;
		oSlideshow.prototype.setup				= setup ;
		
		oSlideshow.prototype.start				= start ;
		oSlideshow.prototype.stop				= stop ;
		oSlideshow.prototype.play				= play ;
		oSlideshow.prototype.pause				= pause ;
		
		oSlideshow.prototype.next				= next ;
		oSlideshow.prototype.prev				= prev ;
	}
	
	this.id				= id;
	this.album			= album;
	this.width			= width;
	this.height			= height;
	this.duration		= duration;
	this.transition		= transition;
	
	this.div			= null;
	this.window			= null;
	this.bullpen		= null;
	this.titleCell		= null;
	this.slideCell		= null;
	this.buttons		= null;
	this.playButton		= null;
	
	this.errorStatus	= false;
	this.playing		= false;
	
	this.images			= Array();
	this.cursor			= -1;
	this.image			= null;
	this.prevImage		= null;
	this.nextImage		= null;
	
	this.setup();
	
	function ele(id)
	{
		return document.getElementById(id);
	}
	
	function resize(width, height)
	{
		var x = new Object();
		x.width = Number(width);
		x.height = Number(height);
		x.top = 0;
		x.left = 0;
		
		if(x.width > this.width)
		{
			x.height = Math.round( height * (this.width / width) );
			x.width = this.width;
		}
		
		if(x.height > this.height)
		{
			x.width = Math.round( width * (this.height / height) );
			x.height = this.height;
		}
		
		if(this.height > x.height)
			x.top = Math.round( (this.height / 2) - (x.height / 2) );
		
		if(this.width > x.width)
			x.left = Math.round( (this.width / 2) - (x.width / 2) );
		
		return x;
	}
	
	function setEvent(element, e, action)
	{
		if(!element.events)
			element.events = Array();
		if(!element.events[e])
			element.events[e] = Array();
		element.events[e].push( action );
		
		if( element.addEventListener )
			element.addEventListener( e, action, false );
		else if( element.attachEvent )
			element.attachEvent( 'on' + e, action );
		else
			eval( 'element.on' + e + ' = action ;' );
	}
	
	function clearEvents(element, e)
	{
		if(!element.events || !element.events[e])
			return;
		
		if( element.removeEventListener )
		{
			for(var i in element.events[e])
				element.removeEventListener( e, element.events[e][i], false );
		}
		else if( element.detachEvent )
		{
			for(var i in element.events[e])
				element.detachEvent( 'on' + e, element.events[e][i] );
		}
		else
			eval( 'element.on' + e + ' = null ;' );
	}
	
	function moveCursor(by)
	{
		this.cursor += by;
		if(this.cursor >= this.images.length)
			this.cursor = 0;
		else if(this.cursor < 0)
			this.cursor = this.images.length - 1;
	}
	
	function setup()
	{
		document.write('<div id="oSlideshow_container_' + this.id + '" class="oSlideshow_container" style="position:relative; width:' + this.width + 'px;"></div>');
		this.div = this.ele('oSlideshow_container_' + this.id);
		var thisReference = this;
		
		this.window = document.createElement('div');
		this.window.setAttribute('id', 'oSlideshow_window_' + this.id);
		this.window.className = 'oSlideshow_window';
		this.div.appendChild(this.window);
		this.window.style.width = this.width + 'px';
		this.window.style.height = this.height + 'px';
		this.window.style.maxWidth = this.width + 'px';
		this.window.style.maxHeight = this.height + 'px';
		this.window.style.position = 'relative';
		this.window.style.overflow = 'hidden';
		this.window.innerHTML = '<div style="padding-top:' + ((this.height / 2) - 8) + 'px; text-align:center; height:100%;"><img src="' + bw_url + '/art/loadingcircle.gif" /></div>';
		
		this.buttons = document.createElement('div');
		this.buttons.setAttribute('id', 'oSlideshow_buttons_' + this.id);
		this.buttons.className = 'oSlideshow_controller';
		this.buttons.style.position = 'relative';
		this.div.appendChild(this.buttons);
		
		this.bullpen = document.createElement('div');
		this.bullpen.style.display = 'none';
		this.div.appendChild(this.bullpen);
		
		var table = document.createElement('table');
		table.setAttribute('cellPadding', '0');
		table.setAttribute('cellSpacing', '0');
		table.setAttribute('border', '0');
		table.setAttribute('width', this.width);
		this.buttons.appendChild(table);
		
		var tbody = document.createElement('tbody');
		table.appendChild(tbody);
		
		var tr = document.createElement('tr');
		tbody.appendChild(tr);
		
		var width1 = Math.ceil((this.width - 125) / 2);
		var width2 = this.width - 125 - width1;
		
		var td = document.createElement('td');
		td.setAttribute('width', width1);
		td.className = 'oSlideshow_titleCell';
		tr.appendChild(td);
		
		this.titleCell = document.createElement('div');
		this.titleCell.style.width = (width1 - 10) + 'px';
		this.titleCell.style.maxWidth = (width1 - 10) + 'px';
		this.titleCell.style.overflow = 'hidden';
		td.appendChild(this.titleCell);
		
		this.buttons = document.createElement('td');
		this.buttons.className = 'oSlideshow_buttons';
		this.buttons.style.textAlign = 'center';
		tr.appendChild(this.buttons);
		
		var button1 = document.createElement('img');
		button1.src = bw_url + '/mod/ophoto/art/slideshow_previous.png';
		button1.style.cursor = 'pointer';
		button1.style.margin = '0px';
		button1.title = 'Click here to go to the previous slide.';
		this.buttons.appendChild(button1);
		this.buttons.appendChild( document.createTextNode(' ') );
		
		this.playButton = document.createElement('img');
		this.playButton.src = bw_url + '/mod/ophoto/art/slideshow_play.png';
		this.playButton.style.cursor = 'pointer';
		this.playButton.style.margin = '0px';
		this.buttons.appendChild(this.playButton);
		this.buttons.appendChild( document.createTextNode(' ') );
		
		var button2 = document.createElement('img');
		button2.src = bw_url + '/mod/ophoto/art/slideshow_next.png';
		button2.style.cursor = 'pointer';
		button2.style.margin = '0px';
		button2.title = 'Click here to go to the next slide.';
		this.buttons.appendChild(button2);
		
		this.slideCell = document.createElement('td');
		this.slideCell.setAttribute('width', width2);
		this.slideCell.className = 'oSlideshow_slideCell';
		tr.appendChild(this.slideCell);
		
		var ajax = new bwAjax();
		
		ajax.setGetHandler( function(response) {
			var result = bwAjax_unserialize(response);
			
			if(result == null || result === false || result.length == 0)
			{
				thisReference.window.innerHTML = 'The album you are trying to view either doesn\'t exist or you don\'t have permission to view it.';
				thisReference.errorStatus = true;
			}
			else
			{
				thisReference.images = result;
				
				var row = thisReference.images[ 0 ];
				var x = thisReference.resize( row.display_width, row.display_height );
				
				thisReference.nextImage = document.createElement('img');
				thisReference.nextImage.setAttribute('src', row.url);
				thisReference.nextImage.width = x.width;
				thisReference.nextImage.height = x.height;
				thisReference.nextImage.style.width = x.width + 'px';
				thisReference.nextImage.style.height = x.height + 'px';
				thisReference.nextImage.style.position = 'absolute';
				thisReference.nextImage.style.top = x.top + 'px';
				thisReference.nextImage.style.left = x.left + 'px';
				thisReference.bullpen.appendChild(thisReference.nextImage);
				
				row = thisReference.images[ thisReference.images.length - 1 ];
				x = thisReference.resize( row.display_width, row.display_height );
				
				thisReference.prevImage = document.createElement('img');
				thisReference.prevImage.setAttribute('src', row.url);
				thisReference.prevImage.width = x.width;
				thisReference.prevImage.height = x.height;
				thisReference.prevImage.style.width = x.width + 'px';
				thisReference.prevImage.style.height = x.height + 'px';
				thisReference.prevImage.style.position = 'absolute';
				thisReference.prevImage.style.top = x.top + 'px';
				thisReference.prevImage.style.left = x.left + 'px';
				thisReference.bullpen.appendChild(thisReference.prevImage);
				
				thisReference.image = thisReference.prevImage;
				
				thisReference.setEvent(button1, 'click', function() { thisReference.prev(); });
				thisReference.setEvent(button2, 'click', function() { thisReference.next(); });
				
				thisReference.playing = true;
				thisReference.timeout = window.setTimeout('_oSlideshow_' + thisReference.id + '.next();', 2000);
				
				thisReference.playButton.src = bw_url + '/mod/ophoto/art/slideshow_pause.png';
				thisReference.playButton.title = 'Click here to pause the slideshow.';
				thisReference.setEvent(thisReference.playButton, 'click', function() { thisReference.pause(); });
			}
		} );
		ajax.setErrorHandler( function(error) {
			thisReference.errorStatus = true;
			alert(error);
		} );
		ajax.sendRequest( bw_url + '/mod/ophoto/slideshow.php?SID=' + bw_session + '&a=' + this.album + '&r=' + (Math.random() * Math.random()) );
	}
	
	function start()
	{
		this.stop();
		this.timeout = window.setTimeout('_oSlideshow_' + this.id + '.next();', this.duration * 1000);
		this.playing = true;
	}
	
	function stop()
	{
		if(this.timeout != null && this.timeout != false)
			window.clearTimeout(this.timeout);
	}
	
	function play()
	{
		this.start();
		
		var thisReference = this;
		this.playButton.src = bw_url + '/mod/ophoto/art/slideshow_pause.png';
		this.playButton.title = 'Click here to pause the slideshow.';
		this.clearEvents(this.playButton, 'click');
		this.setEvent(this.playButton, 'click', function() { thisReference.pause(); });
	}
	
	function pause()
	{
		this.stop();
		this.playing = false;
		
		var thisReference = this;
		this.playButton.src = bw_url + '/mod/ophoto/art/slideshow_play.png';
		this.playButton.title = 'Click here to play the slideshow.';
		this.clearEvents(this.playButton, 'click');
		this.setEvent(this.playButton, 'click', function() { thisReference.play(); });
	}
	
	function next()
	{
		this.stop();
		var thisReference = this;
		var imageReference = this.nextImage;
		
		this.moveCursor(1);
		var row = this.images[ this.cursor ];
		var x = this.resize( row.display_width, row.display_height );
		
		this.titleCell.innerHTML = row.title;
		this.slideCell.innerHTML = 'Image ' + Number(this.cursor + 1) + ' of ' + this.images.length;
		
		switch(this.transition)
		{
			case oTransitions.SLIDER:
				this.nextImage.style.visibility = 'hidden';
				this.window.appendChild(this.nextImage);
				this.nextImage.style.left = ((x.width + 15) * -1) + 'px';
				this.nextImage.style.visibility = 'visible';
				
				$(this.image).animate( { left: (thisReference.width + 15) + 'px' }, 1000 );
				$(this.nextImage).animate( { left: x.left + 'px' }, 1000, null, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				break;
			
			case oTransitions.SLIDEL:
				this.nextImage.style.visibility = 'hidden';
				this.window.appendChild(this.nextImage);
				this.nextImage.style.left = (thisReference.width + 15) + 'px';
				this.nextImage.style.visibility = 'visible';
				
				$(this.image).animate( { left: ((this.image.width + 15) * -1) + 'px' }, 1000 );
				$(this.nextImage).animate( { left: x.left + 'px' }, 1000, null, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				break;
			
			case oTransitions.SLIDED:
				this.nextImage.style.visibility = 'hidden';
				this.window.appendChild(this.nextImage);
				this.nextImage.style.top = ((x.height + 15) * -1) + 'px';
				this.nextImage.style.visibility = 'visible';
				
				$(this.image).animate( { top: (thisReference.height + 15) + 'px' }, 1000 );
				$(this.nextImage).animate( { top: x.top + 'px' }, 1000, null, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				break;
			
			case oTransitions.SLIDEU:
				this.nextImage.style.visibility = 'hidden';
				this.window.appendChild(this.nextImage);
				this.nextImage.style.top = (thisReference.height + 15) + 'px';
				this.nextImage.style.visibility = 'visible';
				
				$(this.image).animate( { top: ((this.image.height + 15) * -1) + 'px' }, 1000 );
				$(this.nextImage).animate( { top: x.top + 'px' }, 1000, null, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				break;
			
			case oTransitions.FADE:
				this.image.style.zIndex = '500';
				this.nextImage.style.zIndex = '400';
				this.nextImage.style.display = 'none';
				this.window.appendChild(this.nextImage);
				
				$(this.image).fadeOut( 1000, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				$(this.nextImage).fadeIn( 900 );
				break;
			
			case oTransitions.NONE:
			default:
				this.window.innerHTML = '';
				this.window.appendChild(this.nextImage);
				break;
		}
		
		// take a peek at the next slide
		this.moveCursor(1);
		row = this.images[ this.cursor ];
		x = this.resize( row.display_width, row.display_height );
		this.moveCursor(-1);
		
		this.prevImage = this.image;
		this.image = this.nextImage;
		this.nextImage = document.createElement('img');
		this.nextImage.setAttribute('src', row.url);
		this.nextImage.width = x.width;
		this.nextImage.height = x.height;
		this.nextImage.style.width = x.width + 'px';
		this.nextImage.style.height = x.height + 'px';
		this.nextImage.style.position = 'absolute';
		this.nextImage.style.top = x.top + 'px';
		this.nextImage.style.left = x.left + 'px';
		
		this.bullpen.innerHTML = '';
		this.bullpen.appendChild(this.nextImage);
		
		if(this.playing)
			this.start();
	}
	
	function prev()
	{
		this.pause();
		var thisReference = this;
		var imageReference = this.prevImage;
		
		this.moveCursor(-1);
		var row = this.images[ this.cursor ];
		var x = this.resize( row.display_width, row.display_height );
		
		this.titleCell.innerHTML = row.title;
		this.slideCell.innerHTML = 'Image ' + Number(this.cursor + 1) + ' of ' + this.images.length;
		
		switch(this.transition)
		{
			case oTransitions.SLIDER:
				this.prevImage.style.visibility = 'hidden';
				this.window.appendChild(this.prevImage);
				this.prevImage.style.left = (thisReference.width + 15) + 'px';
				this.prevImage.style.visibility = 'visible';
				
				$(this.image).animate( { left: ((this.image.width + 15) * -1) + 'px' }, 1000 );
				$(this.prevImage).animate( { left: x.left + 'px' }, 1000, null, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				break;
			
			case oTransitions.SLIDEL:
				this.prevImage.style.visibility = 'hidden';
				this.window.appendChild(this.prevImage);
				this.prevImage.style.left = ((x.width + 15) * -1) + 'px';
				this.prevImage.style.visibility = 'visible';
				
				$(this.image).animate( { left: (thisReference.width + 15) + 'px' }, 1000 );
				$(this.prevImage).animate( { left: x.left + 'px' }, 1000, null, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				break;
			
			case oTransitions.SLIDED:
				this.prevImage.style.visibility = 'hidden';
				this.window.appendChild(this.prevImage);
				this.prevImage.style.top = (thisReference.height + 15) + 'px';
				this.prevImage.style.visibility = 'visible';
				
				$(this.image).animate( { top: ((this.image.height + 15) * -1) + 'px' }, 1000 );
				$(this.prevImage).animate( { top: x.top + 'px' }, 1000, null, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				break;
			
			case oTransitions.SLIDEU:
				this.prevImage.style.visibility = 'hidden';
				this.window.appendChild(this.prevImage);
				this.prevImage.style.top = ((x.height + 15) * -1) + 'px';
				this.prevImage.style.visibility = 'visible';
				
				$(this.image).animate( { top: (thisReference.height + 15) + 'px' }, 1000 );
				$(this.prevImage).animate( { top: x.top + 'px' }, 1000, null, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				break;
			
			case oTransitions.FADE:
				this.image.style.zIndex = '500';
				this.prevImage.style.zIndex = '400';
				this.prevImage.style.display = 'none';
				this.window.appendChild(this.prevImage);
				
				$(this.image).fadeOut( 1000, function() { thisReference.window.innerHTML = ''; thisReference.window.appendChild(imageReference); } );
				$(this.prevImage).fadeIn( 900 );
				break;
			
			case oTransitions.NONE:
			default:
				this.window.innerHTML = '';
				this.window.appendChild(this.prevImage);
				break;
		}
		
		// take a peek at the next slide
		this.moveCursor(-1);
		row = this.images[ this.cursor ];
		x = this.resize( row.display_width, row.display_height );
		this.moveCursor(1);
		
		this.nextImage = this.image;
		this.image = this.prevImage;
		this.prevImage = document.createElement('img');
		this.prevImage.setAttribute('src', row.url);
		this.prevImage.width = x.width;
		this.prevImage.height = x.height;
		this.prevImage.style.width = x.width + 'px';
		this.prevImage.style.height = x.height + 'px';
		this.prevImage.style.position = 'absolute';
		this.prevImage.style.top = x.top + 'px';
		this.prevImage.style.left = x.left + 'px';
		
		this.bullpen.innerHTML = '';
		this.bullpen.appendChild(this.prevImage);
	}
}