/**
*	ajax_pagination.js - zawiera klasę do stronicowania pobieranych partiami (z użyciem Ajaxa) wyników 
*
*	Wymagana biblioteka jQuery
*	
	PRZYKŁAD UŻYCIA
	
	osadzenie js w kodzie html (najlepiej w head):

	<script type="text/javascript">
	<!--
		$(document).ready(function() {
			new bmAjaxPagination('klasa1', 32, 'plugin1', 'pobieranie danych...');
		});
	//-->
	</script>


	w body:

	<div class="klasa1">
		<div class="pag_content"></div>
		<div class="nav"></div>
	</div>
	
	
	w pliku ajax.php plugina 'plugin1'
	
		odbieramy dane POST:
	
		$this->_post['items_per_page'];
		$this->_post['current_page'];
		
		renderujemy kod XML na wzór
		
		<pag_data>
			<pag_content>
				<![CDATA[ <!--TU HTML Z TREŚCIĄ AKTUALNEJ STRONY WYNIKÓW--> ]]>
			</pag_content>
			<pages_number><!--TU ILOŚĆ STRON WYNIKÓW--></pages_number>
		</pag_data>
	
	
*	POLE PRZEJDŹ DO STRONY - wystarczy stworzyć pole tekstowe o klasie "pagination-go-to-page"
*	i element do kliknięcia (przycisk, link, obrazek) o klasie "submit-arrow".
*	Oba te elementy muszą znajdować się wewnątrz bloku o klasie określonej w parametrze className.
	
*/

// Czwarty parametr jest opcjonalny - gdy jest używany, elementy do paginacji muszą mieć określoną klasę
function bmAjaxPagination(className, itemsPerPage, ajaxPlugin, loadHtml, visibleLinks, callback, params) {
	// --- CONFIG ----
	this.prevPageStr = '« Poprzednia strona';
	this.nextPageStr = 'Następna strona »';
	// --- end CONFIG ---
	
	this.className = className;
    this.itemsPerPage = itemsPerPage;
    this.loadHtml = loadHtml;
	this.visibleLinks = visibleLinks;
	this.currentPage;
	this.pagesNumber = 1;
	this.params = params ? params : null;
	
	this.init = function() {
		this.setPage(0);
		
		var bmpagTmp = this;
		
		
		$('.' + bmpagTmp.className + ' .nav a').die('click');
		$('.' + bmpagTmp.className + ' .nav a').live('click', function(e) {
			e.preventDefault();
			var page = $(this).attr('page');
			if(page === 'prev') {
				bmpagTmp.prevPage(bmpagTmp.currentPage);
			} else if (page === 'next') {
				bmpagTmp.nextPage(bmpagTmp.currentPage);
			} else {
				bmpagTmp.setPage($(this).attr('page'));
			}
		});
		
		$('.' + bmpagTmp.className + ' .submit-arrow').die('click');
		$('.' + bmpagTmp.className + ' .submit-arrow').live('click', function(e) {
			e.preventDefault();
			bmpagTmp.setPage($('.' + bmpagTmp.className + ' .pagination-go-to-page').val() - 1);
		});
	};
	
    this.setPage = function(page) {
		this.currentPage = page;
		updatePageContent(this);
    };
	
	this.prevPage = function(page) {
		if(this.currentPage > 0) {
			this.currentPage--;
			updatePageContent(this);
		}
	};
	
	this.nextPage = function(page) {
		if(this.currentPage < this.pagesNumber - 1) {
			this.currentPage++;
			updatePageContent(this);
		}
	};
	
	
	// --- Private functions ---
	
	function updateNav(bmpag) {
		var navHtml = getNav(bmpag);
		$('.' + bmpag.className + ' .nav').html(navHtml);
	}
	
	function getNav(bmpag) {
		var aLinks = prepareVisibleLinks(bmpag);
	
		var result = '';
		if(bmpag.currentPage > 0) {
			result += '<a class="prev" page="prev" href="#">' + bmpag.prevPageStr + '</a>';
		} else {
			result += '<span class="prev">' + bmpag.prevPageStr + '</span>';
		}
		
		result += ' <span>|</span> ';
		var first = true;
		for(var i in aLinks) {
			if(first) {
				first = false;
			} else {
				result += ' ';
			}
			if((aLinks[i-1] && aLinks[i] - aLinks[i-1] > 1) || (aLinks[i+1] && aLinks[i+1] - aLinks[i] > 1)) {
				result += ' <span class="current">...</span> <span>|</span> ';
			}
			if(aLinks[i] - 1 == bmpag.currentPage) {
				result += ' <span class="current">' + aLinks[i] + '</span> <span>|</span> ';
			} else {
				result += '<a page="' + (aLinks[i] - 1) + '" href="#">' + aLinks[i] + '</a> <span>|</span> ';
			}
		}
		
		if(bmpag.currentPage < bmpag.pagesNumber - 1) {
			result += '<a class="next" page="next" href="#">' + bmpag.nextPageStr + '</a>';
		} else {
			result += '<span class="next">' + bmpag.nextPageStr + '</span>';
		}
		return result;
	}
	
	function updatePageContent(bmpag) {
		var p = '';
		if(bmpag.params) {
			$.each(bmpag.params, function(index, value) { 
				p += "&" + index + '=' + value;
			});
		}
		$.ajax({
			url: "/ajax.php",
			type: "POST",
			data: "plugin_name="+ajaxPlugin+"&items_per_page=" + bmpag.itemsPerPage + "&current_page=" + (parseInt(bmpag.currentPage) + 1) + p,
			beforeSend: function() {
				bmpag.prevPageContent = $('.' + bmpag.className + ' .pag_content').html();
				if(loadHtml) {
					$('.' + bmpag.className + ' .pag_content').html(loadHtml);
				}
			},
			success: function(xml) {
				var pagesNumber = parseInt($("pages_number", xml).text());
				
				if(bmpag.currentPage >= 0 && bmpag.currentPage < pagesNumber) {
					$('.' + bmpag.className + ' .pag_content').html($("pag_content", xml).text());
					bmpag.pagesNumber = pagesNumber;
					updateNav(bmpag);
				} else {
					$('.' + bmpag.className + ' .pag_content').html(bmpag.prevPageContent);
				}
				if(callback){
					callback();
				}
			},
			complete: function() {
				
			}
		});
	}
	
	function prepareVisibleLinks(bmpag) {
		var aResult = new Array();
		if(!bmpag.visibleLinks) {
			bmpag.visibleLinks = 7;
		}
		if(bmpag.visibleLinks < 5) {
			bmpag.visibleLinks = 5;
		}
		
		if(bmpag.visibleLinks >= bmpag.pagesNumber) {
			for(var i = 1; i <= bmpag.pagesNumber; i++) {
				aResult.push(i);
			}
		} else {
			var surroundingsCount = bmpag.visibleLinks - 2;
			var surroundingsBegin = parseInt(bmpag.currentPage) + 1 - Math.floor((surroundingsCount - 1)/2);
			var surroundingsEnd = parseInt(bmpag.currentPage) + 1 + parseInt(Math.ceil((surroundingsCount - 1)/2));
			
			if(surroundingsBegin < 2) {
				surroundingsBegin = 2;
				surroundingsEnd = surroundingsBegin + surroundingsCount - 1;
			}
			if(surroundingsEnd > bmpag.pagesNumber - 1) {
				surroundingsEnd = bmpag.pagesNumber - 1;
				surroundingsBegin = surroundingsEnd - surroundingsCount + 1;
			}
			
			aResult.push(1);
			for(var i = surroundingsBegin; i <= surroundingsEnd; i++) {
				aResult.push(i);
			}
			aResult.push(parseInt(bmpag.pagesNumber));
		}
		
		return aResult;
	}
	this.init();
}

