// Slider class, written by Ben, end Oct 2010.
// Apologies if it's a little messy below. It's all fairly straightforward, I just didn't plan anything
// before I wrote it. Should be super simple to use, follow the instructions in the comments below.

/* -----------------------------------------------------------------------------------------------------
   You need mootools, and moomore.
   
   <script src="/slider/slider.js" type="text/javascript"></script> 
	<script type="text/javascript"> 
		window.addEvent('domready', function() {
			var mySlider = new horizontalSlider('sliderBox', '#sliderBox .slide');
			// var mySlider = new horizontalSlider('sliderBox', '#sliderBox .slide', {playAtStart:false, slideTimer:4000});
			mySlider.startTimer();
		});
	</script>
   
	You must set a div with an ID for your slider box, and then inside give each slide a class. These are passed
	to the JS class as show above (with any options you want to include). I also recommend you wrap them all in
	another div otherwise the controls will just be built below. If you put them in another div and set the CSS 
	position to relative, this will enable you to absolutely position your controls on top of the sliding frames.
	Here's my HTML and css for a very basic slider:
	
	<div id="slider">
		<div id="sliderBox">
			<div class="slide">Slide 1</div>
			<div class="slide">Slide 2</div>
			<div class="slide">Slide 3</div>
		</div>
	</div>
	
	#slider {
		float: left;
		width: 960px;
		height: 400px;
		position: relative;
	}
		#sliderBox {
			float: left;
			width: 960px;
			height: 300px;
			overflow: hidden;
		}
			#sliderBox .slide {
				width: 960px;
				height: 300px;
				overflow: hidden;
			}
   
	What you do in #slider (if anything!) is up to you, but it's important you follow the same rules for the 
	SliderBox and the slides. Of course you can give your slides IDs (if you like), and you can style up any
	of the controls by using firebug to see the IDs / classes they're given. All these will be preceeded by 
	your sliderBox name and an underscore. In the example above: 'sliderBox_stop_button' for instance.
	Your CSS will determine the size of the slides / slider, so make sure it's all set correctly.
	
	Options:
	
	showLR: true/false         = show left and right controls
	showControls: true/false   = show links for the number slides (these can be targetted/styled by ID)
	slideTimer: 2000           = ms amount for how long to display the slide for
	transitionTime: 1000       = ms amount for how long to make the transition
	pauseOnHover: true/false   = if slider is playing, should it pause when you hover on a slide?
	cancelOnClick: true/false  = if slider is playing, should it cancel when you click a control?
	addPlayStop: true/false    = show the stop/play buttons
	playAtStart: true          = start playing automatically? (note you can set this as false and call mySlider.startTimer();)
	transName: Fx.Transitions.Quad.easeInOut  = mootools slide transition
   
*/

var horizontalSlider = new Class({
	
	//implements
	Implements: [Options],

	//options
	options: {
		showLR: true,
		showControls: true,
		slideTimer: 2000,
		transitionTime: 1000,
		pauseOnHover: true,
		cancelOnClick: true,
		addPlayStop: true,
		playAtStart: true,
		transName: Fx.Transitions.Quad.easeInOut
	},
	
	// Should be no need to change these.
	slideShowing:0,
	container: 'slider',
	slides: '#slider .slides',
	numSlides: 2,
	slideWidth: 500,
	sliderSliding: false,
	hasClickedStop: false,
	slideInProgress: false,
	
			
	//initialization
	initialize: function(container, el, options) {
		
		var moveTheSlide;
		
		this.setOptions(options);
		this.container       = container;
		this.containerSlides = el;
		
		//var containerDiv = $(container);
		
		var sliderSize   = $(container).getSize();
		var slideWidth   = sliderSize.x;
		this.slideWidth  = sliderSize.x;
		var slideHeight  = sliderSize.y;
		
		var items        = $$(el);
		this.totalSlides = items.length; // number of slide
		this.numSlides   = (items.length - 1); // because we start everything at 0
		
		var slideContent = $(container).get('html');
		
		$(container).set('html', '');
		$(container).setStyle('position', 'relative');
		
		var slideWrap = new Element('div', {
			//here you set all the element parameters
			'id': container + '_wrap',
			'html': '<div id="">' + slideContent + '</div>',
			'styles': {
				'width': (slideWidth * this.totalSlides),
				'height': slideHeight,
				'position': 'absolute',
				'top': 0,
				'left': 0
			}
		});
		slideWrap.inject($(this.container), 'top');
		
		useCard = 0;
		$$(el).each(function (e) {
			e.addClass(container + '_slide_' + useCard);
			e.setStyle('float', 'left');
			useCard++;
		});
		
		if (this.options.showControls == true) {
			this.addControls();
		}
		
		if (this.options.addPlayStop == true) {
			this.addPlayStop();
		}
		
		if (this.options.showLR == true) {
			this.addLRControls();
		}
		
		if (this.options.pauseOnHover == true) {
			$(container).addEvent('mouseover',function() {
				if (this.slider.sliderSliding == true) {
					this.slider.stopTimer();
				}
			});
			$(container).addEvent('mouseout',function() {
				if (this.slider.sliderSliding == false && this.slider.hasClickedStop == false) {
					this.slider.startTimer();
				}
			});
			$(container).slider = this;
		}
		
		if (this.options.playAtStart == true) {
			this.startTimer();
		} else {
			this.hasClickedStop = true;
		}
		
	},
	
	setOptions: function(options) {
		for(var i in options) {
			this.options[i] = options[i];
		}
	},
	
	addControls: function() {
		
		var controlsContainer = new Element('div', { 'id': this.container + '_controls_container' });
		controlsContainer.inject($(this.container), 'after');
		
		var ul = new Element('ul');
		for (var i = 0; i < this.totalSlides; i++) {
			if (i == 0) {
				showingClass = ' showing';
			} else {
				showingClass = '';
			}
			var li = new Element('li', { 'id': this.container+'_control_li_'+i, 'class': this.container + '_control_li' } );
			var a  = new Element('a', {	'href': 'javascript:void(0);',
										'id': this.container+'_control_'+i,
										'class': this.container+'_control_a' + showingClass,
										'html': i,
										'events':{'click':function() {
													this.slider.slideTo(this.i);
													if (this.slider.sliderSliding == true && this.slider.options.cancelOnClick == true) {
														this.slider.hasClickedStop = true;
														this.slider.stopTimer();
													}
												}
											}
										});
			a.i = i;
			a.slider = this;
			a.inject(li);
			li.inject(ul);
		}
		ul.inject(controlsContainer, 'top');

	},
	
	addPlayStop: function() {
		
		var playStopContainer = new Element('div', { 
				'id': this.container + '_playstop_container',
				'html': '<a id="' + this.container + '_stop_button" href="javascript:void(0);">Stop</a><a id="' + this.container + '_play_button" href="javascript:void(0);">Play</a>'
			});
		playStopContainer.inject($(this.container), 'after');
		
		$(this.container + '_stop_button').addEvent('click',function() {
			if (this.slider.sliderSliding == true) {
				this.slider.hasClickedStop = true;
				this.slider.stopTimer();
			}
		});
		$(this.container + '_stop_button').slider = this;
		$(this.container + '_stop_button').addClass('stopActive');
		
		$(this.container + '_play_button').addEvent('click',function() {
			if (this.slider.sliderSliding == false) {
				this.slider.hasClickedStop = false;
				this.slider.startTimer();
			}
		});
		$(this.container + '_play_button').slider = this;
		
		
	},
	
	addLRControls: function() {
		var leftA  = new Element('a', { 'id': this.container + '_left_control', 
										'text': '<', 
										'href': 'javascript:void(0);',
										events:{'click':function() {
													this.slider.slideTo('last');
													if (this.slider.sliderSliding == true && this.slider.options.cancelOnClick == true) {
														this.slider.hasClickedStop = true;
														this.slider.stopTimer();
													}
												}
											}
										});
		var rightA = new Element('a', { 'id': this.container + '_right_control', 
										'text': '>', 
										'href': 'javascript:void(0);', 
										events:{'click':function() {
													this.slider.slideTo('next');
													if (this.slider.sliderSliding == true && this.slider.options.cancelOnClick == true) {
														this.slider.hasClickedStop = true;
														this.slider.stopTimer();
													}
												}
											}
										});
		leftA.slider  = this;
		rightA.slider = this;
		
		rightA.inject($(this.container), 'after');
		leftA.inject($(this.container), 'after');

	},
	
	slideTo: function(slideNum) {
		// Here we slide to where we need to go.
		// Check if we're going to next or last, or an actual slide. Regardless, get a slide number
		
		if (slideNum == 'next' || slideNum == null) {
			if (this.slideShowing + 1 > this.numSlides) {
				slideNum = 0;
			} else {
				slideNum = this.slideShowing + 1;
			}
		} else if (slideNum == 'last') {
			if (this.slideShowing - 1 < 0) {
				slideNum = this.numSlides;
			} else {
				slideNum = this.slideShowing - 1;
			}
		}
		
		// Check we've actually got to slide (as in someone hasn't clicked the slide we're on)
		if (slideNum != this.slideShowing) {
			goToPixels = (slideNum * this.slideWidth);
			
			if (this.slideInProgress == true) {
				if (this.sliderSliding == true) {
					this.stopTimer();
					moveTheSlide.cancel();
					this.startTimer();
				} else {
					moveTheSlide.cancel();
				}
				
			}
			
			this.slideInProgress = true;
			moveTheSlide = new Fx.Morph(this.container + '_wrap',{duration: this.options.transitionTime, transition: this.options.transName,
				onComplete: function () { this.slider.slideInProgress = false; }
			}).start({'left': '-'+ goToPixels +'px'});
			moveTheSlide.slider = this;
			
			if (this.options.showControls == true) {
				for (var i = 0; i < this.totalSlides; i++) {
					$(this.container+'_control_'+i).removeClass('showing');
					$(this.container+'_control_li_'+i).removeClass('showing');
				}
				$(this.container+'_control_' + slideNum).addClass('showing');
				$(this.container+'_control_li_' + slideNum).addClass('showing');
			}

			this.slideShowing = slideNum;
		}
		
	},
	
	startTimer: function() {
		// not removing classes for stop?
		this.sliderSliding = true;
		if (this.options.addPlayStop == true) {
			$(this.container + '_play_button').addClass('playActive');
			$(this.container + '_stop_button').removeClass('stopActive');
		}
		this.slideId = this.slideTo.periodical((this.options.slideTimer + this.options.transitionTime), this);
	},
	
	stopTimer: function() {
		this.sliderSliding = false;
		if (this.options.addPlayStop == true) {
			$(this.container + '_play_button').removeClass('playActive');
			$(this.container + '_stop_button').addClass('stopActive');
		}
		clearInterval(this.slideId);
	}
	

	
});
