/*
	jQuery Paging plugin
	2008, Paul van Dam
*/

(function($){
$.fn.paging = function (options) {
	
	var opt = {
		itemsPerPage: 5,
		elementType: 'li',
		prevText: 'prev',
		nextText: 'next',
		firstText: 'first',
        lastText: 'last',
		selectedClass: 'selected',
		navClass: 'pagenav',
		prevClass: 'prev',
		nextClass: 'next',
		firstClass: 'first',
		lastClass: 'last',
		disabledClass: 'disabled',
		addNav: 'after',
		showPageNumbers: true,
		trimPageNumbers: false,
		lastHash: ''
	};

	if (options) $.extend(opt, options);
	
	if (opt.elementType == 'tr') opt.elementType = 'tbody>tr';

	return this.each (function () {
		var self = this;
		var pages = Math.ceil($('>'+opt.elementType,$(this)).length/opt.itemsPerPage);
		var currentPage = 1;

        //-- Set page according to hash tag
        var current_hash = location.hash.replace(/\?.*$/, '');
        var hash         = current_hash.replace(/^#/, '');
        if (hash) currentPage = hash;

		if ( pages > 1 ) {
			var html = '<a href="#1" class="'+opt.firstClass+'" rel="first">'+opt.firstText+'</a>';
			html += '<a href="#1" class="'+opt.prevClass+'" rel="prev">'+opt.prevText+'</a>';
			if (opt.showPageNumbers) {
				for (var i=1; i<=pages; i++)
					html += '<a href="#'+i+'" rel="history">'+i+'</a>';
					if(currentPage == i){
						var nextpage = i+1;
					}
			}
			html += '<a href="#2" class="'+opt.nextClass+'" rel="next">'+opt.nextText+'</a>';
			html += '<a href="#'+pages+'" class="'+opt.lastClass+'" rel="last">'+opt.lastText+'</a>';
			var pagenav = $('<div class="'+opt.navClass+'">'+html+'</div>');
			
			if (opt.addNav == 'before')
				pagenav.insertBefore($(this));
			else
				pagenav.insertAfter($(this));

			$('a',pagenav).click(function(){
                var hash = this.href;
                hash = hash.replace(/^.*#/, '');

                location.hash = '#' + hash;
				showPage(hash);
				
				/* arrow nav */
				var nextpage = ((hash > 0) && (hash < pages) ? hash*1+1 : pages);
				var prevpage = ((hash <= pages) && (hash > 0) ) ? hash*1-1 : 1;
				$('a[rel=next]').attr('href', '#' + nextpage)
				$('a[rel=prev]').attr('href', '#' + prevpage)
				
				$(this).blur();
				return false;
			});


			showPage(currentPage);
		} else {
                    //-- When only one page exists, remove pager content
                    if ($('div.'+ opt.navClass).length > 0)
                    {
                        $('div.'+ opt.navClass).html('');
                    } else {
                        var pagenav = $('<div class="'+opt.navClass+'"></div>');

                        if (opt.addNav == 'before')
                            pagenav.insertBefore($(this));
                        else
                            pagenav.insertAfter($(this));
                        
                    }
                    
                    showPage(1);
                }


        //-- Check if hash changes by user
       setInterval(checkHash, 100);

        /**
         * Checks if the hash has changed and moves
         * to the page according to the hash given
         * 
         */
        function checkHash()
        {
            var current_hash = location.hash.replace(/\?.*$/, '');
            var hash         = current_hash.replace(/^#/, '');
            if (hash && hash != opt.lastHash) {
                showPage(hash);
				opt.lastHash = hash;
            }
        }


		function showPage(nr) {
			$(self).triggerHandler('pagingBeforePageChange');

			if (nr == 'next') {
				if (currentPage == pages) return;
				currentPage ++;
			} else if (nr == 'prev') {
				if (currentPage == 1) return;
				currentPage --;
			} else
				currentPage = parseInt(nr);
			
			if (currentPage == 1){
				$('a[rel=prev]',pagenav).addClass(opt.disabledClass);
				$('a[rel=first]',pagenav).addClass(opt.disabledClass);
			}else{
				$('a[rel=prev]',pagenav).removeClass(opt.disabledClass);
				$('a[rel=first]',pagenav).removeClass(opt.disabledClass);
			}

			if (currentPage == pages){
				$('a[rel=next]',pagenav).addClass(opt.disabledClass);
				$('a[rel=last]',pagenav).addClass(opt.disabledClass);
			}else{
				$('a[rel=next]',pagenav).removeClass(opt.disabledClass);
				$('a[rel=last]',pagenav).removeClass(opt.disabledClass);
			}

			$('>'+opt.elementType+':visible',self).hide();

			// Fix for jQuery 1.3
			var selector = '>'+opt.elementType;
			if (currentPage != 1)
				selector += ':gt('+(((currentPage-1)*opt.itemsPerPage)-1)+')';
			selector += ':lt('+opt.itemsPerPage+')';
			$(selector,self).show();

			$('a',pagenav).removeClass(opt.selectedClass);
			$('a[href*=#'+currentPage+']',pagenav).addClass(opt.selectedClass);


			// Trim page numbers if more than 5 (TODO: make option)
			if (opt.trimPageNumbers && pages > 5) {
				var p = [1,pages];
				if (currentPage!=1 && currentPage!=pages) p.push(currentPage);
				if (currentPage-1>1) p.push(currentPage-1);
				if (currentPage+1<pages) p.push(currentPage+1);

				// Edge cases
				if (currentPage == 1) { p.push(3); p.push(4); }
				if (currentPage == 2) { p.push(4); }
				if (currentPage == pages) { p.push(pages-3); p.push(pages-2); }
				if (currentPage == pages-1) { p.push(pages-3); }

				// Show only selected page numbers
				var s = [];
				$(p).each(function(i,e){
					s.push('a[rel='+e+']');
				});

				pagenav.find('a:not(.prev):not(.next)').hide();
				pagenav.find(s.join(',')).show();
			}

			$(self).triggerHandler('pagingAfterPageChange');
		};
	});
};
})(jQuery);