/*
Developed and tested using jquery 1.3.2

Example usage:
<head>
	...
	<link rel="stylesheet" href="/cirkuit/includes/js/jquery/plugins/paginationBox/1.0/theme-greyred.css">
	<script type="text/javascript" src="/cirkuit/includes/js/jquery/plugins/paginationBox/1.0/jquery.paginationBox-min.js"></script>
	<script type="text/javascript">
		$(function(){
			$('#paginationBoxSection').paginationBox({
				itemSelector: '.p_item',
				title: 'Browse',
				itemsPerPage: 4
			});
		});
	</script>
	<style>
		.p_item{
			width: 192px;
			float:left;
			text-align: center;
			padding: .5em 0 1em;
			border-bottom: 1px solid #ccc; //for when viewing all item
		}
		...
	</style>
	...
<head>
<body>
	...
	<div id="paginationBoxSection">
		<div class="p_item">
			(whatever content you want so long as it has a set width and height and is floated left. see css rules above)
		</div>
		<div class="p_item">
			(whatever content you want so long as it has a set width and height and is floated left. see css rules above)
		</div>
		(etc)
	</div>
	...
</body>
*/
(function($) {
	$.fn.paginationBox = function(options){
		options = $.extend({}, $.fn.paginationBox.defaults, options);
		return $(this).each(function(){
			var $this = $(this);
			$this.$items = $(options.itemSelector, this);
			$this.numItems = $this.$items.length;
			if ($this.numItems === 0) {
				return false; //no items selected
			}

			//hide all items. will show only what we need to later
			$this.$items.hide();

			$this.numPages = Math.ceil($this.numItems / options.itemsPerPage);
			$this.currentPage = 1;
			$this.showingAll = false;


			/* building markup */

			//build markup for before items
			var markupBefore = '\
					<div class="p_title">\
						'+options.title+'\
					</div>\
					<div class="p_nav">'
			if ($this.numPages > 1) {
				markupBefore += '\
						<ul>\
							<li class="p_active" title="View Page 1">1</li>';
				for (var i = 2; i <= $this.numPages; i++) {
					markupBefore += '<li title="View Page ' + i + '">' + i + '</li>';
				}
				markupBefore += '\
						</ul>';
			}
			markupBefore += '\
						<span class="p_numItems">Showing 1-' + ($this.numItems < options.itemsPerPage ? $this.numItems : options.itemsPerPage) + ' of '+$this.numItems+' items</span>\
					</div>\
			';
			$markupBefore = $(markupBefore);

			//build markup for after items
			if ($this.numPages > 1) {
				var markupAfter = '\
					<div class="p_prevBtn" title="Previous Page"></div>\
					<div class="p_nextBtn" title="Next Page"></div>';
			}
			markupAfter += '<div class="p_clear"></div>';
			if($this.numPages > 1){
					markupAfter += '<div class="p_showAll" title="Show All">Expand To See All</div>';
			}
			$markupAfter = $(markupAfter);


			/* altering markup */

			//wrap a container around everything
			$this.wrap('<div class="p_container" />');
			$this.container = $this.parent(); //ref to .p_container

			//add markup before and after
			$markupBefore = $markupBefore.insertBefore(this);
			$markupAfter.insertAfter(this);
			$this.wrap('<div class="p_itemContainer" />');

			$this.$navLIs = $('.p_nav li', $this.container); //save nav to var for optimization
			$this.$navTxt = $('.p_numItems', $this.container); //save nav text to var for optimization

			//show only items we should
			$this.$items.slice(0,options.itemsPerPage).show();


			/* click events */

			//auxillary helper for click events
			$this.showPageNum = function(pageNum, callback){
				var startSlice = (pageNum-1) * options.itemsPerPage;
				var endSlice = ((pageNum-1) * options.itemsPerPage) + options.itemsPerPage;
				if(endSlice > $this.numItems){
					endSlice = $this.numItems;
				}

				//called after the items are hidden to show the new items
				$this.hideAnimationCompleteCallback = function(){
					$this.css({
						position:'static',
						left: 0,
						'height':$this.parent().height()
					});
					$this.css('opacity','');
					$this.$items.hide();
					$this.$items.slice(startSlice, endSlice).fadeIn(options.itemFadeInSpeed, callback);
					$this.css('height','');
					$this.currentPage = pageNum;

					$this.$navLIs.removeClass('p_active').eq(pageNum - 1).addClass('p_active');

					$this.$navTxt.text('Showing ' + (startSlice + 1) + '-' + endSlice + ' of ' + $this.numItems + ' items');

					$('.p_prevBtn, .p_nextBtn', $this.container).show();
					if (pageNum <= 1) {
						pageNum = 1;
						$('.p_prevBtn', $this.container).hide();
					}
					if (pageNum >= $this.numPages) {
						pageNum = $this.numPages;
						$('.p_nextBtn', $this.container).hide();
					}
				}

				//hide items by sliding them out
				if ($.browser.msie && parseInt(jQuery.browser.version.substr(0, 1)) <= 7) {
					$this.animate({
							opacity: 0
						}, {
							duration: options.itemFadeInSpeed/2,
							complete: $this.hideAnimationCompleteCallback
						});
				}
				else {
					$this.css('position', 'relative');
					if ($this.currentPage < pageNum) { //slide left
						$this.animate({
							left: '-110%'
						}, {
							duration: options.itemSlideOutSpeed,
							complete: $this.hideAnimationCompleteCallback
						});
					}
					else { //slide right
						$this.animate({
							left: '101%'
						}, {
							duration: options.itemSlideOutSpeed,
							complete: $this.hideAnimationCompleteCallback
						});
					}
				}
			}

			//clicked a nav item
			$('.p_nav li', $this.container).click(function(){
				if($this.showingAll){ //functionality disabled when showing all
					return false;
				}
				var $navLi = $(this);
				if($navLi.hasClass('.p_active')){ //if already active, do nothing
					return false;
				}
				var navItemNum = parseInt($navLi.text());

				$this.showPageNum(navItemNum);
				return false;
			});

			//clicked next button
			$('.p_nextBtn', $this.container).click(function(){
				if($this.showingAll){ //functionality disabled when showing all
					return false;
				}
				if ($this.currentPage < 1) {
					$this.currentPage = 1;
				}
				if ($this.currentPage >= $this.numPages) {
					$this.currentPage = $this.numPages;
					return false; //cannot go next when on last page
				}
				$this.showPageNum($this.currentPage + 1);
				return false;
			});

			//clicked prevoius button
			$('.p_prevBtn', $this.container).click(function(){
				if($this.showingAll){ //functionality disabled when showing all
					return false;
				}
				if ($this.currentPage <= 1) {
					$this.currentPage = 1;
					return false; //cannot go prev when on first page
				}
				if ($this.currentPage > $this.numPages) {
					$this.currentPage = $this.numPages;
				}
				$this.showPageNum($this.currentPage - 1);
				return false;
			});

			//clicked show-all button
			$('.p_showAll', $this.container).click(function(){
				if(!$this.showingAll){ //show all
					$this.$items.show();
					$this.$navTxt.text($this.numItems+' items');
					$('.p_prevBtn, .p_nextBtn, .p_nav ul', $this.container).hide();
					$this.showingAll = true;

					$(this).html("Collapse").addClass('collapse').hide().show();
				}
				else { //hide all
					var $collapseButton = $(this);
					$this.showPageNum(1, function(){
						$collapseButton.fadeIn(100);
					});
					$('.p_nav ul', $this.container).show();
					$this.showingAll = false;
					$collapseButton.hide().html("Expand To See All").removeClass('collapse');
				}
			});
		});
	};

	/*
		OPTIONS
	*/
	$.fn.paginationBox.defaults = {
		itemSelector: '.p_item', //the selector within $this that is used to select the items that should be paginated
		title: 'Browse',
		itemsPerPage: 4,
		itemSlideOutSpeed: 250, //milliseconds
		itemFadeInSpeed: 200 //milliseconds
	};
})(jQuery);

