/**
 * listpager jquery plugin 
 * @usage:  jQuery("#mycontent").listpager();
 * @description: pages through given number of children with prev/next elements
 * @author: @mcn
 */
;(function(jQuery) {
	jQuery.fn.listpager = function(options){
		var nextSelectorIsArray=false,prevSelectorIsArray=false,numListItemsIsArray=false,startingIndexIsArray=false,_this=jQuery(this);
		
		if (typeof(options) == 'undefined') {
			var options = {};
		}
		// initialize defaults
		var defaultOptions = {
			startingIndex		: 0,
			numListItems 		: 3,
			nextSelector		: "#list-pager-next",
			prevSelector		: "#list-pager-prev",
			showNumericPager	: false
		};
		
		// override defaults
		for (var key in defaultOptions) {
			if (typeof options[key] == 'undefined') {
				options[key] = defaultOptions[key];
			}
		}
		
		if (typeof options.nextSelector  != 'string') {
			nextSelectorIsArray = true;
		}
		if (typeof options.prevSelector  != 'string') {
			prevSelectorIsArray = true;
		}
		if (typeof options.numListItems  != 'string') {
			numListItemsIsArray = true;
		}
		if (typeof options.startingIndex != 'string') {
			startingIndexIsArray = true;
		}

		// this is necessary to do an explicit cast to numeric because we are cutting out strings. 
		function add (one, two){
			return parseInt(one) + parseInt(two);
		}
		function subtract (two, one){
			return parseInt(two) - parseInt(one);
		}
		
		// Hide all but the next (n) 'children'
		var nextPane = function(id,idx,len) {
			hideContents(id);
			var maxChildren = _this.children().length;
			var nextIdx 	= add(idx, len) < maxChildren ? add(idx, len) : 0;
			_this.children().each(function(c){
				if (c >= nextIdx && c < add(nextIdx,len)) {
					jQuery(this).css("display", "");
				}
			});
			updateNumbers('#'+id+'-hidden',nextIdx,len);
		};
		
		// Hide all but the previous (n) children
		var prevPane = function(id,idx,len) {
			hideContents(id);
			var nextIdx = subtract(idx, len) > 0 ? subtract(idx,len) : 0;
			_this.children().each(function(c){
				if (c >= nextIdx && c < add(nextIdx,len)) {
					jQuery(this).css("display", "");
				}
			});
			updateNumbers('#'+id+'-hidden',nextIdx,len);
		};
		
		function updateNumbers (sel,idx,of) {
			var idx 	= "idx" + idx;
			var offset	= "offset" + of; 
			jQuery(sel).removeClass();
			jQuery(sel).addClass(idx).addClass(offset);
		}
		
		
		// hide all the contents
		var hideContents = function(id) {
			jQuery("#"+id).children().each(function(){
				jQuery(this).css("display", "none");
			});
		}
		
		// Takes string class attribute extracts idxNUM and offsetNUM, returns array or false;
		function extractIndexOffset(classAttr) {
			if (typeof classAttr == 'undefined' || classAttr == '' || classAttr == null) {
				return false;
			}
			idxPtrn 	= /idx(\d+)/;
			idxMatch 	= idxPtrn.exec(classAttr);
			offPtrn 	= /offset(\d+)/;
			offsetMatch = offPtrn.exec(classAttr);
			idx 		= typeof idxMatch[1]    != null ? idxMatch[1]    : new Array();
			offset 		= typeof offsetMatch[1] != null ? offsetMatch[1] : new Array();
			return new Array(idx,offset);
		}
		
		// Apply this plugin to the context of the given selector(s) only!  
		jQuery(this).each(function(e){
			
			var extracted;
			
			// set global _this to the current jQ object in this iteration of each()
			_this  = jQuery(_this);
			
			// Create a hidden Div after this list that stores the current pager values in the class.
			var id = _this.attr("id") != 'undefined' ? _this.attr("id") : 'listpager' + Math.floor(Math.random()*50000000);
			_this.after('<div id="' + id + '-hidden" class="idx'+options.startingIndex+' offset' + options.numListItems + '" style="display:none;"></div>');
			
			// Initial state(s) for options
			var nselector = !nextSelectorIsArray  ? jQuery(options.nextSelector)  : jQuery(options.nextSelector)[e];
			var pselector = !prevSelectorIsArray  ? jQuery(options.prevSelector)  : jQuery(options.prevSelector)[e];
			var len       = !numListItemsIsArray  ? jQuery(options.numListItems)  : jQuery(options.numListItems)[e];
			var sidx 	  = !startingIndexIsArray ? jQuery(options.startingIndex) : jQuery(options.startingIndex)[e];
			
			// Starting condition(s)
			nextPane(id,sidx,len);
			
			// Click Bindings for next/prev selector(s)
			nselector.click(function(ev){
				extracted = extractIndexOffset(jQuery("#"+id+'-hidden').attr('class'));
				nextPane(id,extracted[0],extracted[1]);
				return false;
			});
			pselector.click(function(ev){
				extracted = extractIndexOffset(jQuery("#"+id+'-hidden').attr('class'));
				prevPane(id,extracted[0],extracted[1]);
				return false;
			});
		});
	};
})(jQuery);
