/*
Script: SlideShow.js
	Contains the SlideShow Class as well as the Slide Class

License:
	MIT-style license.
*/

/*
Class: SlideShow
	
Arguments:
	element - required, DOM Element or Id to contain the SlideShow
	options - optional, Settings for the SlideShow see below - all the options for slide are available as well for the default slide.

Options:
	margin - integer, the Margin between slides on scroll transitions (default 6)
	height - string, CSS property for height of the SlideShow (default 100%)
	width - string, CSS property for width of the SlideShow (default 100%)
	repeat - boolean, flag to repeat the slideshow or not (default true)
	timeout - integer, time in milliseconds to wait for a slide to load (default 1000)
	debug - boolean, flag to allow debug statements (browsers with console only) (default false)
	random - boolean, show slides randomly (default true)
	clsPrefix - string, prefix for configuration classes (only for createFromMarkup function - default 'ss')

Example:
	(start code)
	var ss = new Class('slideshow', {
		'color': '#ffffff',
		'height': '300px',
		'width': '300px'
	});
	ss.start();
	(end)
*/

var SlideShow = new Class( {
	
	options: {
		'margin'				:6,
		'height'				:'100%',
		'width'					:'100%',
		'repeat'				:true,
		'timeout'				:1000,
		'debug'					:false,
		'random'				:true,
		/* createFromMarkup options */
		'clsPrefix'				:'ss',
		/* defaultSlide options */
		'fontFamily'			:'Trebuchet MS, Tahoma, Verdana, sans',
		'fontWeight'			:'bold',
		'fontSize'				:'19px',
		'color'					:'#ffffff',
		'direction'				:'?',
		'sizeToContent'			:false,
		'resizeContainer'		:false,
		'textDirection'			:'?',
		'textPadding'			:3,
		'slideDuration'			:2000,
		'transitionDuration'	:3000,
		'transitionType'		:'?',
		'shadowOffset'			:1,
		'textBg'				:'#000000',
		'textBgOpacity'			:'.4',
		'shadow'				:true,
		'slideTransition'		:Fx.Transitions.Expo.easeOut,
		'textTransition'		:Fx.Transitions.Bounce.easeOut,
		'lazyLoad'				:true
	},
	
	'index'			:0,
	'realIndex'		:false,
	'seen'			:{},
	'on'			:true,
	'slide'			:false,
	'slides'		:[],
	'animations'	:[],
	'timeouts'		:[],
	
	initialize: function(container,options){
		this.container = $(container);
		this.setOptions(options);
		var ds = this.getDefaultSlide();
		var o = {};
		// these are the defaultSlide options.
		var p = ['fontFamily','fontSize','direction','textDirection','slideDuration',
				 'transitionDuration', 'shadow','slideTransition','slideEasing',
				 'textTransition','textEasing','color', 'transitionType', 'textBg', 
				 'textBgOpacity', 'tansitionType','fontWeight','lazyLoad','textPadding',
				 'shadowOffset'];
		p.each(function(v){ o[v] = this.options[v]; }.bind(this) );
		ds.setOptions(o);
		this.container.empty();
		this.drawCanvas();
		this.showLoading();
		this.originalSize = this.options.resizeContainer ? this.container.getSize().size : this.holder.getSize().size;
		this.fireEvent('afterInitialize',[this]);
	},
	
	/*
	Property: getDefaultSlide
		Get the default slide for the slideshow
		
	*/
	
	getDefaultSlide: function(){
		if( !this.defaultSlide ){
			this.defaultSlide = new Slide();
		}
		return this.defaultSlide;
	},
	
	/*
	Property: getSlide
		Get a specific Slide
		
	Arguments:
		index - integer, index of the Slide
	*/
	
	getSlide: function(index){
		if( !index ){
			index = this.index;
		}
		var s = this.slides[index];
		if( !s ){
			return false;
		}
		return s;
	},
	
	registerTimeout: function(to){
		this.timeouts.push(to);
	},
	
	registerEffect: function(fx,save){
		this.animations.push(fx);
		if(!save){
			fx.addEvent('onComplete', function(){
				this.animations.remove(fx);
			}.bind(this));
		}
	},
	/*
	Property: start
		Start the SlideShow
		
	*/
	start: function(){
		this.fireEvent('onStart',[this]);
		if( this.slides.length == 0 ){
			this.container.setHTML('No Slides...');
			return;
		}
		this.holder.removeClass('loading');
		if( this.options.random ){
			this.increment();
		}
		this.transition();
	},
	
	/*
	Property: stop
		Stop the SlideShow
		
	*/
	stop: function(){
		if( this._trans ){
			this._trans = $clear(this._trans);
		}
	},
	
	reset: function(){
		this.index = 0;
		this.seen = {};
	},
	
	/*
	Property: addSlide
		Add a slide to the SlideShow
		
	Arguments:
		slide - required, a Slide or the image source for the slide
		text - optional, Text for the slide
		options - optional, Options for the slide
	*/
	addSlide: function(s,t,o){
		if($type(s)=='string'){
			s = new Slide(s,t,o,this.getDefaultSlide());
		}else{
			s.setDefaultSlide(this.getDefaultSlide());
		}
		this.slides.push(s);
		return s;
	},
	
	retryTransition: function(){
		if( this._timeoutTrans ){
			$clear(this._timeoutTrans);
		}
		if( this._trans ){
			$clear(this._trans);
		}
		this.transition();
	},
	
	isLast: function(){
		if( !this.options.random && this.index == this.slides.length - 1 ){
			return true;
		}
		if( this.options.random ){
			var counts = {};
			var max = 0;
			for( var i in this.seen ){
				var count = this.seen[i];
				if( count > max ){ max = count; }
				if( !counts[count] ){
					counts[""+count] = [];
				}
				counts[count].push(""+i);
			}
			if( counts[max] && counts[max].length == this.slides.length - 1){
				return true;
			}
		}
		return false;
	},
	
	removeAndSkip: function(){
		this.slides = this.slides.remove(this.slides[this.index]);
		delete( this.seen[this.index] );
		this.skip();
	},
	/*
	Property: skip
		Skip to the next slide in the SlideShow
		
	*/
	skip: function(){
		if( this.options.debug){
			this._debug('- skipping slide '+this.index );
		}
		if( this._trans ){
			$clear(this._trans);
		}
		this.animations.each(function(fx){
			fx.stop();
		});
		this.increment();
		this.transition();
	},
	
	transition: function(){
		this._debug('enter transition()');
		if( !this.options.repeat && this.isLast() ){
			this.fireEvent('onLast');
			this.reset();
			return;
		}
		var lastSlide = this.slide || false;
		var slide = this.getSlide(this.index);
		if( !slide || !slide.isLoaded() ){
			if( !slide ){
				this.skip();
			}
			if( this.options.debug){
				this._debug('slide not loaded',this.index,slide);
			}
			this.showLoading();
			this._timeoutTrans = this.removeAndSkip.delay(this.options.timeout,this);
			slide.addEvent('load', this.retryTransition.bind(this));
			return;
		}
		this.hideLoading();
		if( !this.seen[this.index] && this.seen[this.index] != 0){
			this.seen[this.index] = 1;
		}else{
			this.seen[this.index]++;
		}
		this.slide = slide;
		this.lastSlide = lastSlide;
		
		var tt = this.slide.get('transitionType');
		var td = this.slide.get('transitionDuration');
		var sd = this.slide.get('slideDuration');
		
		if( this.options.sizeToContent ){
			var img = this.getSlide().getImg();
			var newSize = {};
			var size = this.options.resizeContainer ? this.container.getSize().size : this.holder.getSize().size;
			newSize.width = img.width;
			newSize.height = img.height;
			if( newSize.width || newSize.height ){
				obj = this.options.resizeContainer ? 'container' : 'holder';
				this[obj].effects({duration: td, transition: this.slide.get('slideTransition') }).start(newSize);
				this.oldSize = size;
				this.newSize = {};
				if( newSize.height ){ this.newSize.y = newSize.height; }
				if( newSize.width){ this.newSize.x = newSize.width; }
			}
		}
		
		if( $type(tt) == 'array' || !this.transitions[tt] ){
			var tr = [];
			if( $type(tt) == 'array' ){
				tr = tt;
			}
			else{
				for(var i in this.transitions){
					tr.push(i);
				}
			}
			var trans = $random(0,tr.length-1);
			tt = tr[trans];
		}
		this.fireEvent('onTransition',[this,this.slide,tt]);
		this.transitions[tt].call(this);
		this._trans = this.transition.delay( sd+td, this );
		this.increment();
		if(this.hideText){
			this.hideText();
		}
		else{
			this.writeText();
		}
	},
	
	
	transitions: {
		
		scroll: function(){
			var lastImg = this.lastSlide ? this.lastSlide.get('img') : false;
			var img = this.slide.get('img');
			
			var direction = this.slide.get('direction');
			
			var td = this.slide.get('transitionDuration');
			var sd = this.slide.get('slideDuration');
			
			var pos = this.mover.getPosition();
			var canvasSize = this.canvas.getSize().size;
			
			var lastSize = this.lastSlide ? lastImg.getSize().size : canvasSize;
			var size = {x:img.width,y:img.height};
			var v = (direction == 't' || direction == 'b');
			var neg = (direction =='t' || direction == 'l');
			
			var newPos = {};
			
			newPos[v?'top':'left'] = (this.lastSlide ? lastImg.getStyle(v?'top':'left').toInt() : 0) + ((neg?(-1*size[v?'y':'x']):lastSize[v?'y':'x']) + (neg?-1:1)*this.options.margin);
			newPos[v?'left':'top'] = (this.lastSlide ? lastImg.getStyle(v?'left':'top').toInt() : 0) - (( size[v?'x':'y'] - lastSize[v?'x':'y'] ) / 2);
			
			img.setStyles({
				position: 'absolute',
				top: newPos.top+'px',
				left: newPos.left+'px',
				display: 'block',
				opacity: 1
			});
			
			if( this.lastSlide ){
				lastImg.effects({duration: td, transition: Fx.Transitions.Expo.easeOut}).
					start( {opacity: [1,0] } );
			}
			img.injectInside( this.mover );
			
			
			var newTop = -(newPos.top + (( size.y - canvasSize.y ) / 2));
			var newLeft = -(newPos.left + (( size.x - canvasSize.x ) / 2));
			
			if(this.newSize){
				newTop = newTop + (this.newSize.y - this.oldSize.y)/2;
				newLeft = newLeft + (this.newSize.x - this.oldSize.x)/2;
			}
			
			if( !this.scroller ){
				this.scroller = this.mover.effects();
			}
			this.scroller.options.duration = td, 
			this.scroller.options.transition = this.slide.get('slideTransition');
			this.scroller.start({left: newLeft+'px',top: newTop+'px'});
			
			if( false ){ // TODO: add flag for burn effect
				var newsize = {x: size.x*1.2, y: size.y*1.2};
				if( !img.fx ){
					img.fx = img.effects({duration: td+sd, transition: Fx.Transitions.Expo.easeOut});
				}
				var xdif = newsize.x - size.x;
				var ydif = newsize.y - size.y;
				
				
				var extra = {};
				if( direction == 'l'){
					extra.left = [(newPos.left - xdif)+'px', newPos.left+'px'];
				}
				if( direction == 'l' || direction == 'r' ){
					extra.top = [(newPos.top - ydif/2)+'px', newPos.top+'px'];
				}
				if( direction == 't' ){
					extra.top = [(newPos.top - ydif)+'px', newPos.top+'px'];
				}
				if( direction == 't' || direction == 'l' ){
					extra.left = [(newPos.left - xdif/2)+'px', newPos.left+'px'];
				}
				var all = $merge({
					width:[size.x*1.5,size.x], 
					height:[size.y*1.5,size.y]
				},extra);
				img.fx.start(all);
			}
		},
		
		crossfade: function(){
			var img = this.slide.get('img');
			var lastImg = this.lastSlide ? this.lastSlide.get('img') : false;
			
			var canvasSize = this.canvas.getSize().size;
			
			var size = {x:img.width,y:img.height};
			
			var newPos = {};
			
			newPos.x = -((this.mover.getStyle('left').toInt()) - ((canvasSize.x - img.width)/2));
			newPos.y = -((this.mover.getStyle('top').toInt()) - ((canvasSize.y - img.height)/2));
			
			img.setStyles({
				display:	'block',
				position:	'absolute',
				top:		(newPos.y)+'px',
				left:		(newPos.x)+'px',
				opacity: 	0
			})
			img.injectInside(this.mover);
			var td = this.slide.get('transitionDuration');
			var sd = this.slide.get('slideDuration');
			var st = this.slide.get('slideTransition');
			var se = this.slide.get('slideEasing');
			var t = this.slide.get('slideTransition');
			var fx1 = img.effects({duration: td, transition: t});
			this.registerEffect(fx1);
			fx1.start({opacity:[0,1]});
			
			if(this.newSize){
				var oldLeft = this.mover.getStyle('left').toInt();
				var oldTop = this.mover.getStyle('top').toInt();
				var newTop = (oldTop+ (( this.newSize.y - this.oldSize.y ) / 2));
				var newLeft = (oldLeft + (( this.newSize.x - this.oldSize.x ) / 2));
				if( !this.scroller ){
					this.scroller = this.mover.effects();
				}
				this.scroller.options.duration = td, 
				this.scroller.options.transition = Fx.Transitions.Expo.easeOut;
				this.scroller.start({left: newLeft+'px',top: newTop+'px'});
			}
			
			
			if( lastImg ){
				var fx2 = lastImg.effects({duration: td, transition: t});
				this.registerEffect(fx2);
				fx2.start({opacity:[1,0]});
				lastImg.setStyle.delay( td, lastImg, ['display','none'] )
			}
		},
		
		burst: function(){
			
			var img = this.slide.get('img');
			var lastImg = this.lastSlide ? this.lastSlide.get('img') : false;
			
			var canvasSize = this.canvas.getSize().size;
			
			var size = {x:img.width,y:img.height};
			
			var newPos = {};
			
			newPos.x = -((this.mover.getStyle('left').toInt()) - ((canvasSize.x - img.width)/2));
			newPos.y = -((this.mover.getStyle('top').toInt()) - ((canvasSize.y - img.height)/2));
			
			
			var div = new Element('div',{
				styles: {
					'display'			:'block',
					'background'		:'url('+img.src+') center center no-repeat',
					'width'				:'0px',
					'height'			:'0px',
					'position'			:'absolute',
					'top'				:(newPos.y)+'px',
					'left'				:(newPos.x)+'px'
				}
			}).injectInside(this.mover);
			
			var imageGro = new Element('img',{
				src: img.src,
				styles:{
					width: '100%',
					height: '100%'
				}
			}).injectInside(div);
			
			img.setStyles({
				display:	'block',
				position:	'absolute',
				top:		(newPos.y)+'px',
				left:		(newPos.x)+'px',
				opacity: 	0
			})
			img.injectInside(this.mover);
			var td = this.slide.get('transitionDuration');
			var sd = this.slide.get('slideDuration');
			
			var t = this.slide.get('slideTransition');
			var fx = div.effects({duration: td, transition: t});
			this.registerEffect(fx);
			if( lastImg ){
				fx2 = lastImg.effects({duration:td, transition: t});
				fx2.start({opacity:[1,0]});
				this.registerEffect(fx2);
			}
			
			var props = {
				//opacity: [0,1],
				width:[0,img.width],
				height:[0,img.height],
				top: [newPos.y+img.height/2,newPos.y],
				left: [newPos.x+img.width/2,newPos.x]
			};
			if(this.newSize){
				var oldLeft = this.mover.getStyle('left').toInt();
				var oldTop = this.mover.getStyle('top').toInt();
				var newTop = (oldTop+ (( this.newSize.y - this.oldSize.y ) / 2));
				var newLeft = (oldLeft + (( this.newSize.x - this.oldSize.x ) / 2));
				if( !this.scroller ){
					this.scroller = this.mover.effects();
				}
				this.scroller.options.duration = td, 
				this.scroller.options.transition = Fx.Transitions.Expo.easeOut;
				this.scroller.start({left: newLeft+'px',top: newTop+'px'});
			}
			fx.start(props).chain(function(){
				div.remove();
			});
			img.setStyle.delay(td,img,['opacity',1]);
			
		}
		
	},
	
	writeText: function(){
		var txt =			this.slide.text;
		if( !txt ){
			return;
		}
		var color = 		this.slide.get('color');
		var pos = 			this.slide.get('textDirection');
		var dropShadow =	this.slide.get('shadow');
		var fontSize = 		this.slide.get('fontSize');
		var fontWeight =	this.slide.get('fontWeight');
		var fontFamily = 	this.slide.get('fontFamily');
		var padding =		this.slide.get('textPadding');
		
		var p ={};
		p.y = pos.test(/t/) ? 'top' : 'bottom';
		p.x = pos.test(/l/) ? 'left' : (pos.test(/c/) ? 'center' : 'right');
		
		var op = p.y == 'top' ? 'bottom' : 'top';
		
		this.textWrap.setStyles({
			'font-size'		:fontSize,
			'font-weight'	:fontWeight,
			'font-family'	:fontFamily,
			'color'			:color,
			'text-align'	:p.x,
			'opacity'		:0
		}).setStyle(p.y,0).setStyle(op,'');
		
		
		this.textSpan.setStyle('padding',padding.toInt()+'px');
		this.textSpan.setHTML(txt);
		
		if( dropShadow ){
			var c = color;
			if( $type(dropShadow) == 'string' ){
				c = new Color(dropShadow);
			}
			else if( $type(dropShadow) == 'function' ){
				c = dropShadow(color);
			}
			else{
				c = color.invert();
			}
			var offset = this.slide.get('shadowOffset');
			this.dropShadowWrap.setStyles({
				'font-size'		:fontSize,
				'top'			:offset+'px',
				'left'			:offset+'px',
				'font-weight'	:fontWeight,
				'font-family'	:fontFamily
			});
			this.dropShadowSpan.setStyles({
				'padding'	:padding.toInt()+'px',
				'color'		:c
			}).setHTML(txt);
		}else{
			this.dropShadowWrap.setStyle('display','none');
		}
		
		var tbg = this.slide.get('textBg');
		
		if( tbg ){ 
			var c = tbg;
			if( $type(c) == 'boolean' ){
				c =  '#ffffff';
			}
			var o = this.slide.get('textBgOpacity');
			this.textBg.setStyles({
				'background'		:c,
				'opacity'			:o,
				'display'			:'block'
			});
		}else{
			this.textBg.setStyle('display', 'none');
		}
		
		var td = this.slide.get('transitionDuration');
		var sd = this.slide.get('slideDuration');
		var textTransition = this.slide.get('textTransition');
		var dur = Math.min( td * .5, 1000 );
		var s = function(t){
			var change = {};
			change[p.y] = [-(this.textWrap.getSize().size.y ),0];
			if( !this.textWrap.fx ){
				this.textWrap.fx = this.textWrap.effects();
			}
			this.textWrap.fx.options.duration = dur;
			this.textWrap.fx.options.transition = t;
			// stop in case its being hidden from before
			this.textWrap.fx.stop();
			this.textWrap.fx.start(change);
			this.textWrap.setStyle.delay(20,this.textWrap,['opacity',1]);
		}.pass(textTransition,this);
		
		this.hideText = function(t){
			var change = {};
			change[p.y] = [0,-(this.textWrap.getSize().size.y) ];
			this.textWrap.fx.duration = dur*.5;
			this.textWrap.fx.transition = t;
			this.textWrap.fx.start(change).chain( function(){
				this.writeText();
			}.bind(this));
		}.pass(textTransition,this);
		s();
	},
	
	increment: function(){
		this.last = this.index;
		if( this.options.random && this.slides.length > 1){
			var counts = {};
			var max = 0;
			for( var i in this.seen ){
				var count = this.seen[i];
				if( count > max ){ max = count; }
				if( !counts[count] ){
					counts[""+count] = [];
				}
				counts[count].push(""+i);
			}
			var av = [];
			for(var i=0; i<this.slides.length;i++){
				av.push(""+i);
			}
			if( max > 0 && counts[max].length != this.slides.length ){
				counts[max].each( function(i){
					av = av.remove(i);
				});
			}
			if( max > 0 && counts[max].length == this.slides.length ){
				av.remove(""+this.index);
			}
			this.index = av[$random(0,av.length-1)];
		}
		else{
			this.index++;
			if( this.index == this.slides.length ){
				this.index = 0;
			}
		}
		// preload image
		if( this.getSlide(this.index) ){
			this.getSlide(this.index).setImg();
		}
	},
	
	drawCanvas: function(){
		
		var p = this.container.getStyle('position');
		if( !p || p=='' || p=='static'){ 
			this.container.setStyle('position','relative'); 
		}
		this.holder = new Element('div', {
			styles: {
				'position'		:'relative',
				'height'		:this.options.height,
				'width'			:this.options.width
			}
		}).injectInside(this.container).addClass('ss-loading');
		
		this.canvas = new Element('div', {
			styles: {
				'position'		:'absolute',
				'top'			:'0px',
				'opacity'		:'1',
				'overflow'		:'hidden',
				'left'			:'0px',
				'text-align'	:'left',
				'width'			:'100%',
				'height'		:'100%'
			}
		}).injectInside(this.holder);
			
		this.mover = new Element('div', {
			styles: {
				'position'		:'absolute',
				'top'			:'0px',
				'left'			:'0px',
				'width'			:'100%',
				'height'		:'100%'
			}
		}).injectInside( this.canvas );
		
		this.loadingCover = new Element('div',{
			styles:{
				'background'	:'#000000',
				'opacity'		:'.3',
				'position'		:'absolute',
				'top'			:'0px',
				'left'			:'0px',
				'width'			:'100%',
				'height'		:'100%',
				'z-index'		:'2',
				'display'		:'none'
			}
		}).injectInside(this.holder);
		
		this.loadingText = new Element('div',{
			styles:{
				'position'		:'absolute',
				'top'			:'48%',
				'left'			:'0px',
				'text-align'	:'center',
				'width'			:'100%',
				'z-index'		:'3',
				'display'		:'block',
				'opacity'		:1,
				'color'			:'#ffffff',
				'font-family'	:'Trebuchet MS, Tahoma',
				'font-size'		:'20px',
				'font-weight'	:'bold'
			}
		}).injectInside(this.holder);
		var span = new Element('span').setHTML('Loading...').injectInside(this.loadingText);
		
		this.textWrap = new Element('div',{
			styles:{
				'margin'		:'0px',
				'display'		:'block',
				'position'		:'absolute',
				'width'			:'100%',
				'opacity'		:0,
				'z-index'		:1,
				'display'		:'block'
			}
		}).injectInside(this.canvas);
		
		this.textSpan = new Element('span',{
			styles: {
				'position'		:'relative',
				'display'		:'block',
				'z-index'		:'3'
			}
		}).injectInside(this.textWrap);
			
		this.dropShadowWrap = new Element('div',{
			styles:{
				'margin'		:'0px',
				'display'		:'block',
				'width'			:'100%',
				'top'			:'1px',
				'left'			:'1px',
				'position'		:'absolute',
				'opacity'		:.65,
				'z-index'		:2
			}
		}).injectInside( this.textWrap );
		
		this.dropShadowSpan = new Element('span',{styles:{'position':'relative','display':'block'}})
			.injectInside( this.dropShadowWrap );
		
		this.textBg = new Element('div',{
			styles: {
				'display'		:'none',
				'z-index'		:1,
				'position'		:'absolute',
				'top'			:'0px',
				'left'			:'0px',
				'right'			:'0px',
				'bottom'		:'0px',
				'height'		:'100%',
				'width'			:'100%'
			}
		}).injectInside( this.textWrap );
		
	},
	showLoading: function(){
		this.loadingCover.setStyle('display','block');
		this.loadingText.setStyle('display','block');
	},
	hideLoading: function(){
		this.loadingCover.setStyle('display','none');
		this.loadingText.setStyle('display','none');
	},
	
	_debug: function(str){
		if( this.options.debug &&  window.console && window.console.log){
			window.console.log( str );
		}
	}
});
SlideShow.implement(new Events);
SlideShow.implement(new Options);
SlideShow.directions = ['b','r','t','l'];
SlideShow.transitions = ['slide','crossfade'];
/*
Function: createFromMarkup
	Returns the slideshow
	
Arguments:
	element - DOM Element or id
	options - SlideShow options
*/
SlideShow.createFromMarkup = function(el,options){
	var imgs = $(el).getElements('img');
	imgs.each(function(el){ el.injectInside(document.body); });
	
	var ss = new SlideShow(el,options);
	
	var ds = ss.getDefaultSlide();
	var getAttr = function(el,name,d){
		var matches = el.className.match( new RegExp( ss.options.clsPrefix+'\\-'+name+'\\-(\\w+)' ) );
		if( matches ){
			return matches[1];
		}
		return d;
	};
	imgs.each( function(img){
		var o = {};
		o.shadow = getAttr(img,'shadow',null);
		o.fontSize = getAttr(img,'size',null);
		if( o.fontSize ){ o.fontSize += 'px'; }
		o.color = getAttr(img,'color',null);
		o.direction = getAttr(img,'dir',null);
		o.textDirection = getAttr(img,'textdir',null);
		var s = new Slide(img.src, img.title,o);
		ss.addSlide(s);
		img.remove();
	});
	//$(el).empty();
	return ss;
}
/*
Class: Slide
	
Arguments:
	src - required, string - source of the image for the slide
	text - optional, string - text to show on the slide
	options - optional, object - see options
	defaultSlide - optional, object - A slide with default options (usually automatically set by SlideShow)
	
Options:
	fontFamily - string, CSS property for default slide font (default 'Trebuchet MS, Tahoma, Verdana, sans')
	fontSize  - string, CSS property for default slide font-size (default 19px)
	color - string, CSS property for default slide font color (default #ffffff)
	direction - string, 't','r','b','l','?' default slide scroll from position (default '?')
	sizeToContent - boolean, size the SlideShow container to the size of the slide (default false)
	resizeContainer - boolean, if sizeToContent is true, resize containing element, otherwise resize internal holder (default false)
	textDirection - string, 'tl','tc',tr','bl','bc','br','?' - default position for text (default '?')
	textPadding - integer, padding for text (default 3)
	slideDuration - integer, time in milliseconds to stay on slides	(default 2000)
	transitionDuration - integer, time in milliseconds for transitions to last (default 3000)
	transitionType - string, an array of transition types or string single type of transition. Possible values 'scroll','crossfade','burst','?' (default '?')
	shadowOffset - integer, if dropShadow, the top and left offset of the shadow (default 1)
	textBg - string/boolean, A CSS color value or boolean false to not show the background (default #000000)
	textBgOpacity - float, a value for opacity of textBg (default .4)
	shadow - boolean, flag to use dropShadow on text (default true)
	slideTransition - function, default transition for slides (default Fx.Transitions.Expo.easeOut)
	textTransition - function, default transition for text (default Fx.Transitions.Bounce.easeOut)
	lazyLoad - boolean, flag to load images as needed (default true)
*/
var Slide = new Class({	
	options: 	{
		// defined by Slide Show
	},
	img:		false,
	text:		'',
	loaded:		false,
	ds:			false,
	initialize: function(src,text,options,ds){
		this.img = false;
		this.src = src;
		this.text = text;
		this.setOptions(options);
		if( ds ){
			this.setDefaultSlide(ds);
		}
		if( !this.get('lazyLoad') ){
			this.setImg();
		}
	},
	/*
	Property: setDefaultSlide
		set the DefaultSlide for this slide
	
	Arguments:
		slide - the default Slide
	
	*/
	setDefaultSlide: function(s){
		this.ds = s;
	},
	onLoad: function(){
		if( !this.loaded ){
			this.loaded = true;
			this.fireEvent('load');
		}
	},
	setImg: function(){
		if( this.img ){ return; }
		this.img = new Asset.image(this.src, {
			alt: this.text,
			onload: this.onLoad.bind(this)
		});
		this.img.setStyle('display','none');
	},
	isLoaded: function(){
		if( this.get('lazyLoad') ){
			this.setImg();
		}
		return this.loaded;
	},
	getImg: function(){
		if( this.get('lazyLoad') ){
			this.setImg();
		}
		return this.img;
	},
	/*
	Property: get
		Get a requested option or property
		
	Arguments:
		variable - The variable to get
	*/
	get: function(v){
		var r = false;
		switch(v){
			case 'img':
				r = this.getImg();
				break;
			case 'direction':
				r = this.getDirection();
				break;
			case 'textDirection':
				r = this.getTextDirection();
				break;
			case 'color':
				r = this.getColor();
				break;
			default:
				if( this.options[v] ){
					r =this.options[v];
				}
				else if( this.ds && this.ds.options[v] ){
					r = this.ds.options[v];
				}
		}
		return r;
	},
	getDirection: function(ds){
		var d = this.options.direction || (this.ds ? this.ds.options.direction : '?');
		if( d == '?' && !SlideShow.directions.contains(d) ){
			d = SlideShow.directions[$random(0,SlideShow.directions.length-1)];
		}
		return d;
	},
	getTextDirection: function(ds){
		var d = this.options.textDirection || (this.ds ? this.ds.options.textDirection : '?');
		if( d == '?' && !Slide.textDirections.contains(d) ){
			d = Slide.textDirections[$random(0,Slide.textDirections.length-1)];
		}
		return d;
	},
	getColor: function(ds){ 
		var c = this.options.color || (this.ds ? this.ds.options.color : '#ffffff');
		return new Color( c ); 
	}
});
Slide.textDirections = ['tl','tr','bl','br','tc','bc'];
Slide.implement(new Options);
Slide.implement(new Events);