if(typeof(Effect) == "undefined")
	throw "Slideshow requires Effects to be loaded.";

var Slideshow = Class.create();
    Slideshow.prototype = {

		
	initialize: function(elem, options) {

		this.setOptions(options);
		
		// insert two panes for double-buffering
		elem.select('.canvas').first().insert({
			bottom: '<div class="' + this.options.pane + ' ' + this.options.pane + '-0" style="display:none"><div class="content"></div></div><div class="' + this.options.pane + ' ' + this.options.pane + '-1" style="display:none;"><div class="content"></div></div>'
		});
		
		
		
		this.element              = elem;
		this.current_pane         = 0;
		
		this.total_image_count    = elem.select('.' + this.options.image).length; 
		this.current_image_count  = 1;
		this.is_first_iteration   = true;

		if (this.options.integrity_check) {
			
			this.checkIntegrity();
			
		}
		
		this.bufferPane()
		this.togglePane()
						
	},

	
	bufferPane: function() {
		
		var panes = this.getPanes();
		
		
		var image_class = '.'
		                + this.options.image
		                + '-'
		                + this.current_image_count;
		
		var root  = this.element.select(image_class).first();
		var image = null;
		
		try {
			
			image = root.select('.content').first().cloneNode(true);
			
		} catch(e) {
			
			return;
			
		}
		
		
		var caption = root.select('.caption').first().cloneNode(true);
		caption.addClassName(this.options.caption);
		
		if ( caption.empty()) {
			
			caption.setStyle({display: 'none'});
			
		}
		    
		panes.buffer.select('.content').first().update(image);
		panes.buffer.select('.content').first().insert(caption);
		panes.buffer.setStyle({display: 'none', zIndex: '3'});
		panes.display.setStyle({zIndex: '4'});
		
		
		// for the first itteration, we don't want to mess with the positioning
		// everything is where it needs to be
		if (!this.is_first_iteration) {
			
			panes.display.setStyle({position:'static'});
			panes.buffer.setStyle({position:'absolute', top:'0px'});
			
		}
		
		
		// If there is only one image, we do not need to buffer anything else
		// as we will not be toggling to anything else
		if (this.total_image_count > 1) {
			
			var callback      = this;
			var callback_time = this.options.span;
			
			if (this.is_first_iteration) {
				
				var callback_time = (this.options.span / 2);
				
			}
			
			
			setTimeout(function() { callback.bufferPane() }, callback_time);
		}
		
	},

	
	togglePane: function() {
		
		var panes    = this.getPanes();		
		var duration = !this.is_first_iteration
		             ? this.options.duration/1000
		             : 0;
		panes.buffer.appear({duration: duration, from: 0, to: 1});
		panes.display.fade({duration: duration, from: 1, to: 0.01});

		
		// adjust counters
		// current_pane is either 0 or 1
		this.current_pane = !this.current_pane;
		this.current_image_count = (++this.current_image_count > this.total_image_count) 
		                         ? 1
		                         : this.current_image_count; 

		
		// If there is only one image, we will not need to call this method again.
		// You cannot *rotate* through one image.
		if (this.total_image_count > 1) {
			
			var callback = this;
			setTimeout(function() { callback.togglePane() }, this.options.span);
			
		}
		
		this.is_first_iteration = false;
		
	},
	
	
	setOptions: function (options) {
		// set options
		this.options = {
				
			span:             30000,
			duration:         5000,
			pane:             'pane',
			image:            'slide',
			integrity_check:  false
		}
		
		Object.extend(this.options, options || {});
	},
	
	
	getPanes: function() {
		
		var panes = {
				
			buffer: {},
			display: {}
			
		};
		
		var pane_prefix = this.options.pane + '-';
		
		var buffered_pane_class  = pane_prefix + Number(!this.current_pane);
		var displayed_pane_class = pane_prefix + Number(this.current_pane);

		panes.buffer = this.element.select('.' + buffered_pane_class).first();
		panes.display = this.element.select('.' + displayed_pane_class).first();
		
		
		return panes;
		
	},
	
	
	checkIntegrity: function() {
				
		var validation = {};
		var value      = '';
		
		
		console.group('Display Panes');
		
		{
			var panes = this.getPanes();
			var value = '';

			var validation = {
				
				position: 'static',
				display:  'none'
					
			};
			
						
			for (var i in validation) {
				
				value = panes.display.getStyle(i);
				
				this.validate(i, validation[i], value);
				
				
			}
			
		}
		
		console.groupEnd();
		
		
		console.group('Images');
		
		{
			var panes = this.getPanes();
			var value = '';
			
			var validation = {
				
				display:  'none'
						
			};
			
			var image_class = '.'
                + this.options.image
                + '-'
                + this.current_image_count;
			
			var image       = this.element.select(image_class).first();
			
			
			
			for (var i in validation) {
							
				value = image.getStyle(i);
			
				this.validate(i, validation[i], value);
				
			}
			
		}
		
		console.groupEnd();
		
		
	},
	
	
	validate: function(key, expected_value, actual_value) {
		
		
		if (actual_value != expected_value) {
			
			console.warn( key + ' should be \'' + expected_value + '\', not \'' + actual_value + '\'.' );
			
		} else {
			
			console.log( key + ' okay.' );
			
		}
	}
			
	
};

		
			
