(function ($) {
	$.fn.displetTablePager = function (options) {
		var container = $(this);
		var defaults = {
			'items_selector': 'table.displetlistings tr',
			'items_per_page': 4,
			'pages_elastic_threshold': 10
		};

		var settings = $.extend(defaults, options);

		function Pages(config) {
			this.current_page = 1;
			this.items = config.items;
			this.pages_count = Math.ceil(config.items.length / config.items_per_page);
			this.controls = config.controls;
			this.items_per_page = config.items_per_page;
			this.elastic_threshold = config.pages_elastic_threshold;
			this.last_index = config.items.length - 1;
			// alert(this.last_index);
			this.items.hide();
			this.draw();

			var minheight = container.height();
			container.css('min-height', minheight);
		}

		Pages.prototype.next_page = function () {
			this.hide_previous();
			// alert(this.items_per_page);
			if (this.current_page < this.pages_count) {
				this.current_page++;
				// alert(this.current_page);
			}
			this.draw();
		};

		Pages.prototype.previous_page = function () {
			this.hide_previous();
			if (this.current_page != 1) {
				this.current_page--;
				// alert(this.current_page);
			}
			this.draw();
		};

		Pages.prototype.draw = function () {
			var first;
			var last;

			// alert(this.items_per_page);

			if (this.current_page === 1) {
				first = 0;
				last = this.items_per_page - 1;
			}
			else {
				first = ((this.current_page - 1) * this.items_per_page);
				last = first + Number(this.items_per_page) - 1;
				if (last > this.last_index) {
					last = this.last_index;
				}
			}

			// alert('Show ' + first + ' -> ' + last);

			var i = first;
			for (; i <= last; i++) {
				$(this.items[i]).show();
			}

			this.draw_buttons();
			this.draw_page_info();
		};

		Pages.prototype.draw_buttons = function () {
 			if (this.current_page === 1) {
				this.controls.previous_button.hide();
				this.controls.previous_button.hidden = true; // saves a dom call
			}
			else if (this.controls.previous_button.hidden === true) {
				this.controls.previous_button.show();
			}

			if (this.current_page === this.pages_count) {
				this.controls.next_button.hide();
				this.controls.next_button.hidden = true;
			}
			else if (this.controls.next_button.hidden === true) {
				this.controls.next_button.show();
			}
		}

		Pages.prototype.draw_page_info = function () {
			var current_page = this.current_page;
			var pages_count = this.pages_count;
			var page_info = this.controls.page_info;
			var elastic_threshold = this.elastic_threshold;
			var draw_first = false;
			var draw_last = false;
			var that = this;
			var button;

			this.controls.page_info.empty();

			var i;
			if (pages_count > elastic_threshold) {
				var median = Math.floor(elastic_threshold / 2);

				if (current_page > median) {
					if ((current_page + median) >= pages_count ) {
						i = pages_count - elastic_threshold + 1;
						last = pages_count;
						draw_first = true;
					}
					else {
						i = current_page - median;
						last = current_page + median;
						draw_first = true;
						draw_last = true;
					}
				}
				else {
					i = 1;
					var last = elastic_threshold;
					draw_last = true;
				}
			}
			else {
				i = 1;
				var last = pages_count;
			}

			if (draw_first) {
				$('<a href="#" class="page_button first_page">1</a>')
					.appendTo(page_info)
					.click(function () {
						that.seek(1);
						return false;
					});
				$('<span class="continuation">...</span>').appendTo(page_info);
			}

			for (i; i <= last; i++) {
				if (i !== Number(current_page)) {
					button = $('<a href="#" class="page_button">'
							+ i + '</a>')
						.appendTo(page_info);

					button.click(function () {
						that.seek($(this).text());
						return false;
					});
				}
				else {
					$('<span class="current_page">' + i + '</span>').appendTo(page_info);
				}
			}

			if (draw_last) {
				$('<span class="continuation">...</a>').appendTo(page_info);
				$('<a href="#" class="page_button last_page">' + pages_count + '</a>')
					.appendTo(page_info)
					.click(function () {
						that.seek(pages_count);
						return false;
					});
			}
		};

		Pages.prototype.seek = function (page_number) {
			this.current_page = Number(page_number);
			this.items.hide();
			this.draw();
		};

		Pages.prototype.hide_previous = function () {
			var first;
			var last;

			if (this.current_page === 1) {
				first = 0;
				last = this.items_per_page - 1;
			}
			else {
				first = ((this.current_page - 1) * this.items_per_page);
				last = first + this.items_per_page - 1;
				if (last > this.last_index) {
					last = this.last_index;
				}
			}

			// alert('Hide ' + first + ' -> ' + last);

			var i = first;
			for (; i <= last; i++) {
				$(this.items[i]).hide();
			}
		}

		return this.each(function () {

			var $this = $(this);

			var controls = $('<div class="DispletReader_controls"></div>')
				.prependTo($this);
			var previous_button = $('<button title="Previous" id="previous_button">&laquo;</button>')
				.appendTo(controls);
			var page_info = $('<div class="DispletReader_pageinfo"></div>')
				.appendTo(controls);
			var next_button = $('<button title="Next" id="next_button">&raquo;</button>')
				.appendTo(controls);

			// alert(settings.items_per_page);

			var pages = new Pages({
				'items': $this.find(settings.items_selector),
				'items_per_page': settings.items_per_page,
				'pages_elastic_threshold': settings.pages_elastic_threshold,
				'controls': {
					'previous_button': previous_button,
					'next_button': next_button,
					'page_info': page_info
				}
			});

			previous_button.click(function () {
				pages.previous_page();
			});

			next_button.click(function () {
				pages.next_page();
			});
		});
	};
})(jQuery)
