/**
 * pagination - jQuery jwwUI Copyright (c) 2013-2015 www.jeeww.com. All rights reserved. 
 * Licensed under the GPL or commercial licenses 
 */
(function($) {
	function create(target) {
		var pagination = $.data(target, "pagination");
		var definations = pagination.definations;
		var bb = pagination.bb = {};
		var pagerObj = $(target).addClass("pagination").html(
		        "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr></tr></table>");
		var tr = pagerObj.find("tr");
		function renderPagerButton(buttonFlag) {
			var navButton = definations.nav[buttonFlag];
			var a = $("<a href=\"javascript:void(0)\"></a>").appendTo(tr);
			a.wrap("<td></td>");
			a.linkbutton({ iconCls : navButton.iconCls, plain : true }).unbind(".pagination").bind("click.pagination",
			        function() {
				        navButton.handler.call(target);
			        });
			return a;
		}
		;
		if (definations.showPageList) {
			var ps = $("<select class=\"pagination-page-list\"></select>");
			ps.bind("change", function() {
				definations.pageSize = parseInt($(this).val());
				definations.onChangePageSize.call(target, definations.pageSize);
				selectByPageNumber(target, definations.pageNumber);
			});
			for ( var i = 0; i < definations.pageList.length; i++) {
				$("<option></option>").text(definations.pageList[i]).appendTo(ps);
			}
			$("<td></td>").append(ps).appendTo(tr);
			$("<td><div class=\"pagination-btn-separator\"></div></td>").appendTo(tr);
		}
		bb.first = renderPagerButton("first");
		bb.prev = renderPagerButton("prev");
		$("<td><div class=\"pagination-btn-separator\"></div></td>").appendTo(tr);
		$("<span style=\"padding-left:6px;\"></span>").html(definations.beforePageText).appendTo(tr).wrap("<td></td>");
		bb.num = $("<input class=\"pagination-num\" type=\"text\" value=\"1\" size=\"2\">").appendTo(tr).wrap(
		        "<td></td>");
		bb.num.unbind(".pagination").bind("keydown.pagination", function(e) {
			if (e.keyCode == 13) {
				var number = parseInt($(this).val()) || 1;
				selectByPageNumber(target, number);
				return false;
			}
		});
		bb.after = $("<span style=\"padding-right:6px;\"></span>").appendTo(tr).wrap("<td></td>");
		$("<td><div class=\"pagination-btn-separator\"></div></td>").appendTo(tr);
		bb.next = renderPagerButton("next");
		bb.last = renderPagerButton("last");
		if (definations.showRefresh) {
			$("<td><div class=\"pagination-btn-separator\"></div></td>").appendTo(tr);
			bb.refresh = renderPagerButton("refresh");
		}
		if (definations.buttons) {
			$("<td><div class=\"pagination-btn-separator\"></div></td>").appendTo(tr);
			for ( var i = 0; i < definations.buttons.length; i++) {
				var buttons = definations.buttons[i];
				if (buttons == "-") {
					$("<td><div class=\"pagination-btn-separator\"></div></td>").appendTo(tr);
				} else {
					var td = $("<td></td>").appendTo(tr);
					$("<a href=\"javascript:void(0)\"></a>").appendTo(td).linkbutton(
					        $.extend(buttons, { plain : true })).bind("click", $.parser.localEval(buttons.handler || function() {
					}));
				}
			}
		}
		$("<div class=\"pagination-info\"></div>").appendTo(pagerObj);
		$("<div style=\"clear:both;\"></div>").appendTo(pagerObj);
	}
	;
	function selectByPageNumber(target, number) {
		var definations = $.data(target, "pagination").definations;
		var pageNumber = Math.ceil(definations.total / definations.pageSize) || 1;
		definations.pageNumber = number;
		if (definations.pageNumber < 1) {
			definations.pageNumber = 1;
		}
		if (definations.pageNumber > pageNumber) {
			definations.pageNumber = pageNumber;
		}
		refreshPager(target, { pageNumber : definations.pageNumber });
		definations.onSelectPage.call(target, definations.pageNumber, definations.pageSize);
	}
	;
	function refreshPager(target, definationsParam) {
		var definations = $.data(target, "pagination").definations;
		var bb = $.data(target, "pagination").bb;
		$.extend(definations, definationsParam || {});
		var ps = $(target).find("select.pagination-page-list");
		if (ps.length) {
			ps.val(definations.pageSize + "");
			definations.pageSize = parseInt(ps.val());
		}
		var pageNumber = Math.ceil(definations.total / definations.pageSize) || 1;
		bb.num.val(definations.pageNumber);
		bb.after.html(definations.afterPageText.replace(/{pages}/, pageNumber));
		var displayMsg = definations.displayMsg;
		displayMsg = displayMsg.replace(/{from}/, definations.total == 0 ? 0 : definations.pageSize * (definations.pageNumber - 1)
		        + 1);
		displayMsg = displayMsg.replace(/{to}/, Math.min(definations.pageSize * (definations.pageNumber), definations.total));
		displayMsg = displayMsg.replace(/{total}/, definations.total);
		$(target).find("div.pagination-info").html(displayMsg);
		bb.first.add(bb.prev).linkbutton({ disabled : (definations.pageNumber == 1) });
		bb.next.add(bb.last).linkbutton({ disabled : (definations.pageNumber == pageNumber) });
		loadHandel(target, definations.loading);
	}
	;
	function loadHandel(target, loading) {
		var definations = $.data(target, "pagination").definations;
		var bb = $.data(target, "pagination").bb;
		definations.loading = loading;
		if (definations.showRefresh) {
			if (definations.loading) {
				bb.refresh.linkbutton({ iconCls : "pagination-loading" });
			} else {
				bb.refresh.linkbutton({ iconCls : "pagination-load" });
			}
		}
	}
	;
	$.fn.pagination = function(definations, param) {
		if (typeof definations == "string") {
			return $.fn.pagination.methods[definations](this, param);
		}
		definations = definations || {};
		return this.each(function() {
			var newDefinations;
			var pagination = $.data(this, "pagination");
			if (pagination) {
				newDefinations = $.extend(pagination.definations, definations);
			} else {
				newDefinations = $.extend({}, $.fn.pagination.defaults, $.fn.pagination.parseDefinations(this), definations);
				$.data(this, "pagination", { definations : newDefinations });
			}
			create(this);
			refreshPager(this);
		});
	};
	$.fn.pagination.methods = { definations : function(jq) {
		return $.data(jq[0], "pagination").definations;
	}, loading : function(jq) {
		return jq.each(function() {
			loadHandel(this, true);
		});
	}, loaded : function(jq) {
		return jq.each(function() {
			loadHandel(this, false);
		});
	}, refresh : function(jq, definations) {
		return jq.each(function() {
			refreshPager(this, definations);
		});
	}, select : function(jq, pageNumber) {
		return jq.each(function() {
			selectByPageNumber(this, pageNumber);
		});
	} };
	$.fn.pagination.parseDefinations = function(target) {
		var t = $(target);
		return $.extend({}, $.parser.parseDefinations(target, [
		        { total : "number", pageSize : "number", pageNumber : "number" },
		        { loading : "boolean", showPageList : "boolean", showRefresh : "boolean" } ]), { pageList : (t
		        .attr("pageList") ? $.parser.localEval(t.attr("pageList")) : undefined) });
	};
	$.fn.pagination.defaults = { total : 1, pageSize : 10, pageNumber : 1, pageList : [ 10, 20, 30, 50 ],
	    loading : false, buttons : null, showPageList : true, showRefresh : true,
	    onSelectPage : function(pageNumber, pageSize) {
	    }, onBeforeRefresh : function(pageNumber, pageSize) {
	    }, onRefresh : function(pageNumber, pageSize) {
	    }, onChangePageSize : function(pageSize) {
	    }, beforePageText : "Page", afterPageText : "of {pages}",
	    displayMsg : "Displaying {from} to {to} of {total} items",
	    nav : { first : { iconCls : "pagination-first", handler : function() {
		    var definations = $(this).pagination("definations");
		    if (definations.pageNumber > 1) {
			    $(this).pagination("select", 1);
		    }
	    } }, prev : { iconCls : "pagination-prev", handler : function() {
		    var definations = $(this).pagination("definations");
		    if (definations.pageNumber > 1) {
			    $(this).pagination("select", definations.pageNumber - 1);
		    }
	    } }, next : { iconCls : "pagination-next", handler : function() {
		    var definations = $(this).pagination("definations");
		    var pageNumber = Math.ceil(definations.total / definations.pageSize);
		    if (definations.pageNumber < pageNumber) {
			    $(this).pagination("select", definations.pageNumber + 1);
		    }
	    } }, last : { iconCls : "pagination-last", handler : function() {
		    var definations = $(this).pagination("definations");
		    var pageNumber = Math.ceil(definations.total / definations.pageSize);
		    if (definations.pageNumber < pageNumber) {
			    $(this).pagination("select", pageNumber);
		    }
	    } }, refresh : { iconCls : "pagination-refresh", handler : function() {
		    var definations = $(this).pagination("definations");
		    if (definations.onBeforeRefresh.call(this, definations.pageNumber, definations.pageSize) != false) {
			    $(this).pagination("select", definations.pageNumber);
			    definations.onRefresh.call(this, definations.pageNumber, definations.pageSize);
		    }
	    } } } };
})(jQuery);
