var mSlideShow = new Class({
	Implements: [Options, Events],
	
	options: {
		autoStart: false,
		random: false,
		ctrls: {
			show: true
		},
		fxOpts: {
			duration: 1000,
			delay: 3000
		},
		// EVENT HANDLERS
		onStart: Class.empty
	},
	
	initialize: function(cont, slides, options){
		this.setOptions(options);
		this.cont = cont;
		
		this.paused = false;
		this.history = [];
		
		// Collect all the slides needed
		this.slides = this.getSlides(slides);
		
		this.cur = this.getFirstSlide();
		
		// Prepare the slide show
		this.prepShow();
		
		// Auto start the slideshow
		if (this.options.autoStart) {			
			this.runShow();
		} else {
			this.slides[this.cur].addEvent('load', this.runShow.bind(this));
		}
	},
	
	prepShow: function(){
		this.slides.each(function(slide, i){
			if(i != this.cur)
				slide.setStyle('display', 'none');
		}, this);
		
		if (this.options.ctrls.show)
			this.prepCtrls();
	},
	
	runShow: function(noDelay){
		// Short hand
		var opts = this.options;
		
		if (!this.paused) {
			function setUpFx(){
				this.fxObj = new Fx.Morph(this.slides[this.cur], {
					duration: opts.fxOpts.duration
				});
				this.fxObj.addEvent('onComplete', this.showNext.bind(this));
				
				this.fxObj.start({opacity: 0});
			};
			
			var delayTime = opts.fxOpts.delay;
			
			this.timer = setUpFx.delay(delayTime, this);
		}
	},
	
	showNext: function() {
		// Short hand
		var opts = this.options;
		
		if (!this.paused) {
			this.slides[this.cur].setStyle('display', 'none');
			
			this.cur = this.getNextSlide();
			
			this.slides[this.cur].setStyles({
				display: 'block',
				opacity: '0'
			});
			
			this.fxObj = new Fx.Morph(this.slides[this.cur], {
				duration: opts.fxOpts.duration
			});
			this.fxObj.addEvent('onComplete', this.runShow.bind(this));
			this.fxObj.start({opacity: 1});
		}
	},
	
	getSlides: function(slides){
		switch($type(slides)) {
			case 'string':
				return this.cont.getElements(slides);
			break;
		}
	},
	
	getFirstSlide: function() {
		if(this.options.random) {
			return $random(0, this.slides.length-1);
		} else {
			return 0;
		}
	},
	
	getNextSlide: function(){
		if (this.options.random) {
			return $random(0, this.slides.length - 1);
		}
		else {
			if (this.cur + 1 >= this.slides.length) 
				return 0;
			else 
				return this.cur + 1;
		}
	},
	
	getPreviousSlide: function(){
		if(this.cur - 1 < 0)
			return this.slides.length-1;
		else
			return this.cur - 1;
	},
	
	//////////////////////////////////////////////
	// CONTROLS
	//////////////////////////////////////////////
	prepCtrls: function(){
		this.cont.setStyles({
			'position': 'relative',
			'z-index': 0
		});
		
		var contSize = this.cont.getSize();
		
		this.backCtrl = this.createBackCtrl();
		this.backCtrl.injectTop(this.cont);
		
		this.pauseCtrl = this.createPauseCtrl();
		this.pauseCtrl.injectAfter(this.backCtrl);
	
		this.nextCtrl = this.createNextCtrl();
		this.nextCtrl.injectAfter(this.pauseCtrl);
	},
	
	createBackCtrl: function() {
		var contSize = this.cont.getSize();
		
		var nextDiv = new Element('div', {
			'id': 'backCtrl',
			'styles': {
				'width': contSize.x/3,
				'height': contSize.y,
				'position': 'absolute',
				'left': 0,
				'top': 0,
				'z-index': 2
			},
			'events': {
				'mouseenter': function() {
					this.addClass('over');
				},
				'mouseleave': function() {
					this.removeClass('over');
				},
				'click': this.backSlide.bind(this)
			}
		});
		
		//IE FIX
		if(Browser.Engine.trident) {
			var img = new Element('img', {
				'src': '/static/images/js/slideshow/spacer.gif',
				'styles': {
					'width': '100%',
					'height': '100%'
				}
			});
			nextDiv.appendChild(img);
		}
		
		return nextDiv; 
	},
	
	backSlide: function() {
		$clear(this.timer);
		
		if($defined(this.fxObj))
			this.fxObj.cancel();
		
		this.slides[this.cur].setStyle('display', 'none');
		
		this.cur = this.getPreviousSlide();
		
		this.slides[this.cur].setStyles({
			'display': 'block',
			'opacity': 1
		});
		
		this.runShow();
		
		return false;
	},
	
	createNextCtrl: function(){
		var contSize = this.cont.getSize();
		
		var nextDiv = new Element('div', {
			'id': 'nextCtrl',
			'styles': {
				'width': contSize.x/3,
				'height': contSize.y,
				'position': 'absolute',
				'left': (contSize.x/3)*2,
				'top': 0,
				'z-index': 2
			},
			'events': {
				'mouseenter': function() {
					this.addClass('over');
				},
				'mouseleave': function() {
					this.removeClass('over');
				},
				'click': this.nextSlide.bind(this)
			}
		});
		
		//IE FIX
		if(Browser.Engine.trident) {
			var img = new Element('img', {
				'src': '/static/images/js/slideshow/spacer.gif',
				'styles': {
					'width': '100%',
					'height': '100%'
				}
			});
			nextDiv.appendChild(img);
		}
		
		return nextDiv;
	},
	
	nextSlide: function(){
		$clear(this.timer);
		
		if($defined(this.fxObj))
			this.fxObj.cancel();
		
		this.slides[this.cur].setStyle('display', 'none');
			
		this.cur = this.getNextSlide();
		
		this.slides[this.cur].setStyles({
			'display': 'block',
			'opacity': 1
		});
		
		this.runShow();
		
		return false;
	},
	
	// NEEDS REFACTORING
	createPauseCtrl: function(){
		var contSize = this.cont.getSize();
		
		var pauseDiv = new Element('div', {
			'id': 'pauseCtrl',
			'styles': {
				'width': contSize.x/3,
				'height': contSize.y,
				'position': 'absolute',
				'left': contSize.x/3,
				'top': 0,
				'z-index': 2
			},
			'events': {
				'click': this.pauseShow.bind(this),
				'mouseover': function(){
					this.addClass('over');
				},
				'mouseout': function(){
					this.removeClass('over');
				}
			}
		});
		
		//IE FIX		
		if(Browser.Engine.trident) {
			var img = new Element('img', {
				'src': '/static/images/js/slideshow/spacer.gif',
				'styles': {
					'width': '100%',
					'height': '100%'
				}
			});
			pauseDiv.appendChild(img);
		}
		
		return pauseDiv;
	},
	
	pauseShow: function() {
		if (!this.paused) {
			// Clear the timer
			$clear(this.timer);
			
			this.paused = true;
			
			this.pauseCtrl.addClass('paused');
			
			// If fxObj is set pause the running effect
			if($defined(this.fxObj))
				this.fxObj.pause();
		} else {
			// Run the slideshow
			this.runShow();
			
			this.paused = false;
			
			this.pauseCtrl.removeClass('paused');
			
			if($defined(this.fxObj))
				this.fxObj.resume();
		}
				
		return false;
	}
});