/*
	Scrollable Panel Plugin.
	
	Takes an element and makes it scrollable (horizonal or vertical). The
	scrolling always occurs one page at a time.
	
	Usage:
		Call pageScroll passing in the element (any valid jQuery selector) that
		you want to make scrollable. Eg:
		
		Azexis.pageScroll("#myid");
		
		This will return an object to interact with and add events to.
		
		The HTML structure should match the following:
		
		<div id="outer">
			<div id="myid">
				<div></div>
				<div></div>
				<div></div>
			</div>
		</div>
		
		#outer will have overflow:hidden applied to it, and #myid will be given
		the size of its children. Any child elements may be inserted below
		#myid, but only the direct children will be used in page calculations.
		
	Events:
		moveComplete:
			Called whenever an object has finished moving toa given page.
			
	Options:
		duration:
			Time taken to switch pages.
			
		easing:
			Any valid jQuery easing type, used to animate the page changes.
			
		horizontal:
			Select whether page scrolling is horizonal (default) or vertical.
*/

var Azexis = Azexis || {};

(function($) {
	
	Azexis.pageScroll = function(el, options) {
		var opts = $.extend({}, Azexis.pageScroll.defaults, options);
		var el = $(el);
		var pub = Azexis.events();
		
		var animating = false;
		
		var dir = opts.horizontal ? "left" : "top";
		var width = "width";
		
		// Get full width/height of the elements.
		var totalDist = 0;
		el.children().each(function() {
			totalDist += opts.horizontal ?
				$(this).outerWidth(true) : $(this).outerHeight(true);
		});
		
		// Setup some required attributes.
		el.parent().css("overflow", "hidden");
		el.css("position", "relative");
		
		if (opts.horizontal) {
			el.css("width", totalDist);
		} else {
			el.css("height", totalDist);
		}
		
		
		var scrollDist = opts.horizontal ?
			el.parent().innerWidth() : el.parent().innerHeight();
		
		function slide(pred, dist) {
			if (animating || !pred()) {
				return false;
			}
			
			var dist = el.position()[dir] + dist;
			
			var animOpts = {};
			animOpts[dir] = dist;
			
			el.animate(animOpts, opts.duration, opts.easing, function() {
				animating = false;
				pub.trigger("moveComplete", pub);
			});
			
			animating = true;
			return true;
		}
		
		// Public interface.
		pub.next = function() {			
			return slide(pub.hasNextPage, -scrollDist);
		};
		
		pub.prev = function() {
			return slide(pub.hasPrevPage, scrollDist);
		};
		
		pub.hasNextPage = function() {
			return -(el.position()[dir]) + scrollDist < totalDist;
		};
		
		pub.hasPrevPage = function() {
			return el.position()[dir] < 0;
		};
		
		pub.page = function() {
			return -(el.position()[dir]) / scrollDist;
		};
		
		pub.pages = function() {
			return totalDist / scrollDist;
		};
		
		return pub;
	};
	
	// Allow access to defaults.
	Azexis.pageScroll.defaults = {
		duration: 500,
		easing: "swing",
		horizontal: true
	};
	
})(jQuery);

