/*
	Glossary:
	holder - the main holder into which everything goes
	pane - a pieces of content on the page that'll be animated through
	slideset - a container holding the three slides
	slides - three slides, one off to the left, the currently visible one, one off to the right, animating either way can then be handled by sliding the slideset.
	current - the current pane that's in the active (slide[1]) slide.
	animating - A flag that's put up whenever animating's happening to ensure no additional animation can get fired and clash with it until it's done.
 */
slider=function(settings) {
	// Store a self reference for use within nested functions
	var _that=this;

	// Allow the HTML classes, ids, etc. to be specified.
	// Additionally allow it to force starting on a specific image
	this.settings=jQuery.extend({
		holder: "#slider-holder",
		panes: ".slider-pane",
		current: 0
	}, settings);
	
	// jQuery wrap the holder and pane
	this.settings.holder=jQuery(this.settings.holder);
	this.settings.panes=jQuery(this.settings.panes);
	
	// Get the width and height
	this.height=this.settings.holder.height();
	this.width=this.settings.holder.width();
	
	// Ensure the requested "current" is within range
	this.settings.current=this.keepInRange(this.settings.current);
	
	// Hide all the panes as we'll be copying their HTML out of them rather than actually displaying them directly
	this.settings.panes.hide();
	
	// Create the slideset
	this.settings.holder.append('<div class="slider-slide-set"></div>');
	this.slideset=jQuery('.slider-slide-set', this.settings.holder);
	
	// Create a 3 position array of slides
	this.slide=[];
	for (i=0; i<3; i++) {
		// Create the HTML
		this.slideset.append('<div class="slider-slide slider-slide'+i+'"></div>');
		// Store a reference to its jQuery object
		this.slide[i]=jQuery('.slider-slide'+i, this.settings.holder);
		// Set the width and height to match the holder
		this.slide[i].css('width', this.width);
		this.slide[i].css('height', this.height);
		// Left position it within the slideset
		this.slide[i].css('left', this.width*i);
	}
	
	// Create the next and previous buttons
		this.settings.holder.append('<a href="#" class="slider-dir slider-prev">Prev</a>');
		this.settings.holder.append('<a href="#" class="slider-dir slider-next">next</a>');
	
	// Store references to the next and previous buttons
	this.prev=jQuery('.slider-prev', this.settings.holder);
	this.next=jQuery('.slider-next', this.settings.holder);

	// Bind the previous button
	this.prev.click(function(e) {
		e.preventDefault();
		_that.transition(-1);
	});
	// Bind the next button
	this.next.click(function(e) {
		e.preventDefault();
		_that.transition(1);
	});
	
	// Call an initial reset to make sure everything is set up properly
	this.resetPos();
	
	// Drop the animating flag so further animations will be allowed.
	this.animating=false;
}

/**
 * Takes any value and brings it back within range of the number of panes.
 * For example, if there were 7 panes and it received 22, it would return 1 - as 22 is position 1, three sets on.
 * This allows looping to run smoothly.
 */
slider.prototype.keepInRange=function(val) {
	// Get the number of panes
	var len=this.settings.panes.length;
	// Can't use % for < 0 reliably, so keep adding the number of panes until we're >= 0
	while (val<0) {
		val+=len;
	}
	// Now we're greater than zero, we can use % to bring too large numbers back in line
	val=val % len;
	return val;
}

/**
 * Reset the positions of the slides and slideset.
 * The main slide ensure's it's fully opaque.
 * The content of all three slides is updated
 */
slider.prototype.resetPos=function() {
	this.slideset.css('left', 0-this.width);
	this.slide[1].css('opacity', 1);
	// Get the previous, current and next panes, using keepInRange to handle looping
	var source=[];
	source[0]=jQuery(this.settings.panes[this.keepInRange(this.settings.current-1)]);
	source[1]=jQuery(this.settings.panes[this.keepInRange(this.settings.current)]);
	source[2]=jQuery(this.settings.panes[this.keepInRange(this.settings.current+1)]);
	// Copy the HTML from those panes to the slides
	this.slide[0].html(source[0].html());
	this.slide[1].html(source[1].html());
	this.slide[2].html(source[2].html());
}

/**
 * Handle transitions.
 * dir of -1 animated left, dir of 1 animates right.
 */
slider.prototype.transition=function(dir) {
	// Store a self reference for use within nested functions
	var _that=this;

	// Only allow anything to happen if the animating flag is currently down
	if (!this.animating) {
		// Put up the animating flag
		this.animating=true;
		// Ensure all of the states are initialized
		this.resetPos();
		
		// Calculate the new position for the slideset for it to slide to
		var newLeft=0;
		if (dir==1) {
			newLeft=0-2*this.width;
		}
		
		// Initially, fade out
		this.slide[1].animate({
			opacity: 0.1
		}, 500, function() {
			// Then, when complete, slide the slideset to its new position
			_that.slideset.animate({
				left: newLeft
			}, 1000, function() {
				// When that secondary animation is complete...
				// Store the new current position
				_that.settings.current=_that.keepInRange(_that.settings.current+dir);
				// Drop the animating flag as we're finished
				_that.animating=false;
			});
		});
	}
}